aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs47
-rw-r--r--Emby.Server.Implementations/Data/SqliteUserRepository.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/FileWriter.cs6
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs1
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs15
-rw-r--r--Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs1
-rw-r--r--Emby.Server.Implementations/HttpServer/ResponseFilter.cs3
-rw-r--r--Emby.Server.Implementations/HttpServer/StreamWriter.cs11
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs2
-rw-r--r--Emby.Server.Implementations/Services/HttpResult.cs5
-rw-r--r--Emby.Server.Implementations/Services/ResponseHelper.cs81
-rw-r--r--Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs2
-rw-r--r--Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs110
13 files changed, 124 insertions, 162 deletions
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index aa0fdde2d..53bc85b28 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -1146,7 +1146,7 @@ namespace Emby.Server.Implementations
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error loading plugin {pluginName}", plugin.GetType().FullName);
+ Logger.LogError(ex, "Error loading plugin {PluginName}", plugin.GetType().FullName);
return null;
}
@@ -1160,10 +1160,32 @@ namespace Emby.Server.Implementations
{
Logger.LogInformation("Loading assemblies");
- AllConcreteTypes = GetComposablePartAssemblies()
- .SelectMany(x => x.ExportedTypes)
- .Where(type => type.IsClass && !type.IsAbstract && !type.IsInterface && !type.IsGenericType)
- .ToArray();
+ AllConcreteTypes = GetTypes(GetComposablePartAssemblies()).ToArray();
+ }
+
+ private IEnumerable<Type> GetTypes(IEnumerable<Assembly> assemblies)
+ {
+ foreach (var ass in assemblies)
+ {
+ Type[] exportedTypes;
+ try
+ {
+ exportedTypes = ass.GetExportedTypes();
+ }
+ catch (TypeLoadException ex)
+ {
+ Logger.LogError(ex, "Error getting exported types from {Assembly}", ass.FullName);
+ continue;
+ }
+
+ foreach (Type type in exportedTypes)
+ {
+ if (type.IsClass && !type.IsAbstract && !type.IsInterface && !type.IsGenericType)
+ {
+ yield return type;
+ }
+ }
+ }
}
private CertificateInfo CertificateInfo { get; set; }
@@ -1327,8 +1349,19 @@ namespace Emby.Server.Implementations
{
foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.AllDirectories))
{
- Logger.LogInformation("Loading assembly {Path}", file);
- yield return Assembly.LoadFrom(file);
+ Assembly plugAss;
+ try
+ {
+ plugAss = Assembly.LoadFrom(file);
+ }
+ catch (FileLoadException ex)
+ {
+ Logger.LogError(ex, "Failed to load assembly {Path}", file);
+ continue;
+ }
+
+ Logger.LogInformation("Loaded assembly {Assembly} from {Path}", plugAss.FullName, file);
+ yield return plugAss;
}
}
diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs
index 182df0edc..5957b2903 100644
--- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs
@@ -81,7 +81,7 @@ namespace Emby.Server.Implementations.Data
{
// If the user password is the sha1 hash of the empty string, remove it
if (!string.Equals(user.Password, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal)
- || !string.Equals(user.Password, "$SHA1$DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal))
+ && !string.Equals(user.Password, "$SHA1$DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal))
{
continue;
}
diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs
index c4d2a70e2..c6b7d31a8 100644
--- a/Emby.Server.Implementations/HttpServer/FileWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs
@@ -67,6 +67,7 @@ namespace Emby.Server.Implementations.HttpServer
if (string.IsNullOrWhiteSpace(rangeHeader))
{
+ Headers[HeaderNames.ContentLength] = TotalContentLength.ToString(CultureInfo.InvariantCulture);
StatusCode = HttpStatusCode.OK;
}
else
@@ -99,10 +100,13 @@ namespace Emby.Server.Implementations.HttpServer
RangeStart = requestedRange.Key;
RangeLength = 1 + RangeEnd - RangeStart;
+ // Content-Length is the length of what we're serving, not the original content
+ var lengthString = RangeLength.ToString(CultureInfo.InvariantCulture);
+ Headers[HeaderNames.ContentLength] = lengthString;
var rangeString = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
Headers[HeaderNames.ContentRange] = rangeString;
- Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Range: {2}", Path, RangeHeader, rangeString);
+ Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
}
/// <summary>
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index 06d304077..b3d2b9cc2 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -626,6 +626,7 @@ namespace Emby.Server.Implementations.HttpServer
private static Task Write(IResponse response, string text)
{
var bOutput = Encoding.UTF8.GetBytes(text);
+ response.OriginalResponse.ContentLength = bOutput.Length;
return response.OutputStream.WriteAsync(bOutput, 0, bOutput.Length);
}
diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index 134f3c841..0b2924a3b 100644
--- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -132,7 +132,7 @@ namespace Emby.Server.Implementations.HttpServer
content = Array.Empty<byte>();
}
- result = new StreamWriter(content, contentType);
+ result = new StreamWriter(content, contentType, contentLength);
}
else
{
@@ -176,7 +176,7 @@ namespace Emby.Server.Implementations.HttpServer
bytes = Array.Empty<byte>();
}
- result = new StreamWriter(bytes, contentType);
+ result = new StreamWriter(bytes, contentType, contentLength);
}
else
{
@@ -335,13 +335,13 @@ namespace Emby.Server.Implementations.HttpServer
if (isHeadRequest)
{
- var result = new StreamWriter(Array.Empty<byte>(), contentType);
+ var result = new StreamWriter(Array.Empty<byte>(), contentType, contentLength);
AddResponseHeaders(result, responseHeaders);
return result;
}
else
{
- var result = new StreamWriter(content, contentType);
+ var result = new StreamWriter(content, contentType, contentLength);
AddResponseHeaders(result, responseHeaders);
return result;
}
@@ -581,6 +581,11 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
+ if (totalContentLength.HasValue)
+ {
+ responseHeaders["Content-Length"] = totalContentLength.Value.ToString(CultureInfo.InvariantCulture);
+ }
+
if (isHeadRequest)
{
using (stream)
@@ -624,7 +629,7 @@ namespace Emby.Server.Implementations.HttpServer
if (lastModifiedDate.HasValue)
{
- responseHeaders[HeaderNames.LastModified] = lastModifiedDate.ToString();
+ responseHeaders[HeaderNames.LastModified] = lastModifiedDate.Value.ToString(CultureInfo.InvariantCulture);
}
}
diff --git a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
index 449159834..e27f794ba 100644
--- a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
@@ -96,6 +96,7 @@ namespace Emby.Server.Implementations.HttpServer
RangeStart = requestedRange.Key;
RangeLength = 1 + RangeEnd - RangeStart;
+ Headers[HeaderNames.ContentLength] = RangeLength.ToString(CultureInfo.InvariantCulture);
Headers[HeaderNames.ContentRange] = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
if (RangeStart > 0 && SourceStream.CanSeek)
diff --git a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
index a53d9bf0b..08f424757 100644
--- a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
+++ b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
@@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.HttpServer
public void FilterResponse(IRequest req, IResponse res, object dto)
{
// Try to prevent compatibility view
- res.AddHeader("Access-Control-Allow-Headers", "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Authorization");
+ res.AddHeader("Access-Control-Allow-Headers", "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Authorization");
res.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
res.AddHeader("Access-Control-Allow-Origin", "*");
@@ -58,6 +58,7 @@ namespace Emby.Server.Implementations.HttpServer
if (length > 0)
{
+ res.OriginalResponse.ContentLength = length;
res.SendChunked = false;
}
}
diff --git a/Emby.Server.Implementations/HttpServer/StreamWriter.cs b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
index 324f9085e..194d04441 100644
--- a/Emby.Server.Implementations/HttpServer/StreamWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -49,6 +50,13 @@ namespace Emby.Server.Implementations.HttpServer
SourceStream = source;
+ Headers["Content-Type"] = contentType;
+
+ if (source.CanSeek)
+ {
+ Headers[HeaderNames.ContentLength] = source.Length.ToString(CultureInfo.InvariantCulture);
+ }
+
Headers[HeaderNames.ContentType] = contentType;
}
@@ -57,7 +65,7 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
/// <param name="source">The source.</param>
/// <param name="contentType">Type of the content.</param>
- public StreamWriter(byte[] source, string contentType)
+ public StreamWriter(byte[] source, string contentType, int contentLength)
{
if (string.IsNullOrEmpty(contentType))
{
@@ -66,6 +74,7 @@ namespace Emby.Server.Implementations.HttpServer
SourceBytes = source;
+ Headers[HeaderNames.ContentLength] = contentLength.ToString(CultureInfo.InvariantCulture);
Headers[HeaderNames.ContentType] = contentType;
}
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index 952cc6896..c33bb7740 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -596,7 +596,7 @@ namespace Emby.Server.Implementations.Library
}
bool hasConfiguredPassword = GetAuthenticationProvider(user).HasPassword(user).Result;
- bool hasConfiguredEasyPassword = string.IsNullOrEmpty(GetLocalPasswordHash(user));
+ bool hasConfiguredEasyPassword = !string.IsNullOrEmpty(GetLocalPasswordHash(user));
bool hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ?
hasConfiguredEasyPassword :
diff --git a/Emby.Server.Implementations/Services/HttpResult.cs b/Emby.Server.Implementations/Services/HttpResult.cs
index b6758486c..2b5963a77 100644
--- a/Emby.Server.Implementations/Services/HttpResult.cs
+++ b/Emby.Server.Implementations/Services/HttpResult.cs
@@ -43,6 +43,11 @@ namespace Emby.Server.Implementations.Services
{
var contentLength = bytesResponse.Length;
+ if (response != null)
+ {
+ response.OriginalResponse.ContentLength = contentLength;
+ }
+
if (contentLength > 0)
{
await responseStream.WriteAsync(bytesResponse, 0, contentLength, cancellationToken).ConfigureAwait(false);
diff --git a/Emby.Server.Implementations/Services/ResponseHelper.cs b/Emby.Server.Implementations/Services/ResponseHelper.cs
index 0301ff335..251ba3529 100644
--- a/Emby.Server.Implementations/Services/ResponseHelper.cs
+++ b/Emby.Server.Implementations/Services/ResponseHelper.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
@@ -20,6 +21,8 @@ namespace Emby.Server.Implementations.Services
{
response.StatusCode = (int)HttpStatusCode.NoContent;
}
+
+ response.OriginalResponse.ContentLength = 0;
return Task.CompletedTask;
}
@@ -39,11 +42,6 @@ namespace Emby.Server.Implementations.Services
response.StatusCode = httpResult.Status;
response.StatusDescription = httpResult.StatusCode.ToString();
- //if (string.IsNullOrEmpty(httpResult.ContentType))
- //{
- // httpResult.ContentType = defaultContentType;
- //}
- //response.ContentType = httpResult.ContentType;
}
var responseOptions = result as IHasHeaders;
@@ -53,6 +51,7 @@ namespace Emby.Server.Implementations.Services
{
if (string.Equals(responseHeaders.Key, "Content-Length", StringComparison.OrdinalIgnoreCase))
{
+ response.OriginalResponse.ContentLength = long.Parse(responseHeaders.Value, CultureInfo.InvariantCulture);
continue;
}
@@ -72,52 +71,37 @@ namespace Emby.Server.Implementations.Services
response.ContentType += "; charset=utf-8";
}
- var asyncStreamWriter = result as IAsyncStreamWriter;
- if (asyncStreamWriter != null)
- {
- return asyncStreamWriter.WriteToAsync(response.OutputStream, cancellationToken);
- }
-
- var streamWriter = result as IStreamWriter;
- if (streamWriter != null)
+ switch (result)
{
- streamWriter.WriteTo(response.OutputStream);
- return Task.CompletedTask;
- }
-
- var fileWriter = result as FileWriter;
- if (fileWriter != null)
- {
- return fileWriter.WriteToAsync(response, cancellationToken);
- }
-
- var stream = result as Stream;
- if (stream != null)
- {
- return CopyStream(stream, response.OutputStream);
- }
+ case IAsyncStreamWriter asyncStreamWriter:
+ return asyncStreamWriter.WriteToAsync(response.OutputStream, cancellationToken);
+ case IStreamWriter streamWriter:
+ streamWriter.WriteTo(response.OutputStream);
+ return Task.CompletedTask;
+ case FileWriter fileWriter:
+ return fileWriter.WriteToAsync(response, cancellationToken);
+ case Stream stream:
+ return CopyStream(stream, response.OutputStream);
+ case byte[] bytes:
+ response.ContentType = "application/octet-stream";
+ response.OriginalResponse.ContentLength = bytes.Length;
+
+ if (bytes.Length > 0)
+ {
+ return response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
+ }
- var bytes = result as byte[];
- if (bytes != null)
- {
- response.ContentType = "application/octet-stream";
+ return Task.CompletedTask;
+ case string responseText:
+ var responseTextAsBytes = Encoding.UTF8.GetBytes(responseText);
+ response.OriginalResponse.ContentLength = responseTextAsBytes.Length;
- if (bytes.Length > 0)
- {
- return response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
- }
- return Task.CompletedTask;
- }
+ if (responseTextAsBytes.Length > 0)
+ {
+ return response.OutputStream.WriteAsync(responseTextAsBytes, 0, responseTextAsBytes.Length, cancellationToken);
+ }
- var responseText = result as string;
- if (responseText != null)
- {
- bytes = Encoding.UTF8.GetBytes(responseText);
- if (bytes.Length > 0)
- {
- return response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
- }
- return Task.CompletedTask;
+ return Task.CompletedTask;
}
return WriteObject(request, result, response);
@@ -143,14 +127,13 @@ namespace Emby.Server.Implementations.Services
ms.Position = 0;
var contentLength = ms.Length;
+ response.OriginalResponse.ContentLength = contentLength;
if (contentLength > 0)
{
await ms.CopyToAsync(response.OutputStream).ConfigureAwait(false);
}
}
-
- //serializer(result, outputStream);
}
}
}
diff --git a/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs b/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs
index f835aa1b5..6a522fbef 100644
--- a/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs
+++ b/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs
@@ -71,7 +71,7 @@ namespace Emby.Server.Implementations.Services
string propertyName = pair.Key;
string propertyTextValue = pair.Value;
- if (string.IsNullOrEmpty(propertyTextValue)
+ if (propertyTextValue == null
|| !propertySetterMap.TryGetValue(propertyName, out propertySerializerEntry)
|| propertySerializerEntry.PropertySetFn == null)
{
diff --git a/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs b/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
index 792615a0f..00465b63e 100644
--- a/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
+++ b/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
@@ -4,6 +4,7 @@ using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
+using MediaBrowser.Common.Net;
using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
@@ -38,16 +39,9 @@ namespace Emby.Server.Implementations.SocketSharp
public string RawUrl => request.GetEncodedPathAndQuery();
public string AbsoluteUri => request.GetDisplayUrl().TrimEnd('/');
+ // Header[name] returns "" when undefined
- public string XForwardedFor
- => StringValues.IsNullOrEmpty(request.Headers["X-Forwarded-For"]) ? null : request.Headers["X-Forwarded-For"].ToString();
-
- public int? XForwardedPort
- => StringValues.IsNullOrEmpty(request.Headers["X-Forwarded-Port"]) ? (int?)null : int.Parse(request.Headers["X-Forwarded-Port"], CultureInfo.InvariantCulture);
-
- public string XForwardedProtocol => StringValues.IsNullOrEmpty(request.Headers["X-Forwarded-Proto"]) ? null : request.Headers["X-Forwarded-Proto"].ToString();
-
- public string XRealIp => StringValues.IsNullOrEmpty(request.Headers["X-Real-IP"]) ? null : request.Headers["X-Real-IP"].ToString();
+ private string GetHeader(string name) => request.Headers[name].ToString();
private string remoteIp;
public string RemoteIp
@@ -59,101 +53,27 @@ namespace Emby.Server.Implementations.SocketSharp
return remoteIp;
}
- var temp = CheckBadChars(XForwardedFor.AsSpan());
- if (temp.Length != 0)
- {
- return remoteIp = temp.ToString();
- }
+ IPAddress ip;
- temp = CheckBadChars(XRealIp.AsSpan());
- if (temp.Length != 0)
+ // "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(GetHeader(CustomHeaderNames.XForwardedFor), out ip))
{
- return remoteIp = NormalizeIp(temp).ToString();
- }
-
- return remoteIp = NormalizeIp(request.HttpContext.Connection.RemoteIpAddress.ToString().AsSpan()).ToString();
- }
- }
-
- private static readonly char[] HttpTrimCharacters = new char[] { (char)0x09, (char)0xA, (char)0xB, (char)0xC, (char)0xD, (char)0x20 };
-
- // CheckBadChars - throws on invalid chars to be not found in header name/value
- internal static ReadOnlySpan<char> CheckBadChars(ReadOnlySpan<char> name)
- {
- if (name.Length == 0)
- {
- return name;
- }
-
- // VALUE check
- // Trim spaces from both ends
- name = name.Trim(HttpTrimCharacters);
-
- // First, check for correctly formed multi-line value
- // Second, check for absence of CTL characters
- int crlf = 0;
- for (int i = 0; i < name.Length; ++i)
- {
- char c = (char)(0x000000ff & (uint)name[i]);
- switch (crlf)
- {
- case 0:
- if (c == '\r')
- {
- crlf = 1;
- }
- else if (c == '\n')
- {
- // Technically this is bad HTTP. But it would be a breaking change to throw here.
- // Is there an exploit?
- crlf = 2;
- }
- else if (c == 127 || (c < ' ' && c != '\t'))
- {
- throw new ArgumentException("net_WebHeaderInvalidControlChars", nameof(name));
- }
-
- break;
-
- case 1:
- if (c == '\n')
- {
- crlf = 2;
- break;
- }
-
- throw new ArgumentException("net_WebHeaderInvalidCRLFChars", nameof(name));
-
- case 2:
- if (c == ' ' || c == '\t')
- {
- crlf = 0;
- break;
- }
-
- throw new ArgumentException("net_WebHeaderInvalidCRLFChars", nameof(name));
+ if (!IPAddress.TryParse(GetHeader(CustomHeaderNames.XRealIP), out ip))
+ {
+ ip = request.HttpContext.Connection.RemoteIpAddress;
+ }
}
- }
- if (crlf != 0)
- {
- throw new ArgumentException("net_WebHeaderInvalidCRLFChars", nameof(name));
+ return remoteIp = NormalizeIp(ip).ToString();
}
-
- return name;
}
- private ReadOnlySpan<char> NormalizeIp(ReadOnlySpan<char> ip)
+ private static IPAddress NormalizeIp(IPAddress ip)
{
- if (ip.Length != 0 && !ip.IsWhiteSpace())
+ if (ip.IsIPv4MappedToIPv6)
{
- // Handle ipv4 mapped to ipv6
- const string srch = "::ffff:";
- var index = ip.IndexOf(srch.AsSpan(), StringComparison.OrdinalIgnoreCase);
- if (index == 0)
- {
- ip = ip.Slice(srch.Length);
- }
+ return ip.MapToIPv4();
}
return ip;