aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/HttpServer
diff options
context:
space:
mode:
authorAndrew Rabert <6550543+nvllsvm@users.noreply.github.com>2019-01-22 18:13:47 -0500
committerGitHub <noreply@github.com>2019-01-22 18:13:47 -0500
commit28483bdb54be96ae83e0fded097f534d7e26ba1e (patch)
treee7f4b92326417ebf55eecdf68a01d2c3b9e660d7 /Emby.Server.Implementations/HttpServer
parent920c39454c05e979eabe81877269cd4517a03ccf (diff)
parent8106c8393b711a7e1d40487e3caf2b014decbe28 (diff)
Merge pull request #651 from jellyfin/release-10.1.0
Release 10.1.0
Diffstat (limited to 'Emby.Server.Implementations/HttpServer')
-rw-r--r--Emby.Server.Implementations/HttpServer/FileWriter.cs19
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs180
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs83
-rw-r--r--Emby.Server.Implementations/HttpServer/IHttpListener.cs6
-rw-r--r--Emby.Server.Implementations/HttpServer/LoggerUtils.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs20
-rw-r--r--Emby.Server.Implementations/HttpServer/ResponseFilter.cs30
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthService.cs17
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs15
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/SessionContext.cs8
-rw-r--r--Emby.Server.Implementations/HttpServer/StreamWriter.cs12
-rw-r--r--Emby.Server.Implementations/HttpServer/WebSocketConnection.cs55
12 files changed, 168 insertions, 279 deletions
diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs
index 1a875e533..c32c91670 100644
--- a/Emby.Server.Implementations/HttpServer/FileWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs
@@ -1,13 +1,13 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
-using Microsoft.Extensions.Logging;
using MediaBrowser.Model.Services;
-using System.Linq;
+using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.HttpServer
{
@@ -38,10 +38,7 @@ namespace Emby.Server.Implementations.HttpServer
/// Gets the options.
/// </summary>
/// <value>The options.</value>
- public IDictionary<string, string> Headers
- {
- get { return _options; }
- }
+ public IDictionary<string, string> Headers => _options;
public string Path { get; set; }
@@ -49,7 +46,7 @@ namespace Emby.Server.Implementations.HttpServer
{
if (string.IsNullOrEmpty(contentType))
{
- throw new ArgumentNullException("contentType");
+ throw new ArgumentNullException(nameof(contentType));
}
Path = path;
@@ -148,7 +145,7 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private string[] SkipLogExtensions = new string[]
+ private string[] SkipLogExtensions = new string[]
{
".js",
".html",
@@ -203,8 +200,8 @@ namespace Emby.Server.Implementations.HttpServer
public HttpStatusCode StatusCode
{
- get { return (HttpStatusCode)Status; }
- set { Status = (int)value; }
+ 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 69ca0f85b..834ffb130 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -1,27 +1,25 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Net;
-using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Emby.Server.Implementations.Net;
using Emby.Server.Implementations.Services;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Security;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Model.Events;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
-using MediaBrowser.Model.Text;
-using System.Net.Sockets;
-using Emby.Server.Implementations.Net;
-using MediaBrowser.Model.Events;
+using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.HttpServer
{
@@ -38,11 +36,7 @@ namespace Emby.Server.Implementations.HttpServer
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
-
private readonly IServerApplicationHost _appHost;
-
- private readonly ITextEncoding _textEncoding;
-
private readonly IJsonSerializer _jsonSerializer;
private readonly IXmlSerializer _xmlSerializer;
private readonly Func<Type, Func<string, object>> _funcParseFn;
@@ -55,47 +49,32 @@ namespace Emby.Server.Implementations.HttpServer
private IWebSocketListener[] _webSocketListeners = Array.Empty<IWebSocketListener>();
private readonly List<IWebSocketConnection> _webSocketConnections = new List<IWebSocketConnection>();
- public HttpListenerHost(IServerApplicationHost applicationHost,
- ILogger logger,
+ public HttpListenerHost(
+ IServerApplicationHost applicationHost,
+ ILoggerFactory loggerFactory,
IServerConfigurationManager config,
- string defaultRedirectPath, INetworkManager networkManager, ITextEncoding textEncoding, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer, Func<Type, Func<string, object>> funcParseFn)
+ string defaultRedirectPath,
+ INetworkManager networkManager,
+ IJsonSerializer jsonSerializer,
+ IXmlSerializer xmlSerializer,
+ Func<Type, Func<string, object>> funcParseFn)
{
- Instance = this;
-
_appHost = applicationHost;
+ _logger = loggerFactory.CreateLogger("HttpServer");
+ _config = config;
DefaultRedirectPath = defaultRedirectPath;
_networkManager = networkManager;
- _textEncoding = textEncoding;
_jsonSerializer = jsonSerializer;
_xmlSerializer = xmlSerializer;
- _config = config;
-
- _logger = logger;
_funcParseFn = funcParseFn;
- ResponseFilters = new Action<IRequest, IResponse, object>[] { };
+ Instance = this;
+ ResponseFilters = Array.Empty<Action<IRequest, IResponse, object>>();
}
public string GlobalResponse { get; set; }
- readonly Dictionary<Type, int> _mapExceptionToStatusCode = new Dictionary<Type, int>
- {
- {typeof (ResourceNotFoundException), 404},
- {typeof (RemoteServiceUnavailableException), 502},
- {typeof (FileNotFoundException), 404},
- //{typeof (DirectoryNotFoundException), 404},
- {typeof (SecurityException), 401},
- {typeof (PaymentRequiredException), 402},
- {typeof (ArgumentException), 400}
- };
-
- protected ILogger Logger
- {
- get
- {
- return _logger;
- }
- }
+ protected ILogger Logger => _logger;
public object CreateInstance(Type type)
{
@@ -103,7 +82,7 @@ namespace Emby.Server.Implementations.HttpServer
}
/// <summary>
- /// Applies the request filters. Returns whether or not the request has been handled
+ /// Applies the request filters. Returns whether or not the request has been handled
/// and no more processing should be done.
/// </summary>
/// <returns></returns>
@@ -111,9 +90,9 @@ namespace Emby.Server.Implementations.HttpServer
{
//Exec all RequestFilter attributes with Priority < 0
var attributes = GetRequestFilterAttributes(requestDto.GetType());
- var i = 0;
- var count = attributes.Count;
+ int count = attributes.Count;
+ int i = 0;
for (; i < count && attributes[i].Priority < 0; i++)
{
var attribute = attributes[i];
@@ -130,8 +109,7 @@ namespace Emby.Server.Implementations.HttpServer
public Type GetServiceTypeByRequest(Type requestType)
{
- Type serviceType;
- ServiceOperationsMap.TryGetValue(requestType, out serviceType);
+ ServiceOperationsMap.TryGetValue(requestType, out var serviceType);
return serviceType;
}
@@ -162,7 +140,7 @@ namespace Emby.Server.Implementations.HttpServer
return;
}
- var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger, _textEncoding)
+ var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger)
{
OnReceive = ProcessWebSocketMessageReceived,
Url = e.Url,
@@ -176,10 +154,7 @@ namespace Emby.Server.Implementations.HttpServer
_webSocketConnections.Add(connection);
}
- if (WebSocketConnected != null)
- {
- WebSocketConnected?.Invoke(this, new GenericEventArgs<IWebSocketConnection>(connection));
- }
+ WebSocketConnected?.Invoke(this, new GenericEventArgs<IWebSocketConnection>(connection));
}
private void Connection_Closed(object sender, EventArgs e)
@@ -190,10 +165,9 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private Exception GetActualException(Exception ex)
+ private static Exception GetActualException(Exception ex)
{
- var agg = ex as AggregateException;
- if (agg != null)
+ if (ex is AggregateException agg)
{
var inner = agg.InnerException;
if (inner != null)
@@ -215,27 +189,16 @@ namespace Emby.Server.Implementations.HttpServer
private int GetStatusCode(Exception ex)
{
- if (ex is ArgumentException)
+ switch (ex)
{
- return 400;
- }
-
- var exceptionType = ex.GetType();
-
- int statusCode;
- if (!_mapExceptionToStatusCode.TryGetValue(exceptionType, out statusCode))
- {
- if (ex is DirectoryNotFoundException)
- {
- statusCode = 404;
- }
- else
- {
- statusCode = 500;
- }
+ case ArgumentException _: return 400;
+ case SecurityException _: return 401;
+ case DirectoryNotFoundException _:
+ case FileNotFoundException _:
+ case ResourceNotFoundException _: return 404;
+ case RemoteServiceUnavailableException _: return 502;
+ default: return 500;
}
-
- return statusCode;
}
private async Task ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStackTrace, bool logExceptionMessage)
@@ -321,32 +284,25 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private readonly Dictionary<string, int> _skipLogExtensions = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
+ private static readonly string[] _skipLogExtensions =
{
- {".js", 0},
- {".css", 0},
- {".woff", 0},
- {".woff2", 0},
- {".ttf", 0},
- {".html", 0}
+ ".js",
+ ".css",
+ ".woff",
+ ".woff2",
+ ".ttf",
+ ".html"
};
private bool EnableLogging(string url, string localPath)
{
var extension = GetExtension(url);
- if (string.IsNullOrEmpty(extension) || !_skipLogExtensions.ContainsKey(extension))
- {
- if (string.IsNullOrEmpty(localPath) || localPath.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) == -1)
- {
- return true;
- }
- }
-
- return false;
+ return ((string.IsNullOrEmpty(extension) || !_skipLogExtensions.Contains(extension))
+ && (string.IsNullOrEmpty(localPath) || localPath.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) == -1));
}
- private string GetExtension(string url)
+ private static string GetExtension(string url)
{
var parts = url.Split(new[] { '?' }, 2);
@@ -379,18 +335,18 @@ namespace Emby.Server.Implementations.HttpServer
string pagePathWithoutQueryString = url.Split(new[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0];
return newQueryString.Count > 0
- ? String.Format("{0}?{1}", pagePathWithoutQueryString, newQueryString)
+ ? string.Format("{0}?{1}", pagePathWithoutQueryString, newQueryString)
: pagePathWithoutQueryString;
}
- private string GetUrlToLog(string url)
+ private static string GetUrlToLog(string url)
{
url = RemoveQueryStringByKey(url, "api_key");
return url;
}
- private string NormalizeConfiguredLocalAddress(string address)
+ private static string NormalizeConfiguredLocalAddress(string address)
{
var index = address.Trim('/').IndexOf('/');
@@ -566,9 +522,7 @@ namespace Emby.Server.Implementations.HttpServer
return;
}
- if (string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase) ||
- string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase) ||
- localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1)
+ if (localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1)
{
httpRes.StatusCode = 200;
httpRes.ContentType = "text/html";
@@ -711,8 +665,7 @@ namespace Emby.Server.Implementations.HttpServer
return null;
}
- string contentType;
- var restPath = ServiceHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, out contentType);
+ var restPath = ServiceHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, out string contentType);
if (restPath != null)
{
@@ -723,11 +676,11 @@ 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 Task Write(IResponse response, string text)
+ private static Task Write(IResponse response, string text)
{
var bOutput = Encoding.UTF8.GetBytes(text);
response.SetContentLength(bOutput.Length);
@@ -737,14 +690,13 @@ namespace Emby.Server.Implementations.HttpServer
private void RedirectToSecureUrl(IHttpRequest httpReq, IResponse httpRes, string url)
{
- int currentPort;
- Uri uri;
- if (Uri.TryCreate(url, UriKind.Absolute, out uri))
+ if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
{
- currentPort = uri.Port;
- var builder = new UriBuilder(uri);
- builder.Port = _config.Configuration.PublicHttpsPort;
- builder.Scheme = "https";
+ var builder = new UriBuilder(uri)
+ {
+ Port = _config.Configuration.PublicHttpsPort,
+ Scheme = "https"
+ };
url = builder.Uri.ToString();
RedirectToUrl(httpRes, url);
@@ -844,16 +796,12 @@ namespace Emby.Server.Implementations.HttpServer
public Task<object> DeserializeJson(Type type, Stream stream)
{
- //using (var reader = new StreamReader(stream))
- //{
- // var json = reader.ReadToEnd();
- // logger.LogInformation(json);
- // return _jsonSerializer.DeserializeFromString(json, type);
- //}
return _jsonSerializer.DeserializeFromStreamAsync(stream, type);
}
- private string NormalizeEmbyRoutePath(string path)
+ //TODO Add Jellyfin Route Path Normalizer
+
+ private static string NormalizeEmbyRoutePath(string path)
{
if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase))
{
@@ -863,7 +811,7 @@ namespace Emby.Server.Implementations.HttpServer
return "emby/" + path;
}
- private string NormalizeMediaBrowserRoutePath(string path)
+ private static string NormalizeMediaBrowserRoutePath(string path)
{
if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase))
{
@@ -873,7 +821,7 @@ namespace Emby.Server.Implementations.HttpServer
return "mediabrowser/" + path;
}
- private string DoubleNormalizeEmbyRoutePath(string path)
+ private static string DoubleNormalizeEmbyRoutePath(string path)
{
if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase))
{
diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index 73b2afe64..8b60d61d4 100644
--- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -1,7 +1,3 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Net;
-using Microsoft.Extensions.Logging;
-using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -13,8 +9,12 @@ using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Emby.Server.Implementations.Services;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
+using Microsoft.Extensions.Logging;
using IRequest = MediaBrowser.Model.Services.IRequest;
using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
@@ -96,8 +96,7 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>();
}
- string expires;
- if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out expires))
+ if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string expires))
{
responseHeaders["Expires"] = "-1";
}
@@ -115,7 +114,8 @@ namespace Emby.Server.Implementations.HttpServer
string compressionType = null;
bool isHeadRequest = false;
- if (requestContext != null) {
+ if (requestContext != null)
+ {
compressionType = GetCompressionType(requestContext, content, contentType);
isHeadRequest = string.Equals(requestContext.Verb, "head", StringComparison.OrdinalIgnoreCase);
}
@@ -142,8 +142,7 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>();
}
- string expires;
- if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out expires))
+ if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string expires))
{
responseHeaders["Expires"] = "-1";
}
@@ -187,8 +186,7 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>();
}
- string expires;
- if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out expires))
+ if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string expires))
{
responseHeaders["Expires"] = "-1";
}
@@ -207,7 +205,7 @@ namespace Emby.Server.Implementations.HttpServer
{
if (result == null)
{
- throw new ArgumentNullException("result");
+ throw new ArgumentNullException(nameof(result));
}
if (responseHeaders == null)
@@ -245,7 +243,7 @@ namespace Emby.Server.Implementations.HttpServer
return GetCompressionType(request);
}
- private string GetCompressionType(IRequest request)
+ private static string GetCompressionType(IRequest request)
{
var acceptEncoding = request.Headers["Accept-Encoding"];
@@ -265,7 +263,7 @@ namespace Emby.Server.Implementations.HttpServer
}
/// <summary>
- /// Returns the optimized result for the IRequestContext.
+ /// Returns the optimized result for the IRequestContext.
/// Does not use or store results in any cache.
/// </summary>
/// <param name="request"></param>
@@ -365,7 +363,7 @@ namespace Emby.Server.Implementations.HttpServer
return _brotliCompressor.Compress(bytes);
}
- private byte[] Deflate(byte[] bytes)
+ private static byte[] Deflate(byte[] bytes)
{
// In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream
// Which means we must use MemoryStream since you have to use ToArray() on a closed Stream
@@ -379,7 +377,7 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private byte[] GZip(byte[] buffer)
+ private static byte[] GZip(byte[] buffer)
{
using (var ms = new MemoryStream())
using (var zipStream = new GZipStream(ms, CompressionMode.Compress))
@@ -398,7 +396,7 @@ namespace Emby.Server.Implementations.HttpServer
: contentType.Split(';')[0].ToLower().Trim();
}
- private string SerializeToXmlString(object from)
+ private static string SerializeToXmlString(object from)
{
using (var ms = new MemoryStream())
{
@@ -412,8 +410,10 @@ namespace Emby.Server.Implementations.HttpServer
serializer.WriteObject(xw, from);
xw.Flush();
ms.Seek(0, SeekOrigin.Begin);
- var reader = new StreamReader(ms);
- return reader.ReadToEnd();
+ using (var reader = new StreamReader(ms))
+ {
+ return reader.ReadToEnd();
+ }
}
}
}
@@ -425,7 +425,7 @@ namespace Emby.Server.Implementations.HttpServer
{
responseHeaders["ETag"] = string.Format("\"{0}\"", cacheKeyString);
- var noCache = (requestContext.Headers.Get("Cache-Control") ?? string.Empty).IndexOf("no-cache", StringComparison.OrdinalIgnoreCase) != -1;
+ bool noCache = (requestContext.Headers.Get("Cache-Control") ?? string.Empty).IndexOf("no-cache", StringComparison.OrdinalIgnoreCase) != -1;
if (!noCache)
{
@@ -453,7 +453,7 @@ namespace Emby.Server.Implementations.HttpServer
{
if (string.IsNullOrEmpty(path))
{
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
}
return GetStaticFileResult(requestContext, new StaticFileResultOptions
@@ -463,15 +463,14 @@ namespace Emby.Server.Implementations.HttpServer
});
}
- public Task<object> GetStaticFileResult(IRequest requestContext,
- StaticFileResultOptions options)
+ public Task<object> GetStaticFileResult(IRequest requestContext, StaticFileResultOptions options)
{
var path = options.Path;
var fileShare = options.FileShare;
if (string.IsNullOrEmpty(path))
{
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
}
if (fileShare != FileShareMode.Read && fileShare != FileShareMode.ReadWrite)
@@ -661,7 +660,7 @@ namespace Emby.Server.Implementations.HttpServer
/// <summary>
/// Adds the expires header.
/// </summary>
- private void AddExpiresHeader(IDictionary<string, string> responseHeaders, string cacheKey, TimeSpan? cacheDuration)
+ private static void AddExpiresHeader(IDictionary<string, string> responseHeaders, string cacheKey, TimeSpan? cacheDuration)
{
if (cacheDuration.HasValue)
{
@@ -678,7 +677,7 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
/// <param name="responseHeaders">The responseHeaders.</param>
/// <param name="lastDateModified">The last date modified.</param>
- private void AddAgeHeader(IDictionary<string, string> responseHeaders, DateTime? lastDateModified)
+ private static void AddAgeHeader(IDictionary<string, string> responseHeaders, DateTime? lastDateModified)
{
if (lastDateModified.HasValue)
{
@@ -699,36 +698,26 @@ namespace Emby.Server.Implementations.HttpServer
var ifModifiedSinceHeader = requestContext.Headers.Get("If-Modified-Since");
- if (!string.IsNullOrEmpty(ifModifiedSinceHeader))
+ if (!string.IsNullOrEmpty(ifModifiedSinceHeader)
+ && DateTime.TryParse(ifModifiedSinceHeader, out DateTime ifModifiedSince)
+ && IsNotModified(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified))
{
- DateTime ifModifiedSince;
-
- if (DateTime.TryParse(ifModifiedSinceHeader, out ifModifiedSince))
- {
- if (IsNotModified(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified))
- {
- return true;
- }
- }
+ return true;
}
var ifNoneMatchHeader = requestContext.Headers.Get("If-None-Match");
- var hasCacheKey = !cacheKey.Equals(Guid.Empty);
+ bool hasCacheKey = !cacheKey.Equals(Guid.Empty);
// Validate If-None-Match
- if ((hasCacheKey || !string.IsNullOrEmpty(ifNoneMatchHeader)))
+ if ((hasCacheKey && !string.IsNullOrEmpty(ifNoneMatchHeader)))
{
- Guid ifNoneMatch;
-
ifNoneMatchHeader = (ifNoneMatchHeader ?? string.Empty).Trim('\"');
- if (Guid.TryParse(ifNoneMatchHeader, out ifNoneMatch))
+ if (Guid.TryParse(ifNoneMatchHeader, out var ifNoneMatch)
+ && cacheKey.Equals(ifNoneMatch))
{
- if (hasCacheKey && cacheKey.Equals(ifNoneMatch))
- {
- return true;
- }
+ return true;
}
}
@@ -771,7 +760,7 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
/// <param name="date">The date.</param>
/// <returns>DateTime.</returns>
- private DateTime NormalizeDateForComparison(DateTime date)
+ private static DateTime NormalizeDateForComparison(DateTime date)
{
return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
}
@@ -781,7 +770,7 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
/// <param name="hasHeaders">The has options.</param>
/// <param name="responseHeaders">The response headers.</param>
- private void AddResponseHeaders(IHasHeaders hasHeaders, IEnumerable<KeyValuePair<string, string>> responseHeaders)
+ private static void AddResponseHeaders(IHasHeaders hasHeaders, IEnumerable<KeyValuePair<string, string>> responseHeaders)
{
foreach (var item in responseHeaders)
{
diff --git a/Emby.Server.Implementations/HttpServer/IHttpListener.cs b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
index e21607ebd..835091361 100644
--- a/Emby.Server.Implementations/HttpServer/IHttpListener.cs
+++ b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
@@ -1,10 +1,10 @@
-using MediaBrowser.Controller.Net;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Model.Services;
using Emby.Server.Implementations.Net;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Model.Services;
namespace Emby.Server.Implementations.HttpServer
{
@@ -33,7 +33,7 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
/// <value>The web socket connecting.</value>
Action<WebSocketConnectingEventArgs> WebSocketConnecting { get; set; }
-
+
/// <summary>
/// Starts this instance.
/// </summary>
diff --git a/Emby.Server.Implementations/HttpServer/LoggerUtils.cs b/Emby.Server.Implementations/HttpServer/LoggerUtils.cs
index 5b7bbe79c..d22d9db26 100644
--- a/Emby.Server.Implementations/HttpServer/LoggerUtils.cs
+++ b/Emby.Server.Implementations/HttpServer/LoggerUtils.cs
@@ -1,7 +1,7 @@
-using Microsoft.Extensions.Logging;
using System;
using System.Globalization;
using MediaBrowser.Model.Services;
+using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.HttpServer
{
diff --git a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
index dc20ee1a2..891a76ec2 100644
--- a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
@@ -1,4 +1,3 @@
-using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -7,6 +6,7 @@ using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
+using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.HttpServer
{
@@ -40,16 +40,11 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
- public List<Cookie> Cookies { get; private set; }
-
/// <summary>
/// Additional HTTP Headers
/// </summary>
/// <value>The headers.</value>
- public IDictionary<string, string> Headers
- {
- get { return _options; }
- }
+ public IDictionary<string, string> Headers => _options;
/// <summary>
/// Initializes a new instance of the <see cref="StreamWriter" /> class.
@@ -62,7 +57,7 @@ namespace Emby.Server.Implementations.HttpServer
{
if (string.IsNullOrEmpty(contentType))
{
- throw new ArgumentNullException("contentType");
+ throw new ArgumentNullException(nameof(contentType));
}
RangeHeader = rangeHeader;
@@ -75,7 +70,6 @@ namespace Emby.Server.Implementations.HttpServer
Headers["Accept-Ranges"] = "bytes";
StatusCode = HttpStatusCode.PartialContent;
- Cookies = new List<Cookie>();
SetRangeValues(contentLength);
}
@@ -186,7 +180,7 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private async Task CopyToInternalAsync(Stream source, Stream destination, long copyLength)
+ private static async Task CopyToInternalAsync(Stream source, Stream destination, long copyLength)
{
var array = new byte[BufferSize];
int bytesRead;
@@ -220,10 +214,8 @@ namespace Emby.Server.Implementations.HttpServer
public HttpStatusCode StatusCode
{
- get { return (HttpStatusCode)Status; }
- set { Status = (int)value; }
+ get => (HttpStatusCode)Status;
+ set => Status = (int)value;
}
-
- public string StatusDescription { get; set; }
}
}
diff --git a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
index f38aa5ea0..da2bf983a 100644
--- a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
+++ b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
@@ -1,8 +1,8 @@
-using Microsoft.Extensions.Logging;
using System;
using System.Globalization;
using System.Text;
using MediaBrowser.Model.Services;
+using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.HttpServer
{
@@ -25,14 +25,11 @@ namespace Emby.Server.Implementations.HttpServer
public void FilterResponse(IRequest req, IResponse res, object dto)
{
// Try to prevent compatibility view
- //res.AddHeader("X-UA-Compatible", "IE=Edge");
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", "*");
- var exception = dto as Exception;
-
- if (exception != null)
+ if (dto is Exception exception)
{
_logger.LogError(exception, "Error processing request for {RawUrl}", req.RawUrl);
@@ -45,43 +42,26 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- var hasHeaders = dto as IHasHeaders;
-
- if (hasHeaders != null)
+ if (dto is IHasHeaders hasHeaders)
{
if (!hasHeaders.Headers.ContainsKey("Server"))
{
hasHeaders.Headers["Server"] = "Microsoft-NetCore/2.0, UPnP/1.0 DLNADOC/1.50";
- //hasHeaders.Headers["Server"] = "Mono-HTTPAPI/1.1";
}
// Content length has to be explicitly set on on HttpListenerResponse or it won't be happy
- string contentLength;
-
- if (hasHeaders.Headers.TryGetValue("Content-Length", out contentLength) && !string.IsNullOrEmpty(contentLength))
+ if (hasHeaders.Headers.TryGetValue("Content-Length", out string contentLength)
+ && !string.IsNullOrEmpty(contentLength))
{
var length = long.Parse(contentLength, UsCulture);
if (length > 0)
{
res.SetContentLength(length);
-
- //var listenerResponse = res.OriginalResponse as HttpListenerResponse;
-
- //if (listenerResponse != null)
- //{
- // // Disable chunked encoding. Technically this is only needed when using Content-Range, but
- // // anytime we know the content length there's no need for it
- // listenerResponse.SendChunked = false;
- // return;
- //}
-
res.SendChunked = false;
}
}
}
-
- //res.KeepAlive = false;
}
/// <summary>
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
index e153d6f71..499a334fc 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
@@ -1,15 +1,13 @@
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Connect;
-using MediaBrowser.Controller.Devices;
+using System;
+using System.Linq;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
-using System;
-using System.Linq;
using MediaBrowser.Model.Services;
-using MediaBrowser.Common.Net;
namespace Emby.Server.Implementations.HttpServer.Security
{
@@ -173,7 +171,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
return false;
}
- private void ValidateRoles(string[] roles, User user)
+ private static void ValidateRoles(string[] roles, User user)
{
if (roles.Contains("admin", StringComparer.OrdinalIgnoreCase))
{
@@ -207,10 +205,9 @@ namespace Emby.Server.Implementations.HttpServer.Security
}
}
- private AuthenticationInfo GetTokenInfo(IRequest request)
+ private static AuthenticationInfo GetTokenInfo(IRequest request)
{
- object info;
- request.Items.TryGetValue("OriginalAuthenticationInfo", out info);
+ request.Items.TryGetValue("OriginalAuthenticationInfo", out var info);
return info as AuthenticationInfo;
}
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
index c3e2d3170..cab41e65b 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -1,12 +1,10 @@
-using MediaBrowser.Controller.Connect;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Controller.Security;
using System;
using System.Collections.Generic;
-using MediaBrowser.Model.Services;
using System.Linq;
-using System.Threading;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Security;
+using MediaBrowser.Model.Services;
namespace Emby.Server.Implementations.HttpServer.Security
{
@@ -28,8 +26,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
public AuthorizationInfo GetAuthorizationInfo(IRequest requestContext)
{
- object cached;
- if (requestContext.Items.TryGetValue("AuthorizationInfo", out cached))
+ if (requestContext.Items.TryGetValue("AuthorizationInfo", out var cached))
{
return (AuthorizationInfo)cached;
}
@@ -115,7 +112,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
{
info.Device = tokenInfo.DeviceName;
}
-
+
else if (!string.Equals(info.Device, tokenInfo.DeviceName, StringComparison.OrdinalIgnoreCase))
{
if (allowTokenInfoUpdate)
@@ -227,7 +224,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
return result;
}
- private string NormalizeValue(string value)
+ private static string NormalizeValue(string value)
{
if (string.IsNullOrEmpty(value))
{
diff --git a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
index a919ce008..81e11d312 100644
--- a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
@@ -1,11 +1,10 @@
-using MediaBrowser.Controller.Entities;
+using System;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
-using System.Threading.Tasks;
using MediaBrowser.Model.Services;
-using System;
namespace Emby.Server.Implementations.HttpServer.Security
{
@@ -32,8 +31,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
private AuthenticationInfo GetTokenInfo(IRequest request)
{
- object info;
- request.Items.TryGetValue("OriginalAuthenticationInfo", out info);
+ request.Items.TryGetValue("OriginalAuthenticationInfo", out var info);
return info as AuthenticationInfo;
}
diff --git a/Emby.Server.Implementations/HttpServer/StreamWriter.cs b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
index 0a44a5fe5..3269d44cf 100644
--- a/Emby.Server.Implementations/HttpServer/StreamWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
@@ -1,12 +1,11 @@
-using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
-
using MediaBrowser.Model.Services;
+using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.HttpServer
{
@@ -35,10 +34,7 @@ namespace Emby.Server.Implementations.HttpServer
/// Gets the options.
/// </summary>
/// <value>The options.</value>
- public IDictionary<string, string> Headers
- {
- get { return _options; }
- }
+ public IDictionary<string, string> Headers => _options;
public Action OnComplete { get; set; }
public Action OnError { get; set; }
@@ -53,7 +49,7 @@ namespace Emby.Server.Implementations.HttpServer
{
if (string.IsNullOrEmpty(contentType))
{
- throw new ArgumentNullException("contentType");
+ throw new ArgumentNullException(nameof(contentType));
}
SourceStream = source;
@@ -77,7 +73,7 @@ namespace Emby.Server.Implementations.HttpServer
{
if (string.IsNullOrEmpty(contentType))
{
- throw new ArgumentNullException("contentType");
+ throw new ArgumentNullException(nameof(contentType));
}
SourceBytes = source;
diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
index 914fa9dbc..e9d0bac74 100644
--- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
+++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
@@ -1,15 +1,15 @@
-using System.Text;
+using System;
+using System.Net.WebSockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Emby.Server.Implementations.Net;
using MediaBrowser.Controller.Net;
-using Microsoft.Extensions.Logging;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
using MediaBrowser.Model.Services;
-using MediaBrowser.Model.Text;
-using System.Net.WebSockets;
-using Emby.Server.Implementations.Net;
+using Microsoft.Extensions.Logging;
+using UtfUnknown;
namespace Emby.Server.Implementations.HttpServer
{
@@ -68,7 +68,6 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
/// <value>The query string.</value>
public QueryParamCollection QueryString { get; set; }
- private readonly ITextEncoding _textEncoding;
/// <summary>
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
@@ -77,24 +76,24 @@ namespace Emby.Server.Implementations.HttpServer
/// <param name="remoteEndPoint">The remote end point.</param>
/// <param name="jsonSerializer">The json serializer.</param>
/// <param name="logger">The logger.</param>
- /// <exception cref="System.ArgumentNullException">socket</exception>
- public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger, ITextEncoding textEncoding)
+ /// <exception cref="ArgumentNullException">socket</exception>
+ public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger)
{
if (socket == null)
{
- throw new ArgumentNullException("socket");
+ throw new ArgumentNullException(nameof(socket));
}
if (string.IsNullOrEmpty(remoteEndPoint))
{
- throw new ArgumentNullException("remoteEndPoint");
+ throw new ArgumentNullException(nameof(remoteEndPoint));
}
if (jsonSerializer == null)
{
- throw new ArgumentNullException("jsonSerializer");
+ throw new ArgumentNullException(nameof(jsonSerializer));
}
if (logger == null)
{
- throw new ArgumentNullException("logger");
+ throw new ArgumentNullException(nameof(logger));
}
Id = Guid.NewGuid();
@@ -110,7 +109,6 @@ namespace Emby.Server.Implementations.HttpServer
RemoteEndPoint = remoteEndPoint;
_logger = logger;
- _textEncoding = textEncoding;
socket.Closed += socket_Closed;
}
@@ -132,8 +130,7 @@ namespace Emby.Server.Implementations.HttpServer
{
return;
}
-
- var charset = _textEncoding.GetDetectedEncodingName(bytes, bytes.Length, null, false);
+ var charset = CharsetDetector.DetectFromBytes(bytes).Detected?.EncodingName;
if (string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase))
{
@@ -141,14 +138,15 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
- OnReceiveInternal(_textEncoding.GetASCIIEncoding().GetString(bytes, 0, bytes.Length));
+ OnReceiveInternal(Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
/// <summary>
/// Called when [receive].
/// </summary>
- /// <param name="bytes">The bytes.</param>
+ /// <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;
@@ -160,7 +158,7 @@ namespace Emby.Server.Implementations.HttpServer
var bytes = memory.Slice(0, length).ToArray();
- var charset = _textEncoding.GetDetectedEncodingName(bytes, bytes.Length, null, false);
+ var charset = CharsetDetector.DetectFromBytes(bytes).Detected?.EncodingName;
if (string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase))
{
@@ -168,7 +166,7 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
- OnReceiveInternal(_textEncoding.GetASCIIEncoding().GetString(bytes, 0, bytes.Length));
+ OnReceiveInternal(Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
@@ -214,12 +212,12 @@ namespace Emby.Server.Implementations.HttpServer
/// <param name="message">The message.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException">message</exception>
+ /// <exception cref="ArgumentNullException">message</exception>
public Task SendAsync<T>(WebSocketMessage<T> message, CancellationToken cancellationToken)
{
if (message == null)
{
- throw new ArgumentNullException("message");
+ throw new ArgumentNullException(nameof(message));
}
var json = _jsonSerializer.SerializeToString(message);
@@ -237,7 +235,7 @@ namespace Emby.Server.Implementations.HttpServer
{
if (buffer == null)
{
- throw new ArgumentNullException("buffer");
+ throw new ArgumentNullException(nameof(buffer));
}
cancellationToken.ThrowIfCancellationRequested();
@@ -249,7 +247,7 @@ namespace Emby.Server.Implementations.HttpServer
{
if (string.IsNullOrEmpty(text))
{
- throw new ArgumentNullException("text");
+ throw new ArgumentNullException(nameof(text));
}
cancellationToken.ThrowIfCancellationRequested();
@@ -261,10 +259,7 @@ namespace Emby.Server.Implementations.HttpServer
/// Gets the state.
/// </summary>
/// <value>The state.</value>
- public WebSocketState State
- {
- get { return _socket.State; }
- }
+ public WebSocketState State => _socket.State;
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.