using System.Net; using MediaBrowser.Common.Net; using Microsoft.AspNetCore.Http; namespace MediaBrowser.Common.Extensions { /// /// Static class containing extension methods for . /// public static class HttpContextExtensions { /// /// Checks the origin of the HTTP request. /// /// The incoming HTTP request. /// true if the request is coming from LAN, false otherwise. public static bool IsLocal(this HttpRequest request) { return (request.HttpContext.Connection.LocalIpAddress == null && request.HttpContext.Connection.RemoteIpAddress == null) || request.HttpContext.Connection.LocalIpAddress.Equals(request.HttpContext.Connection.RemoteIpAddress); } /// /// Extracts the remote IP address of the caller of the HTTP request. /// /// The HTTP request. /// The remote caller IP address. public static string RemoteIp(this HttpRequest request) { var cachedRemoteIp = request.HttpContext.Items["RemoteIp"]?.ToString(); if (!string.IsNullOrEmpty(cachedRemoteIp)) { return cachedRemoteIp; } IPAddress ip; // "Real" remote ip might be in X-Forwarded-For of X-Real-Ip // (if the server is behind a reverse proxy for example) if (!IPAddress.TryParse(request.Headers[CustomHeaderNames.XForwardedFor].ToString(), out ip)) { if (!IPAddress.TryParse(request.Headers[CustomHeaderNames.XRealIP].ToString(), out ip)) { ip = request.HttpContext.Connection.RemoteIpAddress; // Default to the loopback address if no RemoteIpAddress is specified (i.e. during integration tests) ip ??= IPAddress.Loopback; } } if (ip.IsIPv4MappedToIPv6) { ip = ip.MapToIPv4(); } var normalizedIp = ip.ToString(); request.HttpContext.Items["RemoteIp"] = normalizedIp; return normalizedIp; } } }