aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/HttpServer
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/HttpServer')
-rw-r--r--Emby.Server.Implementations/HttpServer/FileWriter.cs46
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs175
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs106
-rw-r--r--Emby.Server.Implementations/HttpServer/IHttpListener.cs17
-rw-r--r--Emby.Server.Implementations/HttpServer/LoggerUtils.cs55
-rw-r--r--Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs9
-rw-r--r--Emby.Server.Implementations/HttpServer/ResponseFilter.cs10
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs3
-rw-r--r--Emby.Server.Implementations/HttpServer/StreamWriter.cs21
-rw-r--r--Emby.Server.Implementations/HttpServer/WebSocketConnection.cs39
10 files changed, 145 insertions, 336 deletions
diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs
index 7aedba9b3..c4d2a70e2 100644
--- a/Emby.Server.Implementations/HttpServer/FileWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs
@@ -5,15 +5,19 @@ using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
+using Emby.Server.Implementations.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
namespace Emby.Server.Implementations.HttpServer
{
public class FileWriter : IHttpResult
{
+ private readonly IStreamHelper _streamHelper;
private ILogger Logger { get; set; }
+ private readonly IFileSystem _fileSystem;
private string RangeHeader { get; set; }
private bool IsHeadRequest { get; set; }
@@ -42,25 +46,27 @@ namespace Emby.Server.Implementations.HttpServer
public string Path { get; set; }
- public FileWriter(string path, string contentType, string rangeHeader, ILogger logger, IFileSystem fileSystem)
+ public FileWriter(string path, string contentType, string rangeHeader, ILogger logger, IFileSystem fileSystem, IStreamHelper streamHelper)
{
if (string.IsNullOrEmpty(contentType))
{
throw new ArgumentNullException(nameof(contentType));
}
+ _streamHelper = streamHelper;
+ _fileSystem = fileSystem;
+
Path = path;
Logger = logger;
RangeHeader = rangeHeader;
- Headers["Content-Type"] = contentType;
+ Headers[HeaderNames.ContentType] = contentType;
TotalContentLength = fileSystem.GetFileInfo(path).Length;
- Headers["Accept-Ranges"] = "bytes";
+ Headers[HeaderNames.AcceptRanges] = "bytes";
if (string.IsNullOrWhiteSpace(rangeHeader))
{
- Headers["Content-Length"] = TotalContentLength.ToString(UsCulture);
StatusCode = HttpStatusCode.OK;
}
else
@@ -93,13 +99,10 @@ 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(UsCulture);
- Headers["Content-Length"] = lengthString;
- var rangeString = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
- Headers["Content-Range"] = rangeString;
+ var rangeString = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
+ Headers[HeaderNames.ContentRange] = rangeString;
- Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
+ Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Range: {2}", Path, RangeHeader, rangeString);
}
/// <summary>
@@ -145,8 +148,7 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private string[] SkipLogExtensions = new string[]
- {
+ private static readonly string[] SkipLogExtensions = {
".js",
".html",
".css"
@@ -163,8 +165,10 @@ namespace Emby.Server.Implementations.HttpServer
}
var path = Path;
+ var offset = RangeStart;
+ var count = RangeLength;
- if (string.IsNullOrWhiteSpace(RangeHeader) || (RangeStart <= 0 && RangeEnd >= TotalContentLength - 1))
+ if (string.IsNullOrWhiteSpace(RangeHeader) || RangeStart <= 0 && RangeEnd >= TotalContentLength - 1)
{
var extension = System.IO.Path.GetExtension(path);
@@ -173,20 +177,15 @@ namespace Emby.Server.Implementations.HttpServer
Logger.LogDebug("Transmit file {0}", path);
}
- //var count = FileShare == FileShareMode.ReadWrite ? TotalContentLength : 0;
-
- await response.TransmitFile(path, 0, 0, FileShare, cancellationToken).ConfigureAwait(false);
- return;
+ offset = 0;
+ count = 0;
}
- await response.TransmitFile(path, RangeStart, RangeLength, FileShare, cancellationToken).ConfigureAwait(false);
+ await response.TransmitFile(path, offset, count, FileShare, _fileSystem, _streamHelper, cancellationToken).ConfigureAwait(false);
}
finally
{
- if (OnComplete != null)
- {
- OnComplete();
- }
+ OnComplete?.Invoke();
}
}
@@ -203,8 +202,5 @@ namespace Emby.Server.Implementations.HttpServer
get => (HttpStatusCode)Status;
set => Status = (int)value;
}
-
- public string StatusDescription { get; set; }
-
}
}
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index 834ffb130..e8d47cad5 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -10,6 +11,7 @@ using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.Net;
using Emby.Server.Implementations.Services;
+using Emby.Server.Implementations.SocketSharp;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
@@ -19,19 +21,20 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Internal;
+using Microsoft.AspNetCore.WebUtilities;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
+using ServiceStack.Text.Jsv;
namespace Emby.Server.Implementations.HttpServer
{
public class HttpListenerHost : IHttpServer, IDisposable
{
private string DefaultRedirectPath { get; set; }
-
- private readonly ILogger _logger;
public string[] UrlPrefixes { get; private set; }
- private IHttpListener _listener;
-
public event EventHandler<GenericEventArgs<IWebSocketConnection>> WebSocketConnected;
private readonly IServerConfigurationManager _config;
@@ -39,6 +42,7 @@ namespace Emby.Server.Implementations.HttpServer
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _jsonSerializer;
private readonly IXmlSerializer _xmlSerializer;
+ private readonly IHttpListener _socketListener;
private readonly Func<Type, Func<string, object>> _funcParseFn;
public Action<IRequest, IResponse, object>[] ResponseFilters { get; set; }
@@ -53,20 +57,23 @@ namespace Emby.Server.Implementations.HttpServer
IServerApplicationHost applicationHost,
ILoggerFactory loggerFactory,
IServerConfigurationManager config,
- string defaultRedirectPath,
+ IConfiguration configuration,
INetworkManager networkManager,
IJsonSerializer jsonSerializer,
IXmlSerializer xmlSerializer,
- Func<Type, Func<string, object>> funcParseFn)
+ IHttpListener socketListener)
{
_appHost = applicationHost;
- _logger = loggerFactory.CreateLogger("HttpServer");
+ Logger = loggerFactory.CreateLogger("HttpServer");
_config = config;
- DefaultRedirectPath = defaultRedirectPath;
+ DefaultRedirectPath = configuration["HttpListenerHost:DefaultRedirectPath"];
_networkManager = networkManager;
_jsonSerializer = jsonSerializer;
_xmlSerializer = xmlSerializer;
- _funcParseFn = funcParseFn;
+ _socketListener = socketListener;
+ _socketListener.WebSocketConnected = OnWebSocketConnected;
+
+ _funcParseFn = t => s => JsvReader.GetParseFn(t)(s);
Instance = this;
ResponseFilters = Array.Empty<Action<IRequest, IResponse, object>>();
@@ -74,7 +81,7 @@ namespace Emby.Server.Implementations.HttpServer
public string GlobalResponse { get; set; }
- protected ILogger Logger => _logger;
+ protected ILogger Logger { get; }
public object CreateInstance(Type type)
{
@@ -140,11 +147,11 @@ namespace Emby.Server.Implementations.HttpServer
return;
}
- var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger)
+ var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, Logger)
{
OnReceive = ProcessWebSocketMessageReceived,
Url = e.Url,
- QueryString = e.QueryString ?? new QueryParamCollection()
+ QueryString = e.QueryString ?? new QueryCollection()
};
connection.Closed += Connection_Closed;
@@ -209,16 +216,16 @@ namespace Emby.Server.Implementations.HttpServer
if (logExceptionStackTrace)
{
- _logger.LogError(ex, "Error processing request");
+ Logger.LogError(ex, "Error processing request");
}
else if (logExceptionMessage)
{
- _logger.LogError(ex.Message);
+ Logger.LogError(ex.Message);
}
var httpRes = httpReq.Response;
- if (httpRes.IsClosed)
+ if (httpRes.OriginalResponse.HasStarted)
{
return;
}
@@ -231,7 +238,7 @@ namespace Emby.Server.Implementations.HttpServer
}
catch (Exception errorEx)
{
- _logger.LogError(errorEx, "Error this.ProcessRequest(context)(Exception while writing error to the response)");
+ Logger.LogError(errorEx, "Error this.ProcessRequest(context)(Exception while writing error to the response)");
}
}
@@ -274,39 +281,6 @@ namespace Emby.Server.Implementations.HttpServer
}
}
-
- if (_listener != null)
- {
- _logger.LogInformation("Stopping HttpListener...");
- var task = _listener.Stop();
- Task.WaitAll(task);
- _logger.LogInformation("HttpListener stopped");
- }
- }
-
- private static readonly string[] _skipLogExtensions =
- {
- ".js",
- ".css",
- ".woff",
- ".woff2",
- ".ttf",
- ".html"
- };
-
- private bool EnableLogging(string url, string localPath)
- {
- var extension = GetExtension(url);
-
- return ((string.IsNullOrEmpty(extension) || !_skipLogExtensions.Contains(extension))
- && (string.IsNullOrEmpty(localPath) || localPath.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) == -1));
- }
-
- private static string GetExtension(string url)
- {
- var parts = url.Split(new[] { '?' }, 2);
-
- return Path.GetExtension(parts[0]);
}
public static string RemoveQueryStringByKey(string url, string key)
@@ -314,7 +288,7 @@ namespace Emby.Server.Implementations.HttpServer
var uri = new Uri(url);
// this gets all the query string key value pairs as a collection
- var newQueryString = MyHttpUtility.ParseQueryString(uri.Query);
+ var newQueryString = QueryHelpers.ParseQuery(uri.Query);
var originalCount = newQueryString.Count;
@@ -335,7 +309,7 @@ namespace Emby.Server.Implementations.HttpServer
string pagePathWithoutQueryString = url.Split(new[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0];
return newQueryString.Count > 0
- ? string.Format("{0}?{1}", pagePathWithoutQueryString, newQueryString)
+ ? QueryHelpers.AddQueryString(pagePathWithoutQueryString, newQueryString.ToDictionary(kv => kv.Key, kv => kv.Value.ToString()))
: pagePathWithoutQueryString;
}
@@ -444,12 +418,11 @@ namespace Emby.Server.Implementations.HttpServer
/// <summary>
/// Overridable method that can be used to implement a custom hnandler
/// </summary>
- protected async Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, CancellationToken cancellationToken)
+ public async Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, CancellationToken cancellationToken)
{
- var date = DateTime.Now;
+ var stopWatch = new Stopwatch();
+ stopWatch.Start();
var httpRes = httpReq.Response;
- bool enableLog = false;
- bool logHeaders = false;
string urlToLog = null;
string remoteIp = httpReq.RemoteIp;
@@ -496,18 +469,8 @@ namespace Emby.Server.Implementations.HttpServer
return;
}
- var operationName = httpReq.OperationName;
-
- enableLog = EnableLogging(urlString, localPath);
- urlToLog = urlString;
- logHeaders = enableLog && urlToLog.IndexOf("/videos/", StringComparison.OrdinalIgnoreCase) != -1;
-
- if (enableLog)
- {
- urlToLog = GetUrlToLog(urlString);
-
- LoggerUtils.LogRequest(_logger, urlToLog, httpReq.HttpMethod, httpReq.UserAgent, logHeaders ? httpReq.Headers : null);
- }
+ urlToLog = GetUrlToLog(urlString);
+ Logger.LogDebug("HTTP {HttpMethod} {Url} UserAgent: {UserAgent} \nHeaders: {@Headers}", urlToLog, httpReq.UserAgent ?? string.Empty, httpReq.HttpMethod, httpReq.Headers);
if (string.Equals(localPath, "/emby/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase))
@@ -515,6 +478,7 @@ namespace Emby.Server.Implementations.HttpServer
RedirectToUrl(httpRes, DefaultRedirectPath);
return;
}
+
if (string.Equals(localPath, "/emby", StringComparison.OrdinalIgnoreCase) ||
string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase))
{
@@ -560,16 +524,19 @@ namespace Emby.Server.Implementations.HttpServer
RedirectToUrl(httpRes, DefaultRedirectPath);
return;
}
+
if (string.Equals(localPath, "/web/", StringComparison.OrdinalIgnoreCase))
{
RedirectToUrl(httpRes, "../" + DefaultRedirectPath);
return;
}
+
if (string.Equals(localPath, "/", StringComparison.OrdinalIgnoreCase))
{
RedirectToUrl(httpRes, DefaultRedirectPath);
return;
}
+
if (string.IsNullOrEmpty(localPath))
{
RedirectToUrl(httpRes, "/" + DefaultRedirectPath);
@@ -605,33 +572,21 @@ namespace Emby.Server.Implementations.HttpServer
if (handler != null)
{
- await handler.ProcessRequestAsync(this, httpReq, httpRes, Logger, operationName, cancellationToken).ConfigureAwait(false);
+ await handler.ProcessRequestAsync(this, httpReq, httpRes, Logger, httpReq.OperationName, cancellationToken).ConfigureAwait(false);
}
else
{
await ErrorHandler(new FileNotFoundException(), httpReq, false, false).ConfigureAwait(false);
}
}
- catch (OperationCanceledException ex)
+ catch (Exception ex) when (ex is SocketException || ex is IOException || ex is OperationCanceledException)
{
await ErrorHandler(ex, httpReq, false, false).ConfigureAwait(false);
}
-
- catch (IOException ex)
- {
- await ErrorHandler(ex, httpReq, false, false).ConfigureAwait(false);
- }
-
- catch (SocketException ex)
- {
- await ErrorHandler(ex, httpReq, false, false).ConfigureAwait(false);
- }
-
catch (SecurityException ex)
{
await ErrorHandler(ex, httpReq, false, true).ConfigureAwait(false);
}
-
catch (Exception ex)
{
var logException = !string.Equals(ex.GetType().Name, "SocketException", StringComparison.OrdinalIgnoreCase);
@@ -640,15 +595,15 @@ namespace Emby.Server.Implementations.HttpServer
}
finally
{
- httpRes.Close();
-
- if (enableLog)
+ stopWatch.Stop();
+ var elapsed = stopWatch.Elapsed;
+ if (elapsed.TotalMilliseconds > 500)
{
- var statusCode = httpRes.StatusCode;
-
- var duration = DateTime.Now - date;
-
- LoggerUtils.LogResponse(_logger, statusCode, urlToLog, remoteIp, duration, logHeaders ? httpRes.Headers : null);
+ Logger.LogWarning("HTTP Response {StatusCode} to {RemoteIp}. Time (slow): {Elapsed:g}. {Url}", httpRes.StatusCode, remoteIp, elapsed, urlToLog);
+ }
+ else
+ {
+ Logger.LogDebug("HTTP Response {StatusCode} to {RemoteIp}. Time: {Elapsed:g}. {Url}", httpRes.StatusCode, remoteIp, elapsed, urlToLog);
}
}
}
@@ -661,12 +616,11 @@ namespace Emby.Server.Implementations.HttpServer
var pathParts = pathInfo.TrimStart('/').Split('/');
if (pathParts.Length == 0)
{
- _logger.LogError("Path parts empty for PathInfo: {pathInfo}, Url: {RawUrl}", pathInfo, httpReq.RawUrl);
+ Logger.LogError("Path parts empty for PathInfo: {PathInfo}, Url: {RawUrl}", pathInfo, httpReq.RawUrl);
return null;
}
var restPath = ServiceHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, out string contentType);
-
if (restPath != null)
{
return new ServiceHandler
@@ -676,15 +630,13 @@ namespace Emby.Server.Implementations.HttpServer
};
}
- _logger.LogError("Could not find handler for {PathInfo}", pathInfo);
+ Logger.LogError("Could not find handler for {PathInfo}", pathInfo);
return null;
}
private static Task Write(IResponse response, string text)
{
var bOutput = Encoding.UTF8.GetBytes(text);
- response.SetContentLength(bOutput.Length);
-
return response.OutputStream.WriteAsync(bOutput, 0, bOutput.Length);
}
@@ -703,6 +655,7 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
+ // TODO what is this?
var httpsUrl = url
.Replace("http://", "https://", StringComparison.OrdinalIgnoreCase)
.Replace(":" + _config.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture), ":" + _config.Configuration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase);
@@ -723,13 +676,15 @@ namespace Emby.Server.Implementations.HttpServer
/// Adds the rest handlers.
/// </summary>
/// <param name="services">The services.</param>
- public void Init(IEnumerable<IService> services, IEnumerable<IWebSocketListener> listeners)
+ /// <param name="listeners"></param>
+ /// <param name="urlPrefixes"></param>
+ public void Init(IEnumerable<IService> services, IEnumerable<IWebSocketListener> listeners, IEnumerable<string> urlPrefixes)
{
_webSocketListeners = listeners.ToArray();
-
+ UrlPrefixes = urlPrefixes.ToArray();
ServiceController = new ServiceController();
- _logger.LogInformation("Calling ServiceStack AppHost.Init");
+ Logger.LogInformation("Calling ServiceStack AppHost.Init");
var types = services.Select(r => r.GetType()).ToArray();
@@ -737,7 +692,7 @@ namespace Emby.Server.Implementations.HttpServer
ResponseFilters = new Action<IRequest, IResponse, object>[]
{
- new ResponseFilter(_logger).FilterResponse
+ new ResponseFilter(Logger).FilterResponse
};
}
@@ -799,8 +754,12 @@ namespace Emby.Server.Implementations.HttpServer
return _jsonSerializer.DeserializeFromStreamAsync(stream, type);
}
- //TODO Add Jellyfin Route Path Normalizer
+ public Task ProcessWebSocketRequest(HttpContext context)
+ {
+ return _socketListener.ProcessWebSocketRequest(context);
+ }
+ //TODO Add Jellyfin Route Path Normalizer
private static string NormalizeEmbyRoutePath(string path)
{
if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase))
@@ -833,6 +792,7 @@ namespace Emby.Server.Implementations.HttpServer
private bool _disposed;
private readonly object _disposeLock = new object();
+
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
@@ -861,7 +821,7 @@ namespace Emby.Server.Implementations.HttpServer
return Task.CompletedTask;
}
- _logger.LogDebug("Websocket message received: {0}", result.MessageType);
+ Logger.LogDebug("Websocket message received: {0}", result.MessageType);
var tasks = _webSocketListeners.Select(i => Task.Run(async () =>
{
@@ -871,7 +831,7 @@ namespace Emby.Server.Implementations.HttpServer
}
catch (Exception ex)
{
- _logger.LogError(ex, "{0} failed processing WebSocket message {1}", i.GetType().Name, result.MessageType ?? string.Empty);
+ Logger.LogError(ex, "{0} failed processing WebSocket message {1}", i.GetType().Name, result.MessageType ?? string.Empty);
}
}));
@@ -882,18 +842,5 @@ namespace Emby.Server.Implementations.HttpServer
{
Dispose(true);
}
-
- public void StartServer(string[] urlPrefixes, IHttpListener httpListener)
- {
- UrlPrefixes = urlPrefixes;
-
- _listener = httpListener;
-
- _listener.WebSocketConnected = OnWebSocketConnected;
- _listener.ErrorHandler = ErrorHandler;
- _listener.RequestHandler = RequestHandler;
-
- _listener.Start(UrlPrefixes);
- }
}
}
diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index 75ca57ebb..463265862 100644
--- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -16,6 +16,8 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Primitives;
+using Microsoft.Net.Http.Headers;
using IRequest = MediaBrowser.Model.Services.IRequest;
using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
@@ -32,17 +34,16 @@ namespace Emby.Server.Implementations.HttpServer
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly IJsonSerializer _jsonSerializer;
-
- private IBrotliCompressor _brotliCompressor;
+ private readonly IStreamHelper _streamHelper;
/// <summary>
/// Initializes a new instance of the <see cref="HttpResultFactory" /> class.
/// </summary>
- public HttpResultFactory(ILoggerFactory loggerfactory, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IBrotliCompressor brotliCompressor)
+ public HttpResultFactory(ILoggerFactory loggerfactory, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IStreamHelper streamHelper)
{
_fileSystem = fileSystem;
_jsonSerializer = jsonSerializer;
- _brotliCompressor = brotliCompressor;
+ _streamHelper = streamHelper;
_logger = loggerfactory.CreateLogger("HttpResultFactory");
}
@@ -76,7 +77,7 @@ namespace Emby.Server.Implementations.HttpServer
public object GetRedirectResult(string url)
{
var responseHeaders = new Dictionary<string, string>();
- responseHeaders["Location"] = url;
+ responseHeaders[HeaderNames.Location] = url;
var result = new HttpResult(Array.Empty<byte>(), "text/plain", HttpStatusCode.Redirect);
@@ -90,16 +91,16 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
private IHasHeaders GetHttpResult(IRequest requestContext, Stream content, string contentType, bool addCachePrevention, IDictionary<string, string> responseHeaders = null)
{
- var result = new StreamWriter(content, contentType, _logger);
+ var result = new StreamWriter(content, contentType);
if (responseHeaders == null)
{
responseHeaders = new Dictionary<string, string>();
}
- if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string expires))
+ if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out string expires))
{
- responseHeaders["Expires"] = "-1";
+ responseHeaders[HeaderNames.Expires] = "-1";
}
AddResponseHeaders(result, responseHeaders);
@@ -131,7 +132,7 @@ namespace Emby.Server.Implementations.HttpServer
content = Array.Empty<byte>();
}
- result = new StreamWriter(content, contentType, contentLength, _logger);
+ result = new StreamWriter(content, contentType);
}
else
{
@@ -143,9 +144,9 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>();
}
- if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string expires))
+ if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out string _))
{
- responseHeaders["Expires"] = "-1";
+ responseHeaders[HeaderNames.Expires] = "-1";
}
AddResponseHeaders(result, responseHeaders);
@@ -175,7 +176,7 @@ namespace Emby.Server.Implementations.HttpServer
bytes = Array.Empty<byte>();
}
- result = new StreamWriter(bytes, contentType, contentLength, _logger);
+ result = new StreamWriter(bytes, contentType);
}
else
{
@@ -187,9 +188,9 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>();
}
- if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string expires))
+ if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out string _))
{
- responseHeaders["Expires"] = "-1";
+ responseHeaders[HeaderNames.Expires] = "-1";
}
AddResponseHeaders(result, responseHeaders);
@@ -214,7 +215,7 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
- responseHeaders["Expires"] = "-1";
+ responseHeaders[HeaderNames.Expires] = "-1";
return ToOptimizedResultInternal(requestContext, result, responseHeaders);
}
@@ -246,9 +247,9 @@ namespace Emby.Server.Implementations.HttpServer
private static string GetCompressionType(IRequest request)
{
- var acceptEncoding = request.Headers["Accept-Encoding"];
+ var acceptEncoding = request.Headers[HeaderNames.AcceptEncoding].ToString();
- if (acceptEncoding != null)
+ if (string.IsNullOrEmpty(acceptEncoding))
{
//if (_brotliCompressor != null && acceptEncoding.IndexOf("br", StringComparison.OrdinalIgnoreCase) != -1)
// return "br";
@@ -277,9 +278,10 @@ namespace Emby.Server.Implementations.HttpServer
private object ToOptimizedResultInternal<T>(IRequest request, T dto, IDictionary<string, string> responseHeaders = null)
{
- var contentType = request.ResponseContentType;
+ // TODO: @bond use Span and .Equals
+ var contentType = request.ResponseContentType?.Split(';')[0].Trim().ToLowerInvariant();
- switch (GetRealContentType(contentType))
+ switch (contentType)
{
case "application/xml":
case "text/xml":
@@ -325,21 +327,21 @@ namespace Emby.Server.Implementations.HttpServer
}
content = Compress(content, requestedCompressionType);
- responseHeaders["Content-Encoding"] = requestedCompressionType;
+ responseHeaders[HeaderNames.ContentEncoding] = requestedCompressionType;
- responseHeaders["Vary"] = "Accept-Encoding";
+ responseHeaders[HeaderNames.Vary] = HeaderNames.AcceptEncoding;
var contentLength = content.Length;
if (isHeadRequest)
{
- var result = new StreamWriter(Array.Empty<byte>(), contentType, contentLength, _logger);
+ var result = new StreamWriter(Array.Empty<byte>(), contentType);
AddResponseHeaders(result, responseHeaders);
return result;
}
else
{
- var result = new StreamWriter(content, contentType, contentLength, _logger);
+ var result = new StreamWriter(content, contentType);
AddResponseHeaders(result, responseHeaders);
return result;
}
@@ -347,23 +349,19 @@ namespace Emby.Server.Implementations.HttpServer
private byte[] Compress(byte[] bytes, string compressionType)
{
- if (string.Equals(compressionType, "br", StringComparison.OrdinalIgnoreCase))
- return CompressBrotli(bytes);
-
if (string.Equals(compressionType, "deflate", StringComparison.OrdinalIgnoreCase))
+ {
return Deflate(bytes);
+ }
if (string.Equals(compressionType, "gzip", StringComparison.OrdinalIgnoreCase))
+ {
return GZip(bytes);
+ }
throw new NotSupportedException(compressionType);
}
- private byte[] CompressBrotli(byte[] bytes)
- {
- return _brotliCompressor.Compress(bytes);
- }
-
private static byte[] Deflate(byte[] bytes)
{
// In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream
@@ -390,13 +388,6 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- public static string GetRealContentType(string contentType)
- {
- return contentType == null
- ? null
- : contentType.Split(';')[0].ToLowerInvariant().Trim();
- }
-
private static string SerializeToXmlString(object from)
{
using (var ms = new MemoryStream())
@@ -424,12 +415,12 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
private object GetCachedResult(IRequest requestContext, IDictionary<string, string> responseHeaders, StaticResultOptions options)
{
- bool noCache = (requestContext.Headers.Get("Cache-Control") ?? string.Empty).IndexOf("no-cache", StringComparison.OrdinalIgnoreCase) != -1;
+ bool noCache = (requestContext.Headers[HeaderNames.CacheControl].ToString()).IndexOf("no-cache", StringComparison.OrdinalIgnoreCase) != -1;
AddCachingHeaders(responseHeaders, options.CacheDuration, noCache, options.DateLastModified);
if (!noCache)
{
- DateTime.TryParse(requestContext.Headers.Get("If-Modified-Since"), out var ifModifiedSinceHeader);
+ DateTime.TryParse(requestContext.Headers[HeaderNames.IfModifiedSince], out var ifModifiedSinceHeader);
if (IsNotModified(ifModifiedSinceHeader, options.CacheDuration, options.DateLastModified))
{
@@ -530,7 +521,7 @@ namespace Emby.Server.Implementations.HttpServer
options.ResponseHeaders = options.ResponseHeaders ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var contentType = options.ContentType;
- if (!string.IsNullOrEmpty(requestContext.Headers.Get("If-Modified-Since")))
+ if (!StringValues.IsNullOrEmpty(requestContext.Headers[HeaderNames.IfModifiedSince]))
{
// See if the result is already cached in the browser
var result = GetCachedResult(requestContext, options.ResponseHeaders, options);
@@ -548,11 +539,11 @@ namespace Emby.Server.Implementations.HttpServer
AddCachingHeaders(responseHeaders, options.CacheDuration, false, options.DateLastModified);
AddAgeHeader(responseHeaders, options.DateLastModified);
- var rangeHeader = requestContext.Headers.Get("Range");
+ var rangeHeader = requestContext.Headers[HeaderNames.Range];
if (!isHeadRequest && !string.IsNullOrEmpty(options.Path))
{
- var hasHeaders = new FileWriter(options.Path, contentType, rangeHeader, _logger, _fileSystem)
+ var hasHeaders = new FileWriter(options.Path, contentType, rangeHeader, _logger, _fileSystem, _streamHelper)
{
OnComplete = options.OnComplete,
OnError = options.OnError,
@@ -590,11 +581,6 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
- if (totalContentLength.HasValue)
- {
- responseHeaders["Content-Length"] = totalContentLength.Value.ToString(UsCulture);
- }
-
if (isHeadRequest)
{
using (stream)
@@ -603,7 +589,7 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- var hasHeaders = new StreamWriter(stream, contentType, _logger)
+ var hasHeaders = new StreamWriter(stream, contentType)
{
OnComplete = options.OnComplete,
OnError = options.OnError
@@ -615,11 +601,6 @@ namespace Emby.Server.Implementations.HttpServer
}
/// <summary>
- /// The us culture
- /// </summary>
- private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
- /// <summary>
/// Adds the caching responseHeaders.
/// </summary>
private void AddCachingHeaders(IDictionary<string, string> responseHeaders, TimeSpan? cacheDuration,
@@ -627,23 +608,23 @@ namespace Emby.Server.Implementations.HttpServer
{
if (noCache)
{
- responseHeaders["Cache-Control"] = "no-cache, no-store, must-revalidate";
- responseHeaders["pragma"] = "no-cache, no-store, must-revalidate";
+ responseHeaders[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
+ responseHeaders[HeaderNames.Pragma] = "no-cache, no-store, must-revalidate";
return;
}
if (cacheDuration.HasValue)
{
- responseHeaders["Cache-Control"] = "public, max-age=" + cacheDuration.Value.TotalSeconds;
+ responseHeaders[HeaderNames.CacheControl] = "public, max-age=" + cacheDuration.Value.TotalSeconds;
}
else
{
- responseHeaders["Cache-Control"] = "public";
+ responseHeaders[HeaderNames.CacheControl] = "public";
}
if (lastModifiedDate.HasValue)
{
- responseHeaders["Last-Modified"] = lastModifiedDate.ToString();
+ responseHeaders[HeaderNames.LastModified] = lastModifiedDate.ToString();
}
}
@@ -656,7 +637,7 @@ namespace Emby.Server.Implementations.HttpServer
{
if (lastDateModified.HasValue)
{
- responseHeaders["Age"] = Convert.ToInt64((DateTime.UtcNow - lastDateModified.Value).TotalSeconds).ToString(CultureInfo.InvariantCulture);
+ responseHeaders[HeaderNames.Age] = Convert.ToInt64((DateTime.UtcNow - lastDateModified.Value).TotalSeconds).ToString(CultureInfo.InvariantCulture);
}
}
@@ -714,9 +695,4 @@ namespace Emby.Server.Implementations.HttpServer
}
}
}
-
- public interface IBrotliCompressor
- {
- byte[] Compress(byte[] content);
- }
}
diff --git a/Emby.Server.Implementations/HttpServer/IHttpListener.cs b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
index 835091361..005656d2c 100644
--- a/Emby.Server.Implementations/HttpServer/IHttpListener.cs
+++ b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
@@ -1,10 +1,9 @@
using System;
-using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.Net;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Services;
+using Microsoft.AspNetCore.Http;
namespace Emby.Server.Implementations.HttpServer
{
@@ -29,20 +28,10 @@ namespace Emby.Server.Implementations.HttpServer
Action<WebSocketConnectEventArgs> WebSocketConnected { get; set; }
/// <summary>
- /// Gets or sets the web socket connecting.
- /// </summary>
- /// <value>The web socket connecting.</value>
- Action<WebSocketConnectingEventArgs> WebSocketConnecting { get; set; }
-
- /// <summary>
- /// Starts this instance.
- /// </summary>
- /// <param name="urlPrefixes">The URL prefixes.</param>
- void Start(IEnumerable<string> urlPrefixes);
-
- /// <summary>
/// Stops this instance.
/// </summary>
Task Stop();
+
+ Task ProcessWebSocketRequest(HttpContext ctx);
}
}
diff --git a/Emby.Server.Implementations/HttpServer/LoggerUtils.cs b/Emby.Server.Implementations/HttpServer/LoggerUtils.cs
deleted file mode 100644
index d22d9db26..000000000
--- a/Emby.Server.Implementations/HttpServer/LoggerUtils.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System;
-using System.Globalization;
-using MediaBrowser.Model.Services;
-using Microsoft.Extensions.Logging;
-
-namespace Emby.Server.Implementations.HttpServer
-{
- public static class LoggerUtils
- {
- public static void LogRequest(ILogger logger, string url, string method, string userAgent, QueryParamCollection headers)
- {
- if (headers == null)
- {
- logger.LogInformation("{0} {1}. UserAgent: {2}", "HTTP " + method, url, userAgent ?? string.Empty);
- }
- else
- {
- var headerText = string.Empty;
- var index = 0;
-
- foreach (var i in headers)
- {
- if (index > 0)
- {
- headerText += ", ";
- }
-
- headerText += i.Name + "=" + i.Value;
-
- index++;
- }
-
- logger.LogInformation("HTTP {0} {1}. {2}", method, url, headerText);
- }
- }
-
- /// <summary>
- /// Logs the response.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="statusCode">The status code.</param>
- /// <param name="url">The URL.</param>
- /// <param name="endPoint">The end point.</param>
- /// <param name="duration">The duration.</param>
- public static void LogResponse(ILogger logger, int statusCode, string url, string endPoint, TimeSpan duration, QueryParamCollection headers)
- {
- var durationMs = duration.TotalMilliseconds;
- var logSuffix = durationMs >= 1000 && durationMs < 60000 ? "ms (slow)" : "ms";
-
- //var headerText = headers == null ? string.Empty : "Headers: " + string.Join(", ", headers.Where(i => i.Name.IndexOf("Access-", StringComparison.OrdinalIgnoreCase) == -1).Select(i => i.Name + "=" + i.Value).ToArray());
- var headerText = string.Empty;
- logger.LogInformation("HTTP Response {0} to {1}. Time: {2}{3}. {4} {5}", statusCode, endPoint, Convert.ToInt32(durationMs).ToString(CultureInfo.InvariantCulture), logSuffix, url, headerText);
- }
- }
-}
diff --git a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
index 891a76ec2..449159834 100644
--- a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
@@ -7,6 +7,7 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
namespace Emby.Server.Implementations.HttpServer
{
@@ -66,8 +67,8 @@ namespace Emby.Server.Implementations.HttpServer
this._logger = logger;
ContentType = contentType;
- Headers["Content-Type"] = contentType;
- Headers["Accept-Ranges"] = "bytes";
+ Headers[HeaderNames.ContentType] = contentType;
+ Headers[HeaderNames.AcceptRanges] = "bytes";
StatusCode = HttpStatusCode.PartialContent;
SetRangeValues(contentLength);
@@ -95,9 +96,7 @@ 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
- Headers["Content-Length"] = RangeLength.ToString(UsCulture);
- Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
+ 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 da2bf983a..a53d9bf0b 100644
--- a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
+++ b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
@@ -3,6 +3,7 @@ using System.Globalization;
using System.Text;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
namespace Emby.Server.Implementations.HttpServer
{
@@ -25,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-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-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-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
res.AddHeader("Access-Control-Allow-Origin", "*");
@@ -44,20 +45,19 @@ namespace Emby.Server.Implementations.HttpServer
if (dto is IHasHeaders hasHeaders)
{
- if (!hasHeaders.Headers.ContainsKey("Server"))
+ if (!hasHeaders.Headers.ContainsKey(HeaderNames.Server))
{
- hasHeaders.Headers["Server"] = "Microsoft-NetCore/2.0, UPnP/1.0 DLNADOC/1.50";
+ hasHeaders.Headers[HeaderNames.Server] = "Microsoft-NetCore/2.0, UPnP/1.0 DLNADOC/1.50";
}
// Content length has to be explicitly set on on HttpListenerResponse or it won't be happy
- if (hasHeaders.Headers.TryGetValue("Content-Length", out string contentLength)
+ if (hasHeaders.Headers.TryGetValue(HeaderNames.ContentLength, out string contentLength)
&& !string.IsNullOrEmpty(contentLength))
{
var length = long.Parse(contentLength, UsCulture);
if (length > 0)
{
- res.SetContentLength(length);
res.SendChunked = false;
}
}
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
index cab41e65b..276312a30 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.Services;
+using Microsoft.Net.Http.Headers;
namespace Emby.Server.Implementations.HttpServer.Security
{
@@ -176,7 +177,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
if (string.IsNullOrEmpty(auth))
{
- auth = httpReq.Headers["Authorization"];
+ auth = httpReq.Headers[HeaderNames.Authorization];
}
return GetAuthorization(auth);
diff --git a/Emby.Server.Implementations/HttpServer/StreamWriter.cs b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
index 3269d44cf..66a13e20d 100644
--- a/Emby.Server.Implementations/HttpServer/StreamWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
@@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
namespace Emby.Server.Implementations.HttpServer
{
@@ -14,8 +15,6 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
public class StreamWriter : IAsyncStreamWriter, IHasHeaders
{
- private ILogger Logger { get; set; }
-
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
@@ -45,7 +44,7 @@ namespace Emby.Server.Implementations.HttpServer
/// <param name="source">The source.</param>
/// <param name="contentType">Type of the content.</param>
/// <param name="logger">The logger.</param>
- public StreamWriter(Stream source, string contentType, ILogger logger)
+ public StreamWriter(Stream source, string contentType)
{
if (string.IsNullOrEmpty(contentType))
{
@@ -53,14 +52,8 @@ namespace Emby.Server.Implementations.HttpServer
}
SourceStream = source;
- Logger = logger;
-
- Headers["Content-Type"] = contentType;
- if (source.CanSeek)
- {
- Headers["Content-Length"] = source.Length.ToString(UsCulture);
- }
+ Headers[HeaderNames.ContentType] = contentType;
}
/// <summary>
@@ -68,8 +61,7 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
/// <param name="source">The source.</param>
/// <param name="contentType">Type of the content.</param>
- /// <param name="logger">The logger.</param>
- public StreamWriter(byte[] source, string contentType, int contentLength, ILogger logger)
+ public StreamWriter(byte[] source, string contentType)
{
if (string.IsNullOrEmpty(contentType))
{
@@ -77,11 +69,8 @@ namespace Emby.Server.Implementations.HttpServer
}
SourceBytes = source;
- Logger = logger;
-
- Headers["Content-Type"] = contentType;
- Headers["Content-Length"] = contentLength.ToString(UsCulture);
+ Headers[HeaderNames.ContentType] = contentType;
}
public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
index e9d0bac74..54a16040f 100644
--- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
+++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
@@ -8,6 +8,7 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
+using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using UtfUnknown;
@@ -67,7 +68,7 @@ namespace Emby.Server.Implementations.HttpServer
/// Gets or sets the query string.
/// </summary>
/// <value>The query string.</value>
- public QueryParamCollection QueryString { get; set; }
+ public IQueryCollection QueryString { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
@@ -101,12 +102,6 @@ namespace Emby.Server.Implementations.HttpServer
_socket = socket;
_socket.OnReceiveBytes = OnReceiveInternal;
- var memorySocket = socket as IMemoryWebSocket;
- if (memorySocket != null)
- {
- memorySocket.OnReceiveMemoryBytes = OnReceiveInternal;
- }
-
RemoteEndPoint = remoteEndPoint;
_logger = logger;
@@ -142,34 +137,6 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- /// <summary>
- /// Called when [receive].
- /// </summary>
- /// <param name="memory">The memory block.</param>
- /// <param name="length">The length of the memory block.</param>
- private void OnReceiveInternal(Memory<byte> memory, int length)
- {
- LastActivityDate = DateTime.UtcNow;
-
- if (OnReceive == null)
- {
- return;
- }
-
- var bytes = memory.Slice(0, length).ToArray();
-
- var charset = CharsetDetector.DetectFromBytes(bytes).Detected?.EncodingName;
-
- if (string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase))
- {
- OnReceiveInternal(Encoding.UTF8.GetString(bytes, 0, bytes.Length));
- }
- else
- {
- OnReceiveInternal(Encoding.ASCII.GetString(bytes, 0, bytes.Length));
- }
- }
-
private void OnReceiveInternal(string message)
{
LastActivityDate = DateTime.UtcNow;
@@ -193,7 +160,7 @@ namespace Emby.Server.Implementations.HttpServer
var info = new WebSocketMessageInfo
{
MessageType = stub.MessageType,
- Data = stub.Data == null ? null : stub.Data.ToString(),
+ Data = stub.Data?.ToString(),
Connection = this
};