From ddd1a282ea6398ee26d74321338d0445d0a0c796 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 7 Jul 2019 21:03:26 +0200 Subject: Remove IpAddressInfo and IpEndPointInfo classes --- Emby.Server.Implementations/ApplicationHost.cs | 53 +++++++++++++++++--------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 120aade392..c6ba2326aa 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Sockets; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; @@ -1546,14 +1547,22 @@ namespace Emby.Server.Implementations return null; } - public string GetLocalApiUrl(IpAddressInfo ipAddress) + public string GetLocalApiUrl(IPAddress ipAddress) { - if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) + if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) { - return GetLocalApiUrl("[" + ipAddress.Address + "]"); + // Remove the scope id from IPv6 addresses + var str = ipAddress.ToString(); + var index = str.IndexOf('%'); + if (index != -1) + { + str = str.Substring(0, index); + } + + return GetLocalApiUrl("[" + str + "]"); } - return GetLocalApiUrl(ipAddress.Address); + return GetLocalApiUrl(ipAddress.ToString()); } public string GetLocalApiUrl(string host) @@ -1564,19 +1573,28 @@ namespace Emby.Server.Implementations host, HttpsPort.ToString(CultureInfo.InvariantCulture)); } + return string.Format("http://{0}:{1}", host, HttpPort.ToString(CultureInfo.InvariantCulture)); } - public string GetWanApiUrl(IpAddressInfo ipAddress) + public string GetWanApiUrl(IPAddress ipAddress) { - if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) + if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) { - return GetWanApiUrl("[" + ipAddress.Address + "]"); + // Remove the scope id from IPv6 addresses + var str = ipAddress.ToString(); + var index = str.IndexOf('%'); + if (index != -1) + { + str = str.Substring(0, index); + } + + return GetWanApiUrl("[" + str + "]"); } - return GetWanApiUrl(ipAddress.Address); + return GetWanApiUrl(ipAddress.ToString()); } public string GetWanApiUrl(string host) @@ -1587,17 +1605,18 @@ namespace Emby.Server.Implementations host, ServerConfigurationManager.Configuration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture)); } + return string.Format("http://{0}:{1}", host, ServerConfigurationManager.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture)); } - public Task> GetLocalIpAddresses(CancellationToken cancellationToken) + public Task> GetLocalIpAddresses(CancellationToken cancellationToken) { return GetLocalIpAddressesInternal(true, 0, cancellationToken); } - private async Task> GetLocalIpAddressesInternal(bool allowLoopback, int limit, CancellationToken cancellationToken) + private async Task> GetLocalIpAddressesInternal(bool allowLoopback, int limit, CancellationToken cancellationToken) { var addresses = ServerConfigurationManager .Configuration @@ -1611,13 +1630,13 @@ namespace Emby.Server.Implementations addresses.AddRange(NetworkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces)); } - var resultList = new List(); + var resultList = new List(); foreach (var address in addresses) { if (!allowLoopback) { - if (address.Equals(IpAddressInfo.Loopback) || address.Equals(IpAddressInfo.IPv6Loopback)) + if (address.Equals(IPAddress.Loopback) || address.Equals(IPAddress.IPv6Loopback)) { continue; } @@ -1638,7 +1657,7 @@ namespace Emby.Server.Implementations return resultList; } - private IpAddressInfo NormalizeConfiguredLocalAddress(string address) + private IPAddress NormalizeConfiguredLocalAddress(string address) { var index = address.Trim('/').IndexOf('/'); @@ -1647,7 +1666,7 @@ namespace Emby.Server.Implementations address = address.Substring(index + 1); } - if (NetworkManager.TryParseIpAddress(address.Trim('/'), out IpAddressInfo result)) + if (IPAddress.TryParse(address.Trim('/'), out IPAddress result)) { return result; } @@ -1657,10 +1676,10 @@ namespace Emby.Server.Implementations private readonly ConcurrentDictionary _validAddressResults = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - private async Task IsIpAddressValidAsync(IpAddressInfo address, CancellationToken cancellationToken) + private async Task IsIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken) { - if (address.Equals(IpAddressInfo.Loopback) || - address.Equals(IpAddressInfo.IPv6Loopback)) + if (address.Equals(IPAddress.Loopback) || + address.Equals(IPAddress.IPv6Loopback)) { return true; } -- cgit v1.2.3 From 8270d0cc91783c0c8c052b43af0d633edb8b6b04 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 25 Jul 2019 00:23:56 +0200 Subject: Move IPv6 scope id removal logic to it's own function --- Emby.Server.Implementations/ApplicationHost.cs | 32 +++++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index c6ba2326aa..ef2f59d303 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1547,17 +1547,27 @@ namespace Emby.Server.Implementations return null; } + /// + /// Removes the scope id from IPv6 addresses. + /// + /// The IPv6 address. + /// The IPv6 address without the scope id. + private string RemoveScopeId(string address) + { + var index = address.IndexOf('%'); + if (index == -1) + { + return address; + } + + return address.Substring(0, index); + } + public string GetLocalApiUrl(IPAddress ipAddress) { if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) { - // Remove the scope id from IPv6 addresses - var str = ipAddress.ToString(); - var index = str.IndexOf('%'); - if (index != -1) - { - str = str.Substring(0, index); - } + var str = RemoveScopeId(ipAddress.ToString()); return GetLocalApiUrl("[" + str + "]"); } @@ -1583,13 +1593,7 @@ namespace Emby.Server.Implementations { if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) { - // Remove the scope id from IPv6 addresses - var str = ipAddress.ToString(); - var index = str.IndexOf('%'); - if (index != -1) - { - str = str.Substring(0, index); - } + var str = RemoveScopeId(ipAddress.ToString()); return GetWanApiUrl("[" + str + "]"); } -- cgit v1.2.3 From 9fff4b060e06569ca77636643901aa42767e318d Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 28 Jul 2019 23:53:19 +0200 Subject: Replace custom code with Asp.Net Core code --- Emby.Server.Implementations/ApplicationHost.cs | 6 +- .../HttpServer/FileWriter.cs | 174 +++--- .../HttpServer/HttpListenerHost.cs | 154 ++--- .../HttpServer/ResponseFilter.cs | 26 +- .../HttpServer/Security/AuthService.cs | 48 +- Emby.Server.Implementations/Services/HttpResult.cs | 9 +- .../Services/ResponseHelper.cs | 31 +- .../Services/ServiceController.cs | 4 - .../Services/ServiceExec.cs | 2 +- .../Services/ServiceHandler.cs | 103 ++-- .../SocketSharp/RequestMono.cs | 647 --------------------- .../SocketSharp/WebSocketSharpRequest.cs | 230 +++----- .../SocketSharp/WebSocketSharpResponse.cs | 98 ---- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- .../Net/AuthenticatedAttribute.cs | 3 +- MediaBrowser.Model/Services/IHasRequestFilter.cs | 4 +- MediaBrowser.Model/Services/IRequest.cs | 30 +- 17 files changed, 370 insertions(+), 1201 deletions(-) delete mode 100644 Emby.Server.Implementations/SocketSharp/RequestMono.cs delete mode 100644 Emby.Server.Implementations/SocketSharp/WebSocketSharpResponse.cs (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index ef2f59d303..a89cf95d3b 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -676,7 +676,7 @@ namespace Emby.Server.Implementations var localPath = context.Request.Path.ToString(); var req = new WebSocketSharpRequest(request, response, request.Path, Logger); - await HttpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, CancellationToken.None).ConfigureAwait(false); + await HttpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false); } public static IStreamHelper StreamHelper { get; set; } @@ -785,7 +785,7 @@ namespace Emby.Server.Implementations HttpServer = new HttpListenerHost( this, - LoggerFactory, + LoggerFactory.CreateLogger(), ServerConfigurationManager, _configuration, NetworkManager, @@ -873,7 +873,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(authContext); serviceCollection.AddSingleton(new SessionContext(UserManager, authContext, SessionManager)); - AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, SessionManager, NetworkManager); + AuthService = new AuthService(authContext, ServerConfigurationManager, SessionManager, NetworkManager); serviceCollection.AddSingleton(AuthService); SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(LibraryManager, LoggerFactory, ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, ProcessFactory); diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs index ec41cc0a91..2890cca7ce 100644 --- a/Emby.Server.Implementations/HttpServer/FileWriter.cs +++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs @@ -1,50 +1,43 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Net; +using System.Runtime.InteropServices; 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.AspNetCore.Http; 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; } - - private long RangeStart { get; set; } - private long RangeEnd { get; set; } - private long RangeLength { get; set; } - public long TotalContentLength { get; set; } + private static readonly CultureInfo UsCulture = CultureInfo.ReadOnly(new CultureInfo("en-US")); - public Action OnComplete { get; set; } - public Action OnError { get; set; } - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - public List Cookies { get; private set; } + private static readonly string[] _skipLogExtensions = { + ".js", + ".html", + ".css" + }; - public FileShareMode FileShare { get; set; } + private readonly IStreamHelper _streamHelper; + private readonly ILogger _logger; + private readonly IFileSystem _fileSystem; /// /// The _options /// private readonly IDictionary _options = new Dictionary(); + /// - /// Gets the options. + /// The _requested ranges /// - /// The options. - public IDictionary Headers => _options; - - public string Path { get; set; } + private List> _requestedRanges; public FileWriter(string path, string contentType, string rangeHeader, ILogger logger, IFileSystem fileSystem, IStreamHelper streamHelper) { @@ -57,7 +50,7 @@ namespace Emby.Server.Implementations.HttpServer _fileSystem = fileSystem; Path = path; - Logger = logger; + _logger = logger; RangeHeader = rangeHeader; Headers[HeaderNames.ContentType] = contentType; @@ -80,39 +73,34 @@ namespace Emby.Server.Implementations.HttpServer Cookies = new List(); } - /// - /// Sets the range values. - /// - private void SetRangeValues() - { - var requestedRange = RequestedRanges[0]; + private string RangeHeader { get; set; } - // If the requested range is "0-", we can optimize by just doing a stream copy - if (!requestedRange.Value.HasValue) - { - RangeEnd = TotalContentLength - 1; - } - else - { - RangeEnd = requestedRange.Value.Value; - } + private bool IsHeadRequest { get; set; } - RangeStart = requestedRange.Key; - RangeLength = 1 + RangeEnd - RangeStart; + private long RangeStart { get; set; } - // 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; + private long RangeEnd { get; set; } - Logger.LogDebug("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString); - } + private long RangeLength { get; set; } + + public long TotalContentLength { get; set; } + + public Action OnComplete { get; set; } + + public Action OnError { get; set; } + + public List Cookies { get; private set; } + + public FileShareMode FileShare { get; set; } /// - /// The _requested ranges + /// Gets the options. /// - private List> _requestedRanges; + /// The options. + public IDictionary Headers => _options; + + public string Path { get; set; } + /// /// Gets the requested ranges. /// @@ -139,6 +127,7 @@ namespace Emby.Server.Implementations.HttpServer { start = long.Parse(vals[0], UsCulture); } + if (!string.IsNullOrEmpty(vals[1])) { end = long.Parse(vals[1], UsCulture); @@ -152,13 +141,50 @@ namespace Emby.Server.Implementations.HttpServer } } - private static readonly string[] SkipLogExtensions = { - ".js", - ".html", - ".css" - }; + public string ContentType { get; set; } + + public IRequest RequestContext { get; set; } + + public object Response { get; set; } + + public int Status { get; set; } + + public HttpStatusCode StatusCode + { + get => (HttpStatusCode)Status; + set => Status = (int)value; + } + + /// + /// Sets the range values. + /// + private void SetRangeValues() + { + var requestedRange = RequestedRanges[0]; + + // If the requested range is "0-", we can optimize by just doing a stream copy + if (!requestedRange.Value.HasValue) + { + RangeEnd = TotalContentLength - 1; + } + else + { + RangeEnd = requestedRange.Value.Value; + } + + 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; - public async Task WriteToAsync(IResponse response, CancellationToken cancellationToken) + _logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString); + } + + public async Task WriteToAsync(HttpResponse response, CancellationToken cancellationToken) { try { @@ -176,16 +202,16 @@ namespace Emby.Server.Implementations.HttpServer { var extension = System.IO.Path.GetExtension(path); - if (extension == null || !SkipLogExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) + if (extension == null || !_skipLogExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) { - Logger.LogDebug("Transmit file {0}", path); + _logger.LogDebug("Transmit file {0}", path); } offset = 0; count = 0; } - await response.TransmitFile(path, offset, count, FileShare, _fileSystem, _streamHelper, cancellationToken).ConfigureAwait(false); + await TransmitFile(response.Body, path, offset, count, FileShare, cancellationToken).ConfigureAwait(false); } finally { @@ -193,18 +219,32 @@ namespace Emby.Server.Implementations.HttpServer } } - public string ContentType { get; set; } - - public IRequest RequestContext { get; set; } + public async Task TransmitFile(Stream stream, string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken) + { + var fileOpenOptions = FileOpenOptions.SequentialScan; - public object Response { get; set; } + // use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039 + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + fileOpenOptions |= FileOpenOptions.Asynchronous; + } - public int Status { get; set; } + using (var fs = _fileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, fileShareMode, fileOpenOptions)) + { + if (offset > 0) + { + fs.Position = offset; + } - public HttpStatusCode StatusCode - { - get => (HttpStatusCode)Status; - set => Status = (int)value; + if (count > 0) + { + await _streamHelper.CopyToAsync(fs, stream, count, cancellationToken).ConfigureAwait(false); + } + else + { + await fs.CopyToAsync(stream, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false); + } + } } } } diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index d8938964fa..4c233456c4 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -5,7 +5,6 @@ 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; @@ -30,11 +29,7 @@ namespace Emby.Server.Implementations.HttpServer { public class HttpListenerHost : IHttpServer, IDisposable { - private string DefaultRedirectPath { get; set; } - public string[] UrlPrefixes { get; private set; } - - public event EventHandler> WebSocketConnected; - + private readonly ILogger _logger; private readonly IServerConfigurationManager _config; private readonly INetworkManager _networkManager; private readonly IServerApplicationHost _appHost; @@ -42,18 +37,15 @@ namespace Emby.Server.Implementations.HttpServer private readonly IXmlSerializer _xmlSerializer; private readonly IHttpListener _socketListener; private readonly Func> _funcParseFn; - - public Action[] ResponseFilters { get; set; } - + private readonly string _defaultRedirectPath; private readonly Dictionary ServiceOperationsMap = new Dictionary(); - public static HttpListenerHost Instance { get; protected set; } - private IWebSocketListener[] _webSocketListeners = Array.Empty(); private readonly List _webSocketConnections = new List(); + private bool _disposed = false; public HttpListenerHost( IServerApplicationHost applicationHost, - ILoggerFactory loggerFactory, + ILogger logger, IServerConfigurationManager config, IConfiguration configuration, INetworkManager networkManager, @@ -62,9 +54,9 @@ namespace Emby.Server.Implementations.HttpServer IHttpListener socketListener) { _appHost = applicationHost; - Logger = loggerFactory.CreateLogger("HttpServer"); + _logger = logger; _config = config; - DefaultRedirectPath = configuration["HttpListenerHost:DefaultRedirectPath"]; + _defaultRedirectPath = configuration["HttpListenerHost:DefaultRedirectPath"]; _networkManager = networkManager; _jsonSerializer = jsonSerializer; _xmlSerializer = xmlSerializer; @@ -74,12 +66,20 @@ namespace Emby.Server.Implementations.HttpServer _funcParseFn = t => s => JsvReader.GetParseFn(t)(s); Instance = this; - ResponseFilters = Array.Empty>(); + ResponseFilters = Array.Empty>(); } + public Action[] ResponseFilters { get; set; } + + public static HttpListenerHost Instance { get; protected set; } + + public string[] UrlPrefixes { get; private set; } + public string GlobalResponse { get; set; } - protected ILogger Logger { get; } + public ServiceController ServiceController { get; private set; } + + public event EventHandler> WebSocketConnected; public object CreateInstance(Type type) { @@ -91,7 +91,7 @@ namespace Emby.Server.Implementations.HttpServer /// and no more processing should be done. /// /// - public void ApplyRequestFilters(IRequest req, IResponse res, object requestDto) + public void ApplyRequestFilters(IRequest req, HttpResponse res, object requestDto) { //Exec all RequestFilter attributes with Priority < 0 var attributes = GetRequestFilterAttributes(requestDto.GetType()); @@ -145,7 +145,7 @@ 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, @@ -215,16 +215,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.OriginalResponse.HasStarted) + if (httpRes.HasStarted) { return; } @@ -233,11 +233,11 @@ namespace Emby.Server.Implementations.HttpServer httpRes.StatusCode = statusCode; httpRes.ContentType = "text/html"; - await Write(httpRes, NormalizeExceptionMessage(ex.Message)).ConfigureAwait(false); + await httpRes.WriteAsync(NormalizeExceptionMessage(ex.Message)).ConfigureAwait(false); } 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)"); } } @@ -431,7 +431,7 @@ namespace Emby.Server.Implementations.HttpServer { httpRes.StatusCode = 503; httpRes.ContentType = "text/plain"; - await Write(httpRes, "Server shutting down").ConfigureAwait(false); + await httpRes.WriteAsync("Server shutting down", cancellationToken).ConfigureAwait(false); return; } @@ -439,7 +439,7 @@ namespace Emby.Server.Implementations.HttpServer { httpRes.StatusCode = 400; httpRes.ContentType = "text/plain"; - await Write(httpRes, "Invalid host").ConfigureAwait(false); + await httpRes.WriteAsync("Invalid host", cancellationToken).ConfigureAwait(false); return; } @@ -447,7 +447,7 @@ namespace Emby.Server.Implementations.HttpServer { httpRes.StatusCode = 403; httpRes.ContentType = "text/plain"; - await Write(httpRes, "Forbidden").ConfigureAwait(false); + await httpRes.WriteAsync("Forbidden", cancellationToken).ConfigureAwait(false); return; } @@ -460,28 +460,27 @@ namespace Emby.Server.Implementations.HttpServer if (string.Equals(httpReq.Verb, "OPTIONS", StringComparison.OrdinalIgnoreCase)) { httpRes.StatusCode = 200; - httpRes.AddHeader("Access-Control-Allow-Origin", "*"); - httpRes.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); - httpRes.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"); + httpRes.Headers.Add("Access-Control-Allow-Origin", "*"); + httpRes.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); + httpRes.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"); httpRes.ContentType = "text/plain"; - await Write(httpRes, string.Empty).ConfigureAwait(false); + await httpRes.WriteAsync(string.Empty, cancellationToken).ConfigureAwait(false); return; } 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)) { - RedirectToUrl(httpRes, DefaultRedirectPath); + httpRes.Redirect(_defaultRedirectPath); return; } if (string.Equals(localPath, "/emby", StringComparison.OrdinalIgnoreCase) || string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase)) { - RedirectToUrl(httpRes, "emby/" + DefaultRedirectPath); + httpRes.Redirect("emby/" + _defaultRedirectPath); return; } @@ -494,9 +493,10 @@ namespace Emby.Server.Implementations.HttpServer if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) { - await Write(httpRes, + await httpRes.WriteAsync( "EmbyPlease update your Emby bookmark to " + newUrl + "").ConfigureAwait(false); + newUrl + "\">" + newUrl + "", + cancellationToken).ConfigureAwait(false); return; } } @@ -511,34 +511,35 @@ namespace Emby.Server.Implementations.HttpServer if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) { - await Write(httpRes, + await httpRes.WriteAsync( "EmbyPlease update your Emby bookmark to " + newUrl + "").ConfigureAwait(false); + newUrl + "\">" + newUrl + "", + cancellationToken).ConfigureAwait(false); return; } } if (string.Equals(localPath, "/web", StringComparison.OrdinalIgnoreCase)) { - RedirectToUrl(httpRes, DefaultRedirectPath); + httpRes.Redirect(_defaultRedirectPath); return; } if (string.Equals(localPath, "/web/", StringComparison.OrdinalIgnoreCase)) { - RedirectToUrl(httpRes, "../" + DefaultRedirectPath); + httpRes.Redirect("../" + _defaultRedirectPath); return; } if (string.Equals(localPath, "/", StringComparison.OrdinalIgnoreCase)) { - RedirectToUrl(httpRes, DefaultRedirectPath); + httpRes.Redirect(_defaultRedirectPath); return; } if (string.IsNullOrEmpty(localPath)) { - RedirectToUrl(httpRes, "/" + DefaultRedirectPath); + httpRes.Redirect("/" + _defaultRedirectPath); return; } @@ -546,12 +547,12 @@ namespace Emby.Server.Implementations.HttpServer { if (localPath.EndsWith("web/dashboard.html", StringComparison.OrdinalIgnoreCase)) { - RedirectToUrl(httpRes, "index.html#!/dashboard.html"); + httpRes.Redirect("index.html#!/dashboard.html"); } if (localPath.EndsWith("web/home.html", StringComparison.OrdinalIgnoreCase)) { - RedirectToUrl(httpRes, "index.html"); + httpRes.Redirect("index.html"); } } @@ -562,7 +563,7 @@ namespace Emby.Server.Implementations.HttpServer { httpRes.StatusCode = 503; httpRes.ContentType = "text/html"; - await Write(httpRes, GlobalResponse).ConfigureAwait(false); + await httpRes.WriteAsync(GlobalResponse, cancellationToken).ConfigureAwait(false); return; } } @@ -571,7 +572,7 @@ namespace Emby.Server.Implementations.HttpServer if (handler != null) { - await handler.ProcessRequestAsync(this, httpReq, httpRes, Logger, cancellationToken).ConfigureAwait(false); + await handler.ProcessRequestAsync(this, httpReq, httpRes, _logger, cancellationToken).ConfigureAwait(false); } else { @@ -598,11 +599,7 @@ namespace Emby.Server.Implementations.HttpServer var elapsed = stopWatch.Elapsed; if (elapsed.TotalMilliseconds > 500) { - 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); + _logger.LogWarning("HTTP Response {StatusCode} to {RemoteIp}. Time (slow): {Elapsed:g}. {Url}", httpRes.StatusCode, remoteIp, elapsed, urlToLog); } } } @@ -619,18 +616,11 @@ namespace Emby.Server.Implementations.HttpServer return new ServiceHandler(restPath, contentType); } - 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.OriginalResponse.ContentLength = bOutput.Length; - return response.OutputStream.WriteAsync(bOutput, 0, bOutput.Length); - } - - private void RedirectToSecureUrl(IHttpRequest httpReq, IResponse httpRes, string url) + private void RedirectToSecureUrl(IHttpRequest httpReq, HttpResponse httpRes, string url) { if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri)) { @@ -640,23 +630,11 @@ namespace Emby.Server.Implementations.HttpServer Scheme = "https" }; url = builder.Uri.ToString(); - - RedirectToUrl(httpRes, url); - } - else - { - RedirectToUrl(httpRes, url); } - } - public static void RedirectToUrl(IResponse httpRes, string url) - { - httpRes.StatusCode = 302; - httpRes.AddHeader("Location", url); + httpRes.Redirect(url); } - public ServiceController ServiceController { get; private set; } - /// /// Adds the rest handlers. /// @@ -672,9 +650,9 @@ namespace Emby.Server.Implementations.HttpServer var types = services.Select(r => r.GetType()); ServiceController.Init(this, types); - ResponseFilters = new Action[] + ResponseFilters = new Action[] { - new ResponseFilter(Logger).FilterResponse + new ResponseFilter(_logger).FilterResponse }; } @@ -772,24 +750,23 @@ namespace Emby.Server.Implementations.HttpServer return "emby/emby/" + path; } - private bool _disposed; - private readonly object _disposeLock = new object(); + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } protected virtual void Dispose(bool disposing) { if (_disposed) return; - lock (_disposeLock) + if (disposing) { - if (_disposed) return; - - _disposed = true; - - if (disposing) - { - Stop(); - } + Stop(); } + + _disposed = true; } /// @@ -803,7 +780,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); IEnumerable GetTasks() { @@ -815,10 +792,5 @@ namespace Emby.Server.Implementations.HttpServer return Task.WhenAll(GetTasks()); } - - public void Dispose() - { - Dispose(true); - } } } diff --git a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs index 08f4247577..3e731366e2 100644 --- a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs +++ b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs @@ -2,6 +2,7 @@ using System; using System.Globalization; using System.Text; using MediaBrowser.Model.Services; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; @@ -9,7 +10,7 @@ namespace Emby.Server.Implementations.HttpServer { public class ResponseFilter { - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); + private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US")); private readonly ILogger _logger; public ResponseFilter(ILogger logger) @@ -23,12 +24,12 @@ namespace Emby.Server.Implementations.HttpServer /// The req. /// The res. /// The dto. - public void FilterResponse(IRequest req, IResponse res, object dto) + public void FilterResponse(IRequest req, HttpResponse 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-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); - res.AddHeader("Access-Control-Allow-Origin", "*"); + res.Headers.Add("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.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); + res.Headers.Add("Access-Control-Allow-Origin", "*"); if (dto is Exception exception) { @@ -39,7 +40,7 @@ namespace Emby.Server.Implementations.HttpServer var error = exception.Message.Replace(Environment.NewLine, " "); error = RemoveControlCharacters(error); - res.AddHeader("X-Application-Error-Code", error); + res.Headers.Add("X-Application-Error-Code", error); } } @@ -54,12 +55,11 @@ namespace Emby.Server.Implementations.HttpServer if (hasHeaders.Headers.TryGetValue(HeaderNames.ContentLength, out string contentLength) && !string.IsNullOrEmpty(contentLength)) { - var length = long.Parse(contentLength, UsCulture); + var length = long.Parse(contentLength, _usCulture); if (length > 0) { - res.OriginalResponse.ContentLength = length; - res.SendChunked = false; + res.ContentLength = length; } } } @@ -72,9 +72,12 @@ namespace Emby.Server.Implementations.HttpServer /// System.String. public static string RemoveControlCharacters(string inString) { - if (inString == null) return null; + if (inString == null) + { + return null; + } - var newString = new StringBuilder(); + var newString = new StringBuilder(inString.Length); foreach (var ch in inString) { @@ -83,6 +86,7 @@ namespace Emby.Server.Implementations.HttpServer newString.Append(ch); } } + return newString.ToString(); } } diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs index 1027883ed9..3d3f67ca22 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs @@ -3,7 +3,6 @@ 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; @@ -13,28 +12,23 @@ namespace Emby.Server.Implementations.HttpServer.Security { public class AuthService : IAuthService { + private readonly IAuthorizationContext _authorizationContext; + private readonly ISessionManager _sessionManager; private readonly IServerConfigurationManager _config; + private readonly INetworkManager _networkManager; - public AuthService(IUserManager userManager, IAuthorizationContext authorizationContext, IServerConfigurationManager config, ISessionManager sessionManager, INetworkManager networkManager) + public AuthService( + IAuthorizationContext authorizationContext, + IServerConfigurationManager config, + ISessionManager sessionManager, + INetworkManager networkManager) { - AuthorizationContext = authorizationContext; + _authorizationContext = authorizationContext; _config = config; - SessionManager = sessionManager; - UserManager = userManager; - NetworkManager = networkManager; + _sessionManager = sessionManager; + _networkManager = networkManager; } - public IUserManager UserManager { get; private set; } - public IAuthorizationContext AuthorizationContext { get; private set; } - public ISessionManager SessionManager { get; private set; } - public INetworkManager NetworkManager { get; private set; } - - /// - /// Redirect the client to a specific URL if authentication failed. - /// If this property is null, simply `401 Unauthorized` is returned. - /// - public string HtmlRedirect { get; set; } - public void Authenticate(IRequest request, IAuthenticationAttributes authAttribtues) { ValidateUser(request, authAttribtues); @@ -43,7 +37,7 @@ namespace Emby.Server.Implementations.HttpServer.Security private void ValidateUser(IRequest request, IAuthenticationAttributes authAttribtues) { // This code is executed before the service - var auth = AuthorizationContext.GetAuthorizationInfo(request); + var auth = _authorizationContext.GetAuthorizationInfo(request); if (!IsExemptFromAuthenticationToken(authAttribtues, request)) { @@ -80,7 +74,7 @@ namespace Emby.Server.Implementations.HttpServer.Security !string.IsNullOrEmpty(auth.Client) && !string.IsNullOrEmpty(auth.Device)) { - SessionManager.LogSessionActivity(auth.Client, + _sessionManager.LogSessionActivity(auth.Client, auth.Version, auth.DeviceId, auth.Device, @@ -89,7 +83,9 @@ namespace Emby.Server.Implementations.HttpServer.Security } } - private void ValidateUserAccess(User user, IRequest request, + private void ValidateUserAccess( + User user, + IRequest request, IAuthenticationAttributes authAttribtues, AuthorizationInfo auth) { @@ -101,7 +97,7 @@ namespace Emby.Server.Implementations.HttpServer.Security }; } - if (!user.Policy.EnableRemoteAccess && !NetworkManager.IsInLocalNetwork(request.RemoteIp)) + if (!user.Policy.EnableRemoteAccess && !_networkManager.IsInLocalNetwork(request.RemoteIp)) { throw new SecurityException("User account has been disabled.") { @@ -109,11 +105,11 @@ namespace Emby.Server.Implementations.HttpServer.Security }; } - if (!user.Policy.IsAdministrator && - !authAttribtues.EscapeParentalControl && - !user.IsParentalScheduleAllowed()) + if (!user.Policy.IsAdministrator + && !authAttribtues.EscapeParentalControl + && !user.IsParentalScheduleAllowed()) { - request.Response.AddHeader("X-Application-Error-Code", "ParentalControl"); + request.Response.Headers.Add("X-Application-Error-Code", "ParentalControl"); throw new SecurityException("This user account is not allowed access at this time.") { @@ -183,6 +179,7 @@ namespace Emby.Server.Implementations.HttpServer.Security }; } } + if (roles.Contains("delete", StringComparer.OrdinalIgnoreCase)) { if (user == null || !user.Policy.EnableContentDeletion) @@ -193,6 +190,7 @@ namespace Emby.Server.Implementations.HttpServer.Security }; } } + if (roles.Contains("download", StringComparer.OrdinalIgnoreCase)) { if (user == null || !user.Policy.EnableContentDownloading) diff --git a/Emby.Server.Implementations/Services/HttpResult.cs b/Emby.Server.Implementations/Services/HttpResult.cs index 2b5963a770..095193828b 100644 --- a/Emby.Server.Implementations/Services/HttpResult.cs +++ b/Emby.Server.Implementations/Services/HttpResult.cs @@ -10,8 +10,6 @@ namespace Emby.Server.Implementations.Services public class HttpResult : IHttpResult, IAsyncStreamWriter { - public object Response { get; set; } - public HttpResult(object response, string contentType, HttpStatusCode statusCode) { this.Headers = new Dictionary(); @@ -21,6 +19,8 @@ namespace Emby.Server.Implementations.Services this.StatusCode = statusCode; } + public object Response { get; set; } + public string ContentType { get; set; } public IDictionary Headers { get; private set; } @@ -37,7 +37,7 @@ namespace Emby.Server.Implementations.Services public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken) { - var response = RequestContext == null ? null : RequestContext.Response; + var response = RequestContext?.Response; if (this.Response is byte[] bytesResponse) { @@ -45,13 +45,14 @@ namespace Emby.Server.Implementations.Services if (response != null) { - response.OriginalResponse.ContentLength = contentLength; + response.ContentLength = contentLength; } if (contentLength > 0) { await responseStream.WriteAsync(bytesResponse, 0, contentLength, cancellationToken).ConfigureAwait(false); } + return; } diff --git a/Emby.Server.Implementations/Services/ResponseHelper.cs b/Emby.Server.Implementations/Services/ResponseHelper.cs index 251ba3529a..ca2b22fe06 100644 --- a/Emby.Server.Implementations/Services/ResponseHelper.cs +++ b/Emby.Server.Implementations/Services/ResponseHelper.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; @@ -7,13 +6,14 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.HttpServer; +using Microsoft.AspNetCore.Http; using MediaBrowser.Model.Services; namespace Emby.Server.Implementations.Services { public static class ResponseHelper { - public static Task WriteToResponse(IResponse response, IRequest request, object result, CancellationToken cancellationToken) + public static Task WriteToResponse(HttpResponse response, IRequest request, object result, CancellationToken cancellationToken) { if (result == null) { @@ -22,7 +22,7 @@ namespace Emby.Server.Implementations.Services response.StatusCode = (int)HttpStatusCode.NoContent; } - response.OriginalResponse.ContentLength = 0; + response.ContentLength = 0; return Task.CompletedTask; } @@ -41,7 +41,6 @@ namespace Emby.Server.Implementations.Services httpResult.RequestContext = request; response.StatusCode = httpResult.Status; - response.StatusDescription = httpResult.StatusCode.ToString(); } var responseOptions = result as IHasHeaders; @@ -51,11 +50,11 @@ namespace Emby.Server.Implementations.Services { if (string.Equals(responseHeaders.Key, "Content-Length", StringComparison.OrdinalIgnoreCase)) { - response.OriginalResponse.ContentLength = long.Parse(responseHeaders.Value, CultureInfo.InvariantCulture); + response.ContentLength = long.Parse(responseHeaders.Value, CultureInfo.InvariantCulture); continue; } - response.AddHeader(responseHeaders.Key, responseHeaders.Value); + response.Headers.Add(responseHeaders.Key, responseHeaders.Value); } } @@ -74,31 +73,31 @@ namespace Emby.Server.Implementations.Services switch (result) { case IAsyncStreamWriter asyncStreamWriter: - return asyncStreamWriter.WriteToAsync(response.OutputStream, cancellationToken); + return asyncStreamWriter.WriteToAsync(response.Body, cancellationToken); case IStreamWriter streamWriter: - streamWriter.WriteTo(response.OutputStream); + streamWriter.WriteTo(response.Body); return Task.CompletedTask; case FileWriter fileWriter: return fileWriter.WriteToAsync(response, cancellationToken); case Stream stream: - return CopyStream(stream, response.OutputStream); + return CopyStream(stream, response.Body); case byte[] bytes: response.ContentType = "application/octet-stream"; - response.OriginalResponse.ContentLength = bytes.Length; + response.ContentLength = bytes.Length; if (bytes.Length > 0) { - return response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken); + return response.Body.WriteAsync(bytes, 0, bytes.Length, cancellationToken); } return Task.CompletedTask; case string responseText: var responseTextAsBytes = Encoding.UTF8.GetBytes(responseText); - response.OriginalResponse.ContentLength = responseTextAsBytes.Length; + response.ContentLength = responseTextAsBytes.Length; if (responseTextAsBytes.Length > 0) { - return response.OutputStream.WriteAsync(responseTextAsBytes, 0, responseTextAsBytes.Length, cancellationToken); + return response.Body.WriteAsync(responseTextAsBytes, 0, responseTextAsBytes.Length, cancellationToken); } return Task.CompletedTask; @@ -115,7 +114,7 @@ namespace Emby.Server.Implementations.Services } } - public static async Task WriteObject(IRequest request, object result, IResponse response) + public static async Task WriteObject(IRequest request, object result, HttpResponse response) { var contentType = request.ResponseContentType; var serializer = RequestHelper.GetResponseWriter(HttpListenerHost.Instance, contentType); @@ -127,11 +126,11 @@ namespace Emby.Server.Implementations.Services ms.Position = 0; var contentLength = ms.Length; - response.OriginalResponse.ContentLength = contentLength; + response.ContentLength = contentLength; if (contentLength > 0) { - await ms.CopyToAsync(response.OutputStream).ConfigureAwait(false); + await ms.CopyToAsync(response.Body).ConfigureAwait(false); } } } diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index 5e3d529c68..d963f9043c 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -147,7 +147,6 @@ namespace Emby.Server.Implementations.Services public Task Execute(HttpListenerHost httpHost, object requestDto, IRequest req) { - req.Dto = requestDto; var requestType = requestDto.GetType(); req.OperationName = requestType.Name; @@ -161,9 +160,6 @@ namespace Emby.Server.Implementations.Services serviceRequiresContext.Request = req; } - if (req.Dto == null) // Don't override existing batched DTO[] - req.Dto = requestDto; - //Executes the service and returns the result return ServiceExecGeneral.Execute(serviceType, req, service, requestDto, requestType.GetMethodName()); } diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs index 38952628d8..9124b9c141 100644 --- a/Emby.Server.Implementations/Services/ServiceExec.cs +++ b/Emby.Server.Implementations/Services/ServiceExec.cs @@ -78,7 +78,7 @@ namespace Emby.Server.Implementations.Services foreach (var requestFilter in actionContext.RequestFilters) { requestFilter.RequestFilter(request, request.Response, requestDto); - if (request.Response.OriginalResponse.HasStarted) + if (request.Response.HasStarted) { Task.FromResult(null); } diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index d32fce1c77..cf15247bb3 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -5,20 +5,21 @@ using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.HttpServer; using MediaBrowser.Model.Services; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Services { public class ServiceHandler { - public RestPath RestPath { get; } + private RestPath _restPath; - public string ResponseContentType { get; } + private string _responseContentType; internal ServiceHandler(RestPath restPath, string responseContentType) { - RestPath = restPath; - ResponseContentType = responseContentType; + _restPath = restPath; + _responseContentType = responseContentType; } protected static Task CreateContentTypeRequest(HttpListenerHost host, IRequest httpReq, Type requestType, string contentType) @@ -54,7 +55,7 @@ namespace Emby.Server.Implementations.Services private static string GetFormatContentType(string format) { - //built-in formats + // built-in formats switch (format) { case "json": return "application/json"; @@ -63,16 +64,16 @@ namespace Emby.Server.Implementations.Services } } - public async Task ProcessRequestAsync(HttpListenerHost httpHost, IRequest httpReq, IResponse httpRes, ILogger logger, CancellationToken cancellationToken) + public async Task ProcessRequestAsync(HttpListenerHost httpHost, IRequest httpReq, HttpResponse httpRes, ILogger logger, CancellationToken cancellationToken) { - httpReq.Items["__route"] = RestPath; + httpReq.Items["__route"] = _restPath; - if (ResponseContentType != null) + if (_responseContentType != null) { - httpReq.ResponseContentType = ResponseContentType; + httpReq.ResponseContentType = _responseContentType; } - var request = httpReq.Dto = await CreateRequest(httpHost, httpReq, RestPath, logger).ConfigureAwait(false); + var request = await CreateRequest(httpHost, httpReq, _restPath, logger).ConfigureAwait(false); httpHost.ApplyRequestFilters(httpReq, httpRes, request); @@ -94,7 +95,7 @@ namespace Emby.Server.Implementations.Services if (RequireqRequestStream(requestType)) { // Used by IRequiresRequestStream - var requestParams = await GetRequestParams(httpReq).ConfigureAwait(false); + var requestParams = GetRequestParams(httpReq.Response.HttpContext.Request); var request = ServiceHandler.CreateRequest(httpReq, restPath, requestParams, host.CreateInstance(requestType)); var rawReq = (IRequiresRequestStream)request; @@ -103,7 +104,7 @@ namespace Emby.Server.Implementations.Services } else { - var requestParams = await GetFlattenedRequestParams(httpReq).ConfigureAwait(false); + var requestParams = GetFlattenedRequestParams(httpReq.Response.HttpContext.Request); var requestDto = await CreateContentTypeRequest(host, httpReq, restPath.RequestType, httpReq.ContentType).ConfigureAwait(false); @@ -130,56 +131,42 @@ namespace Emby.Server.Implementations.Services /// /// Duplicate Params are given a unique key by appending a #1 suffix /// - private static async Task> GetRequestParams(IRequest request) + private static Dictionary GetRequestParams(HttpRequest request) { var map = new Dictionary(); - foreach (var name in request.QueryString.Keys) + foreach (var pair in request.Query) { - if (name == null) - { - // thank you ASP.NET - continue; - } - - var values = request.QueryString[name]; + var values = pair.Value; if (values.Count == 1) { - map[name] = values[0]; + map[pair.Key] = values[0]; } else { for (var i = 0; i < values.Count; i++) { - map[name + (i == 0 ? "" : "#" + i)] = values[i]; + map[pair.Key + (i == 0 ? "" : "#" + i)] = values[i]; } } } - if ((IsMethod(request.Verb, "POST") || IsMethod(request.Verb, "PUT"))) + if ( + (IsMethod(request.Method, "POST") || IsMethod(request.Method, "PUT")) + && request.HasFormContentType) { - var formData = await request.GetFormData().ConfigureAwait(false); - if (formData != null) + foreach (var pair in request.Form) { - foreach (var name in formData.Keys) + var values = pair.Value; + if (values.Count == 1) { - if (name == null) - { - // thank you ASP.NET - continue; - } - - var values = formData.GetValues(name); - if (values.Count == 1) - { - map[name] = values[0]; - } - else + map[pair.Key] = values[0]; + } + else + { + for (var i = 0; i < values.Count; i++) { - for (var i = 0; i < values.Count; i++) - { - map[name + (i == 0 ? "" : "#" + i)] = values[i]; - } + map[pair.Key + (i == 0 ? "" : "#" + i)] = values[i]; } } } @@ -196,36 +183,22 @@ namespace Emby.Server.Implementations.Services /// /// Duplicate params have their values joined together in a comma-delimited string /// - private static async Task> GetFlattenedRequestParams(IRequest request) + private static Dictionary GetFlattenedRequestParams(HttpRequest request) { var map = new Dictionary(); - foreach (var name in request.QueryString.Keys) + foreach (var pair in request.Query) { - if (name == null) - { - // thank you ASP.NET - continue; - } - - map[name] = request.QueryString[name]; + map[pair.Key] = pair.Value; } - if ((IsMethod(request.Verb, "POST") || IsMethod(request.Verb, "PUT"))) + if ( + (IsMethod(request.Method, "POST") || IsMethod(request.Method, "PUT")) + && request.HasFormContentType) { - var formData = await request.GetFormData().ConfigureAwait(false); - if (formData != null) + foreach (var pair in request.Form) { - foreach (var name in formData.Keys) - { - if (name == null) - { - // thank you ASP.NET - continue; - } - - map[name] = formData[name]; - } + map[pair.Key] = pair.Value; } } diff --git a/Emby.Server.Implementations/SocketSharp/RequestMono.cs b/Emby.Server.Implementations/SocketSharp/RequestMono.cs deleted file mode 100644 index ec637186f0..0000000000 --- a/Emby.Server.Implementations/SocketSharp/RequestMono.cs +++ /dev/null @@ -1,647 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using MediaBrowser.Model.Services; -using Microsoft.Extensions.Primitives; -using Microsoft.Net.Http.Headers; - -namespace Emby.Server.Implementations.SocketSharp -{ - public partial class WebSocketSharpRequest : IHttpRequest - { - internal static string GetParameter(ReadOnlySpan header, string attr) - { - int ap = header.IndexOf(attr.AsSpan(), StringComparison.Ordinal); - if (ap == -1) - { - return null; - } - - ap += attr.Length; - if (ap >= header.Length) - { - return null; - } - - char ending = header[ap]; - if (ending != '"') - { - ending = ' '; - } - - var slice = header.Slice(ap + 1); - int end = slice.IndexOf(ending); - if (end == -1) - { - return ending == '"' ? null : header.Slice(ap).ToString(); - } - - return slice.Slice(0, end - ap - 1).ToString(); - } - - private async Task LoadMultiPart(WebROCollection form) - { - string boundary = GetParameter(ContentType.AsSpan(), "; boundary="); - if (boundary == null) - { - return; - } - - using (var requestStream = InputStream) - { - // DB: 30/01/11 - Hack to get around non-seekable stream and received HTTP request - // Not ending with \r\n? - var ms = new MemoryStream(32 * 1024); - await requestStream.CopyToAsync(ms).ConfigureAwait(false); - - var input = ms; - ms.WriteByte((byte)'\r'); - ms.WriteByte((byte)'\n'); - - input.Position = 0; - - // Uncomment to debug - // var content = new StreamReader(ms).ReadToEnd(); - // Console.WriteLine(boundary + "::" + content); - // input.Position = 0; - - var multi_part = new HttpMultipart(input, boundary, ContentEncoding); - - HttpMultipart.Element e; - while ((e = multi_part.ReadNextElement()) != null) - { - if (e.Filename == null) - { - byte[] copy = new byte[e.Length]; - - input.Position = e.Start; - await input.ReadAsync(copy, 0, (int)e.Length).ConfigureAwait(false); - - form.Add(e.Name, (e.Encoding ?? ContentEncoding).GetString(copy, 0, copy.Length)); - } - else - { - // We use a substream, as in 2.x we will support large uploads streamed to disk, - files[e.Name] = new HttpPostedFile(e.Filename, e.ContentType, input, e.Start, e.Length); - } - } - } - } - - public async Task GetFormData() - { - var form = new WebROCollection(); - files = new Dictionary(); - - if (IsContentType("multipart/form-data")) - { - await LoadMultiPart(form).ConfigureAwait(false); - } - else if (IsContentType("application/x-www-form-urlencoded")) - { - await LoadWwwForm(form).ConfigureAwait(false); - } - - if (validate_form && !checked_form) - { - checked_form = true; - ValidateNameValueCollection("Form", form); - } - - return form; - } - - public string Accept => StringValues.IsNullOrEmpty(request.Headers[HeaderNames.Accept]) ? null : request.Headers[HeaderNames.Accept].ToString(); - - public string Authorization => StringValues.IsNullOrEmpty(request.Headers[HeaderNames.Authorization]) ? null : request.Headers[HeaderNames.Authorization].ToString(); - - protected bool validate_form { get; set; } - protected bool checked_form { get; set; } - - private static void ThrowValidationException(string name, string key, string value) - { - string v = "\"" + value + "\""; - if (v.Length > 20) - { - v = v.Substring(0, 16) + "...\""; - } - - string msg = string.Format( - CultureInfo.InvariantCulture, - "A potentially dangerous Request.{0} value was detected from the client ({1}={2}).", - name, - key, - v); - - throw new Exception(msg); - } - - private static void ValidateNameValueCollection(string name, QueryParamCollection coll) - { - if (coll == null) - { - return; - } - - foreach (var pair in coll) - { - var key = pair.Name; - var val = pair.Value; - if (val != null && val.Length > 0 && IsInvalidString(val)) - { - ThrowValidationException(name, key, val); - } - } - } - - internal static bool IsInvalidString(string val) - => IsInvalidString(val, out var validationFailureIndex); - - internal static bool IsInvalidString(string val, out int validationFailureIndex) - { - validationFailureIndex = 0; - - int len = val.Length; - if (len < 2) - { - return false; - } - - char current = val[0]; - for (int idx = 1; idx < len; idx++) - { - char next = val[idx]; - - // See http://secunia.com/advisories/14325 - if (current == '<' || current == '\xff1c') - { - if (next == '!' || next < ' ' - || (next >= 'a' && next <= 'z') - || (next >= 'A' && next <= 'Z')) - { - validationFailureIndex = idx - 1; - return true; - } - } - else if (current == '&' && next == '#') - { - validationFailureIndex = idx - 1; - return true; - } - - current = next; - } - - return false; - } - - private bool IsContentType(string ct) - { - if (ContentType == null) - { - return false; - } - - return ContentType.StartsWith(ct, StringComparison.OrdinalIgnoreCase); - } - - private async Task LoadWwwForm(WebROCollection form) - { - using (var input = InputStream) - { - using (var ms = new MemoryStream()) - { - await input.CopyToAsync(ms).ConfigureAwait(false); - ms.Position = 0; - - using (var s = new StreamReader(ms, ContentEncoding)) - { - var key = new StringBuilder(); - var value = new StringBuilder(); - int c; - - while ((c = s.Read()) != -1) - { - if (c == '=') - { - value.Length = 0; - while ((c = s.Read()) != -1) - { - if (c == '&') - { - AddRawKeyValue(form, key, value); - break; - } - else - { - value.Append((char)c); - } - } - - if (c == -1) - { - AddRawKeyValue(form, key, value); - return; - } - } - else if (c == '&') - { - AddRawKeyValue(form, key, value); - } - else - { - key.Append((char)c); - } - } - - if (c == -1) - { - AddRawKeyValue(form, key, value); - } - } - } - } - } - - private static void AddRawKeyValue(WebROCollection form, StringBuilder key, StringBuilder value) - { - form.Add(WebUtility.UrlDecode(key.ToString()), WebUtility.UrlDecode(value.ToString())); - - key.Length = 0; - value.Length = 0; - } - - private Dictionary files; - - private class WebROCollection : QueryParamCollection - { - public override string ToString() - { - var result = new StringBuilder(); - foreach (var pair in this) - { - if (result.Length > 0) - { - result.Append('&'); - } - - var key = pair.Name; - if (key != null && key.Length > 0) - { - result.Append(key); - result.Append('='); - } - - result.Append(pair.Value); - } - - return result.ToString(); - } - } - private class HttpMultipart - { - - public class Element - { - public string ContentType { get; set; } - - public string Name { get; set; } - - public string Filename { get; set; } - - public Encoding Encoding { get; set; } - - public long Start { get; set; } - - public long Length { get; set; } - - public override string ToString() - { - return "ContentType " + ContentType + ", Name " + Name + ", Filename " + Filename + ", Start " + - Start.ToString(CultureInfo.CurrentCulture) + ", Length " + Length.ToString(CultureInfo.CurrentCulture); - } - } - - private const byte LF = (byte)'\n'; - - private const byte CR = (byte)'\r'; - - private Stream data; - - private string boundary; - - private byte[] boundaryBytes; - - private byte[] buffer; - - private bool atEof; - - private Encoding encoding; - - private StringBuilder sb; - - // See RFC 2046 - // In the case of multipart entities, in which one or more different - // sets of data are combined in a single body, a "multipart" media type - // field must appear in the entity's header. The body must then contain - // one or more body parts, each preceded by a boundary delimiter line, - // and the last one followed by a closing boundary delimiter line. - // After its boundary delimiter line, each body part then consists of a - // header area, a blank line, and a body area. Thus a body part is - // similar to an RFC 822 message in syntax, but different in meaning. - - public HttpMultipart(Stream data, string b, Encoding encoding) - { - this.data = data; - boundary = b; - boundaryBytes = encoding.GetBytes(b); - buffer = new byte[boundaryBytes.Length + 2]; // CRLF or '--' - this.encoding = encoding; - sb = new StringBuilder(); - } - - public Element ReadNextElement() - { - if (atEof || ReadBoundary()) - { - return null; - } - - var elem = new Element(); - ReadOnlySpan header; - while ((header = ReadLine().AsSpan()).Length != 0) - { - if (header.StartsWith("Content-Disposition:".AsSpan(), StringComparison.OrdinalIgnoreCase)) - { - elem.Name = GetContentDispositionAttribute(header, "name"); - elem.Filename = StripPath(GetContentDispositionAttributeWithEncoding(header, "filename")); - } - else if (header.StartsWith("Content-Type:".AsSpan(), StringComparison.OrdinalIgnoreCase)) - { - elem.ContentType = header.Slice("Content-Type:".Length).Trim().ToString(); - elem.Encoding = GetEncoding(elem.ContentType); - } - } - - long start = data.Position; - elem.Start = start; - long pos = MoveToNextBoundary(); - if (pos == -1) - { - return null; - } - - elem.Length = pos - start; - return elem; - } - - private string ReadLine() - { - // CRLF or LF are ok as line endings. - bool got_cr = false; - int b = 0; - sb.Length = 0; - while (true) - { - b = data.ReadByte(); - if (b == -1) - { - return null; - } - - if (b == LF) - { - break; - } - - got_cr = b == CR; - sb.Append((char)b); - } - - if (got_cr) - { - sb.Length--; - } - - return sb.ToString(); - } - - private static string GetContentDispositionAttribute(ReadOnlySpan l, string name) - { - int idx = l.IndexOf((name + "=\"").AsSpan(), StringComparison.Ordinal); - if (idx < 0) - { - return null; - } - - int begin = idx + name.Length + "=\"".Length; - int end = l.Slice(begin).IndexOf('"'); - if (end < 0) - { - return null; - } - - if (begin == end) - { - return string.Empty; - } - - return l.Slice(begin, end - begin).ToString(); - } - - private string GetContentDispositionAttributeWithEncoding(ReadOnlySpan l, string name) - { - int idx = l.IndexOf((name + "=\"").AsSpan(), StringComparison.Ordinal); - if (idx < 0) - { - return null; - } - - int begin = idx + name.Length + "=\"".Length; - int end = l.Slice(begin).IndexOf('"'); - if (end < 0) - { - return null; - } - - if (begin == end) - { - return string.Empty; - } - - ReadOnlySpan temp = l.Slice(begin, end - begin); - byte[] source = new byte[temp.Length]; - for (int i = temp.Length - 1; i >= 0; i--) - { - source[i] = (byte)temp[i]; - } - - return encoding.GetString(source, 0, source.Length); - } - - private bool ReadBoundary() - { - try - { - string line; - do - { - line = ReadLine(); - } - while (line.Length == 0); - - if (line[0] != '-' || line[1] != '-') - { - return false; - } - - if (!line.EndsWith(boundary, StringComparison.Ordinal)) - { - return true; - } - } - catch - { - - } - - return false; - } - - private static bool CompareBytes(byte[] orig, byte[] other) - { - for (int i = orig.Length - 1; i >= 0; i--) - { - if (orig[i] != other[i]) - { - return false; - } - } - - return true; - } - - private long MoveToNextBoundary() - { - long retval = 0; - bool got_cr = false; - - int state = 0; - int c = data.ReadByte(); - while (true) - { - if (c == -1) - { - return -1; - } - - if (state == 0 && c == LF) - { - retval = data.Position - 1; - if (got_cr) - { - retval--; - } - - state = 1; - c = data.ReadByte(); - } - else if (state == 0) - { - got_cr = c == CR; - c = data.ReadByte(); - } - else if (state == 1 && c == '-') - { - c = data.ReadByte(); - if (c == -1) - { - return -1; - } - - if (c != '-') - { - state = 0; - got_cr = false; - continue; // no ReadByte() here - } - - int nread = data.Read(buffer, 0, buffer.Length); - int bl = buffer.Length; - if (nread != bl) - { - return -1; - } - - if (!CompareBytes(boundaryBytes, buffer)) - { - state = 0; - data.Position = retval + 2; - if (got_cr) - { - data.Position++; - got_cr = false; - } - - c = data.ReadByte(); - continue; - } - - if (buffer[bl - 2] == '-' && buffer[bl - 1] == '-') - { - atEof = true; - } - else if (buffer[bl - 2] != CR || buffer[bl - 1] != LF) - { - state = 0; - data.Position = retval + 2; - if (got_cr) - { - data.Position++; - got_cr = false; - } - - c = data.ReadByte(); - continue; - } - - data.Position = retval + 2; - if (got_cr) - { - data.Position++; - } - - break; - } - else - { - // state == 1 - state = 0; // no ReadByte() here - } - } - - return retval; - } - - private static string StripPath(string path) - { - if (path == null || path.Length == 0) - { - return path; - } - - if (path.IndexOf(":\\", StringComparison.Ordinal) != 1 - && !path.StartsWith("\\\\", StringComparison.Ordinal)) - { - return path; - } - - return path.Substring(path.LastIndexOf('\\') + 1); - } - } - } -} diff --git a/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs b/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs index 7a630bf100..43f71a69c6 100644 --- a/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs +++ b/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs @@ -6,7 +6,6 @@ using System.Net; using System.Linq; using System.Text; using MediaBrowser.Common.Net; -using MediaBrowser.Model.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.Extensions.Logging; @@ -14,44 +13,49 @@ using Microsoft.Extensions.Primitives; using Microsoft.Net.Http.Headers; using IHttpFile = MediaBrowser.Model.Services.IHttpFile; using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest; -using IResponse = MediaBrowser.Model.Services.IResponse; namespace Emby.Server.Implementations.SocketSharp { public partial class WebSocketSharpRequest : IHttpRequest { - private readonly HttpRequest request; + public const string FormUrlEncoded = "application/x-www-form-urlencoded"; + public const string MultiPartFormData = "multipart/form-data"; + public const string Soap11 = "text/xml; charset=utf-8"; + + private string _remoteIp; + private Dictionary _items; + private string _responseContentType; + private IHttpFile[] _httpFiles; + private Dictionary _files; - public WebSocketSharpRequest(HttpRequest httpContext, HttpResponse response, string operationName, ILogger logger) + public WebSocketSharpRequest(HttpRequest httpRequest, HttpResponse httpResponse, string operationName, ILogger logger) { this.OperationName = operationName; - this.request = httpContext; - this.Response = new WebSocketSharpResponse(logger, response); + this.Request = httpRequest; + this.Response = httpResponse; } - public HttpRequest HttpRequest => request; + public string Accept => StringValues.IsNullOrEmpty(Request.Headers[HeaderNames.Accept]) ? null : Request.Headers[HeaderNames.Accept].ToString(); - public IResponse Response { get; } + public string Authorization => StringValues.IsNullOrEmpty(Request.Headers[HeaderNames.Authorization]) ? null : Request.Headers[HeaderNames.Authorization].ToString(); - public string OperationName { get; set; } + public HttpRequest Request { get; } - public object Dto { get; set; } + public HttpResponse Response { get; } - public string RawUrl => request.GetEncodedPathAndQuery(); + public string OperationName { get; set; } - public string AbsoluteUri => request.GetDisplayUrl().TrimEnd('/'); - // Header[name] returns "" when undefined + public string RawUrl => Request.GetEncodedPathAndQuery(); - private string GetHeader(string name) => request.Headers[name].ToString(); + public string AbsoluteUri => Request.GetDisplayUrl().TrimEnd('/'); - private string remoteIp; public string RemoteIp { get { - if (remoteIp != null) + if (_remoteIp != null) { - return remoteIp; + return _remoteIp; } IPAddress ip; @@ -62,14 +66,84 @@ namespace Emby.Server.Implementations.SocketSharp { if (!IPAddress.TryParse(GetHeader(CustomHeaderNames.XRealIP), out ip)) { - ip = request.HttpContext.Connection.RemoteIpAddress; + ip = Request.HttpContext.Connection.RemoteIpAddress; } } - return remoteIp = NormalizeIp(ip).ToString(); + return _remoteIp = NormalizeIp(ip).ToString(); } } + public string[] AcceptTypes => Request.Headers.GetCommaSeparatedValues(HeaderNames.Accept); + + public Dictionary Items => _items ?? (_items = new Dictionary()); + + public string ResponseContentType + { + get => + _responseContentType + ?? (_responseContentType = GetResponseContentType(Request)); + set => this._responseContentType = value; + } + + public string PathInfo => Request.Path.Value; + + public string UserAgent => Request.Headers[HeaderNames.UserAgent]; + + public IHeaderDictionary Headers => Request.Headers; + + public IQueryCollection QueryString => Request.Query; + + public bool IsLocal => Request.HttpContext.Connection.LocalIpAddress.Equals(Request.HttpContext.Connection.RemoteIpAddress); + + + public string HttpMethod => Request.Method; + + public string Verb => HttpMethod; + + public string ContentType => Request.ContentType; + + public Uri UrlReferrer => Request.GetTypedHeaders().Referer; + + public Stream InputStream => Request.Body; + + public long ContentLength => Request.ContentLength ?? 0; + + + public IHttpFile[] Files + { + get + { + if (_httpFiles != null) + { + return _httpFiles; + } + + if (_files == null) + { + return _httpFiles = Array.Empty(); + } + + var values = _files.Values; + _httpFiles = new IHttpFile[values.Count]; + for (int i = 0; i < values.Count; i++) + { + var reqFile = values.ElementAt(i); + _httpFiles[i] = new HttpFile + { + ContentType = reqFile.ContentType, + ContentLength = reqFile.ContentLength, + FileName = reqFile.FileName, + InputStream = reqFile.InputStream, + }; + } + + return _httpFiles; + } + } + + private string GetHeader(string name) => Request.Headers[name].ToString(); + private static IPAddress NormalizeIp(IPAddress ip) { if (ip.IsIPv4MappedToIPv6) @@ -80,22 +154,6 @@ namespace Emby.Server.Implementations.SocketSharp return ip; } - public string[] AcceptTypes => request.Headers.GetCommaSeparatedValues(HeaderNames.Accept); - - private Dictionary items; - public Dictionary Items => items ?? (items = new Dictionary()); - - private string responseContentType; - public string ResponseContentType - { - get => - responseContentType - ?? (responseContentType = GetResponseContentType(HttpRequest)); - set => this.responseContentType = value; - } - - public const string FormUrlEncoded = "application/x-www-form-urlencoded"; - public const string MultiPartFormData = "multipart/form-data"; public static string GetResponseContentType(HttpRequest httpReq) { var specifiedContentType = GetQueryStringContentType(httpReq); @@ -152,8 +210,6 @@ namespace Emby.Server.Implementations.SocketSharp return serverDefaultContentType; } - public const string Soap11 = "text/xml; charset=utf-8"; - public static bool HasAnyOfContentTypes(HttpRequest request, params string[] contentTypes) { if (contentTypes == null || request.ContentType == null) @@ -224,105 +280,5 @@ namespace Emby.Server.Implementations.SocketSharp var pos = strVal.IndexOf(needle); return pos == -1 ? strVal : strVal.Slice(0, pos); } - - public string PathInfo => this.request.Path.Value; - - public string UserAgent => request.Headers[HeaderNames.UserAgent]; - - public IHeaderDictionary Headers => request.Headers; - - public IQueryCollection QueryString => request.Query; - - public bool IsLocal => string.Equals(request.HttpContext.Connection.LocalIpAddress.ToString(), request.HttpContext.Connection.RemoteIpAddress.ToString()); - - private string httpMethod; - public string HttpMethod => - httpMethod - ?? (httpMethod = request.Method); - - public string Verb => HttpMethod; - - public string ContentType => request.ContentType; - - private Encoding ContentEncoding - { - get - { - // TODO is this necessary? - if (UserAgent != null && CultureInfo.InvariantCulture.CompareInfo.IsPrefix(UserAgent, "UP")) - { - string postDataCharset = Headers["x-up-devcap-post-charset"]; - if (!string.IsNullOrEmpty(postDataCharset)) - { - try - { - return Encoding.GetEncoding(postDataCharset); - } - catch (ArgumentException) - { - } - } - } - - return request.GetTypedHeaders().ContentType.Encoding ?? Encoding.UTF8; - } - } - - public Uri UrlReferrer => request.GetTypedHeaders().Referer; - - public static Encoding GetEncoding(string contentTypeHeader) - { - var param = GetParameter(contentTypeHeader.AsSpan(), "charset="); - if (param == null) - { - return null; - } - - try - { - return Encoding.GetEncoding(param); - } - catch (ArgumentException) - { - return null; - } - } - - public Stream InputStream => request.Body; - - public long ContentLength => request.ContentLength ?? 0; - - private IHttpFile[] httpFiles; - public IHttpFile[] Files - { - get - { - if (httpFiles != null) - { - return httpFiles; - } - - if (files == null) - { - return httpFiles = Array.Empty(); - } - - var values = files.Values; - httpFiles = new IHttpFile[values.Count]; - for (int i = 0; i < values.Count; i++) - { - var reqFile = values.ElementAt(i); - httpFiles[i] = new HttpFile - { - ContentType = reqFile.ContentType, - ContentLength = reqFile.ContentLength, - FileName = reqFile.FileName, - InputStream = reqFile.InputStream, - }; - } - - return httpFiles; - } - } } } diff --git a/Emby.Server.Implementations/SocketSharp/WebSocketSharpResponse.cs b/Emby.Server.Implementations/SocketSharp/WebSocketSharpResponse.cs deleted file mode 100644 index 0f67eaa622..0000000000 --- a/Emby.Server.Implementations/SocketSharp/WebSocketSharpResponse.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Services; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Logging; -using IRequest = MediaBrowser.Model.Services.IRequest; - -namespace Emby.Server.Implementations.SocketSharp -{ - public class WebSocketSharpResponse : IResponse - { - private readonly ILogger _logger; - - public WebSocketSharpResponse(ILogger logger, HttpResponse response) - { - _logger = logger; - OriginalResponse = response; - } - - public HttpResponse OriginalResponse { get; } - - public int StatusCode - { - get => OriginalResponse.StatusCode; - set => OriginalResponse.StatusCode = value; - } - - public string StatusDescription { get; set; } - - public string ContentType - { - get => OriginalResponse.ContentType; - set => OriginalResponse.ContentType = value; - } - - public void AddHeader(string name, string value) - { - if (string.Equals(name, "Content-Type", StringComparison.OrdinalIgnoreCase)) - { - ContentType = value; - return; - } - - OriginalResponse.Headers.Add(name, value); - } - - public void Redirect(string url) - { - OriginalResponse.Redirect(url); - } - - public Stream OutputStream => OriginalResponse.Body; - - public bool SendChunked { get; set; } - - const int StreamCopyToBufferSize = 81920; - public async Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, IFileSystem fileSystem, IStreamHelper streamHelper, CancellationToken cancellationToken) - { - var allowAsync = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - - //if (count <= 0) - //{ - // allowAsync = true; - //} - - var fileOpenOptions = FileOpenOptions.SequentialScan; - - if (allowAsync) - { - fileOpenOptions |= FileOpenOptions.Asynchronous; - } - - // use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039 - - using (var fs = fileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, fileShareMode, fileOpenOptions)) - { - if (offset > 0) - { - fs.Position = offset; - } - - if (count > 0) - { - await streamHelper.CopyToAsync(fs, OutputStream, count, cancellationToken).ConfigureAwait(false); - } - else - { - await fs.CopyToAsync(OutputStream, StreamCopyToBufferSize, cancellationToken).ConfigureAwait(false); - } - } - } - } -} diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 3994016240..f0d5147a88 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1019,7 +1019,7 @@ namespace MediaBrowser.Api.Playback foreach (var item in responseHeaders) { - Request.Response.AddHeader(item.Key, item.Value); + Request.Response.Headers.Add(item.Key, item.Value); } } diff --git a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs index 64c2294e3d..29fb81e32a 100644 --- a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs +++ b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs @@ -1,5 +1,6 @@ using System; using MediaBrowser.Model.Services; +using Microsoft.AspNetCore.Http; namespace MediaBrowser.Controller.Net { @@ -33,7 +34,7 @@ namespace MediaBrowser.Controller.Net /// The http request wrapper /// The http response wrapper /// The request DTO - public void RequestFilter(IRequest request, IResponse response, object requestDto) + public void RequestFilter(IRequest request, HttpResponse response, object requestDto) { AuthService.Authenticate(request, this); } diff --git a/MediaBrowser.Model/Services/IHasRequestFilter.cs b/MediaBrowser.Model/Services/IHasRequestFilter.cs index d4e6aa8e00..81a2dba692 100644 --- a/MediaBrowser.Model/Services/IHasRequestFilter.cs +++ b/MediaBrowser.Model/Services/IHasRequestFilter.cs @@ -1,3 +1,5 @@ +using Microsoft.AspNetCore.Http; + namespace MediaBrowser.Model.Services { public interface IHasRequestFilter @@ -15,6 +17,6 @@ namespace MediaBrowser.Model.Services /// The http request wrapper /// The http response wrapper /// The request DTO - void RequestFilter(IRequest req, IResponse res, object requestDto); + void RequestFilter(IRequest req, HttpResponse res, object requestDto); } } diff --git a/MediaBrowser.Model/Services/IRequest.cs b/MediaBrowser.Model/Services/IRequest.cs index 4f6ddb476e..3852b1dd74 100644 --- a/MediaBrowser.Model/Services/IRequest.cs +++ b/MediaBrowser.Model/Services/IRequest.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Model.Services { public interface IRequest { - IResponse Response { get; } + HttpResponse Response { get; } /// /// The name of the service being called (e.g. Request DTO Name) @@ -22,11 +22,6 @@ namespace MediaBrowser.Model.Services /// string Verb { get; } - /// - /// The Request DTO, after it has been deserialized. - /// - object Dto { get; set; } - /// /// The request ContentType /// @@ -50,8 +45,6 @@ namespace MediaBrowser.Model.Services IQueryCollection QueryString { get; } - Task GetFormData(); - string RawUrl { get; } string AbsoluteUri { get; } @@ -98,25 +91,4 @@ namespace MediaBrowser.Model.Services { IRequest Request { get; set; } } - - public interface IResponse - { - HttpResponse OriginalResponse { get; } - - int StatusCode { get; set; } - - string StatusDescription { get; set; } - - string ContentType { get; set; } - - void AddHeader(string name, string value); - - void Redirect(string url); - - Stream OutputStream { get; } - - Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, IFileSystem fileSystem, IStreamHelper streamHelper, CancellationToken cancellationToken); - - bool SendChunked { get; set; } - } } -- cgit v1.2.3 From 2a58c643d24354ad8b6c45451bcedf82caa344c0 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 9 Aug 2019 23:16:24 +0200 Subject: Fix more warnings --- Emby.Server.Implementations/ApplicationHost.cs | 45 +++++++++++----------- Emby.Server.Implementations/Devices/DeviceId.cs | 1 - .../LiveTv/TunerHosts/M3uParser.cs | 1 + .../Networking/NetworkManager.cs | 38 +++++------------- Jellyfin.Server/Program.cs | 11 +++--- MediaBrowser.Common/Net/INetworkManager.cs | 4 +- MediaBrowser.Controller/IServerApplicationHost.cs | 2 +- MediaBrowser.Model/System/WakeOnLanInfo.cs | 37 ++++++++++++++++++ 8 files changed, 77 insertions(+), 62 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index ef2f59d303..f0aa60428b 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -108,9 +108,9 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Logging; using ServiceStack; using OperatingSystem = MediaBrowser.Common.System.OperatingSystem; @@ -386,7 +386,7 @@ namespace Emby.Server.Implementations fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); - NetworkManager.NetworkChanged += NetworkManager_NetworkChanged; + NetworkManager.NetworkChanged += OnNetworkChanged; } public string ExpandVirtualPath(string path) @@ -410,7 +410,7 @@ namespace Emby.Server.Implementations return ServerConfigurationManager.Configuration.LocalNetworkSubnets; } - private void NetworkManager_NetworkChanged(object sender, EventArgs e) + private void OnNetworkChanged(object sender, EventArgs e) { _validAddressResults.Clear(); } @@ -421,7 +421,7 @@ namespace Emby.Server.Implementations /// Gets the current application user agent /// /// The application user agent. - public string ApplicationUserAgent => Name.Replace(' ','-') + '/' + ApplicationVersion; + public string ApplicationUserAgent => Name.Replace(' ', '-') + "/" + ApplicationVersion; /// /// Gets the email address for use within a comment section of a user agent field. @@ -429,14 +429,11 @@ namespace Emby.Server.Implementations /// public string ApplicationUserAgentAddress { get; } = "team@jellyfin.org"; - private string _productName; - /// - /// Gets the current application name + /// Gets the current application name. /// /// The application name. - public string ApplicationProductName - => _productName ?? (_productName = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductName); + public string ApplicationProductName { get; } = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductName; private DeviceId _deviceId; @@ -604,10 +601,15 @@ namespace Emby.Server.Implementations foreach (var plugin in Plugins) { - pluginBuilder.AppendLine(string.Format("{0} {1}", plugin.Name, plugin.Version)); + pluginBuilder.AppendLine( + string.Format( + CultureInfo.InvariantCulture, + "{0} {1}", + plugin.Name, + plugin.Version)); } - Logger.LogInformation("Plugins: {plugins}", pluginBuilder.ToString()); + Logger.LogInformation("Plugins: {Plugins}", pluginBuilder.ToString()); } DiscoverTypes(); @@ -629,7 +631,7 @@ namespace Emby.Server.Implementations if (EnableHttps && Certificate != null) { - options.ListenAnyIP(HttpsPort, listenOptions => { listenOptions.UseHttps(Certificate); }); + options.ListenAnyIP(HttpsPort, listenOptions => listenOptions.UseHttps(Certificate)); } }) .UseContentRoot(contentRoot) @@ -643,6 +645,7 @@ namespace Emby.Server.Implementations app.UseWebSockets(); app.UseResponseCompression(); + // TODO app.UseMiddleware(); app.Use(ExecuteWebsocketHandlerAsync); app.Use(ExecuteHttpHandlerAsync); @@ -1044,8 +1047,8 @@ namespace Emby.Server.Implementations .Cast() .ToList(); - await Task.WhenAll(StartEntryPoints(entries, true)); - await Task.WhenAll(StartEntryPoints(entries, false)); + await Task.WhenAll(StartEntryPoints(entries, true)).ConfigureAwait(false); + await Task.WhenAll(StartEntryPoints(entries, false)).ConfigureAwait(false); } /// @@ -1458,15 +1461,10 @@ namespace Emby.Server.Implementations }; } - public WakeOnLanInfo[] GetWakeOnLanInfo() - { - return NetworkManager.GetMacAddresses() - .Select(i => new WakeOnLanInfo - { - MacAddress = i - }) - .ToArray(); - } + public IEnumerable GetWakeOnLanInfo() + => NetworkManager.GetMacAddresses() + .Select(i => new WakeOnLanInfo(i)) + .ToList(); public async Task GetPublicSystemInfo(CancellationToken cancellationToken) { @@ -1482,6 +1480,7 @@ namespace Emby.Server.Implementations { wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); } + return new PublicSystemInfo { Version = ApplicationVersion, diff --git a/Emby.Server.Implementations/Devices/DeviceId.cs b/Emby.Server.Implementations/Devices/DeviceId.cs index 495c3436ab..a470fc482c 100644 --- a/Emby.Server.Implementations/Devices/DeviceId.cs +++ b/Emby.Server.Implementations/Devices/DeviceId.cs @@ -2,7 +2,6 @@ using System; using System.IO; using System.Text; using MediaBrowser.Common.Configuration; -using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Devices diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 814031b126..a632db3eb4 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -58,6 +58,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts UserAgent = _appHost.ApplicationUserAgent }); } + return Task.FromResult((Stream)File.OpenRead(url)); } diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index f613dc2958..7d85a0666a 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -425,47 +425,27 @@ namespace Emby.Server.Implementations.Networking var localEndPoint = new IPEndPoint(IPAddress.Any, 0); using (var udpClient = new UdpClient(localEndPoint)) { - var port = ((IPEndPoint)(udpClient.Client.LocalEndPoint)).Port; + var port = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; return port; } } - private List _macAddresses; - public List GetMacAddresses() + private List _macAddresses; + public List GetMacAddresses() { if (_macAddresses == null) { - _macAddresses = GetMacAddressesInternal(); + _macAddresses = GetMacAddressesInternal().ToList(); } + return _macAddresses; } - private static List GetMacAddressesInternal() - { - return NetworkInterface.GetAllNetworkInterfaces() + private static IEnumerable GetMacAddressesInternal() + => NetworkInterface.GetAllNetworkInterfaces() .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback) - .Select(i => - { - try - { - var physicalAddress = i.GetPhysicalAddress(); - - if (physicalAddress == null) - { - return null; - } - - return physicalAddress.ToString(); - } - catch (Exception) - { - //TODO Log exception. - return null; - } - }) - .Where(i => i != null) - .ToList(); - } + .Select(x => x.GetPhysicalAddress()) + .Where(x => x != null && x != PhysicalAddress.None); /// /// Parses the specified endpointstring. diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 08c0983bef..9529904930 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -18,7 +18,6 @@ using Jellyfin.Drawing.Skia; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.Globalization; -using MediaBrowser.Model.IO; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -41,12 +40,12 @@ namespace Jellyfin.Server // For backwards compatibility. // Modify any input arguments now which start with single-hyphen to POSIX standard // double-hyphen to allow parsing by CommandLineParser package. - const string pattern = @"^(-[^-\s]{2})"; // Match -xx, not -x, not --xx, not xx - const string substitution = @"-$1"; // Prepend with additional single-hyphen - var regex = new Regex(pattern); + const string Pattern = @"^(-[^-\s]{2})"; // Match -xx, not -x, not --xx, not xx + const string Substitution = @"-$1"; // Prepend with additional single-hyphen + var regex = new Regex(Pattern); for (var i = 0; i < args.Length; i++) { - args[i] = regex.Replace(args[i], substitution); + args[i] = regex.Replace(args[i], Substitution); } // Parse the command line arguments and either start the app or exit indicating error @@ -134,7 +133,7 @@ namespace Jellyfin.Server Batteries_V2.Init(); if (raw.sqlite3_enable_shared_cache(1) != raw.SQLITE_OK) { - Console.WriteLine("WARN: Failed to enable shared cache for SQLite"); + _logger.LogWarning("Failed to enable shared cache for SQLite"); } using (var appHost = new CoreAppHost( diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 61f2bc2f9f..1df74d9955 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Net; -using System.Threading.Tasks; +using System.Net.NetworkInformation; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; @@ -25,7 +25,7 @@ namespace MediaBrowser.Common.Net /// Returns MAC Address from first Network Card in Computer /// /// [string] MAC Address - List GetMacAddresses(); + List GetMacAddresses(); /// /// Determines whether [is in private address space] [the specified endpoint]. diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 3f8cc0b83f..61b2c15ae2 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -83,7 +83,7 @@ namespace MediaBrowser.Controller void EnableLoopback(string appName); - WakeOnLanInfo[] GetWakeOnLanInfo(); + IEnumerable GetWakeOnLanInfo(); string ExpandVirtualPath(string path); string ReverseVirtualPath(string path); diff --git a/MediaBrowser.Model/System/WakeOnLanInfo.cs b/MediaBrowser.Model/System/WakeOnLanInfo.cs index 031458735e..534ad19ecc 100644 --- a/MediaBrowser.Model/System/WakeOnLanInfo.cs +++ b/MediaBrowser.Model/System/WakeOnLanInfo.cs @@ -1,10 +1,47 @@ +using System.Net.NetworkInformation; + namespace MediaBrowser.Model.System { + /// + /// Provides the MAC address and port for wake-on-LAN functionality. + /// public class WakeOnLanInfo { + /// + /// Returns the MAC address of the device. + /// + /// The MAC address. public string MacAddress { get; set; } + + /// + /// Returns the wake-on-LAN port. + /// + /// The wake-on-LAN port. public int Port { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The MAC address. + public WakeOnLanInfo(PhysicalAddress macAddress) + { + MacAddress = macAddress.ToString(); + Port = 9; + } + + /// + /// Initializes a new instance of the class. + /// + /// The MAC address. + public WakeOnLanInfo(string macAddress) + { + MacAddress = macAddress; + Port = 9; + } + + /// + /// Initializes a new instance of the class. + /// public WakeOnLanInfo() { Port = 9; -- cgit v1.2.3 From 6032f31aa660e3b0fe1936217109f9fb47853ba3 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Thu, 28 Feb 2019 23:22:57 +0100 Subject: Use CultureInvariant string conversion for Guids --- Emby.Dlna/Didl/DidlBuilder.cs | 4 ++-- Emby.Dlna/DlnaManager.cs | 5 ++-- Emby.Dlna/Eventing/EventManager.cs | 2 +- Emby.Dlna/Main/DlnaEntryPoint.cs | 3 ++- Emby.Dlna/PlayTo/PlayToManager.cs | 5 ++-- Emby.Drawing/ImageProcessor.cs | 6 ++--- Emby.Notifications/NotificationManager.cs | 5 ++-- .../Activity/ActivityLogEntryPoint.cs | 4 ++-- .../Activity/ActivityRepository.cs | 4 ++-- Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Channels/ChannelManager.cs | 17 +++++++------- .../Collections/CollectionManager.cs | 3 ++- .../Data/SqliteDisplayPreferencesRepository.cs | 3 ++- .../Data/SqliteItemRepository.cs | 19 +++++++-------- Emby.Server.Implementations/Devices/DeviceId.cs | 4 ++-- .../Devices/DeviceManager.cs | 4 ++-- Emby.Server.Implementations/Dto/DtoService.cs | 17 +++++++------- .../EntryPoints/LibraryChangedNotifier.cs | 16 ++++++------- .../EntryPoints/ServerEventNotifier.cs | 3 ++- .../EntryPoints/UserDataChangeNotifier.cs | 6 ++--- .../HttpClientManager/HttpClientManager.cs | 2 +- .../IO/ManagedFileSystem.cs | 3 ++- .../Images/BaseDynamicImageProvider.cs | 3 ++- .../Library/ExclusiveLiveStream.cs | 3 ++- .../Library/LibraryManager.cs | 14 +++++------ .../Library/LiveStreamHelper.cs | 2 +- .../Library/MediaSourceManager.cs | 6 ++--- .../Library/UserDataManager.cs | 2 +- .../Library/UserViewManager.cs | 9 ++++---- .../Library/Validators/ArtistsValidator.cs | 3 ++- .../Library/Validators/PeopleValidator.cs | 4 ++-- .../Library/Validators/StudiosValidator.cs | 3 ++- .../LiveTv/EmbyTV/EmbyTV.cs | 8 +++---- .../LiveTv/Listings/XmlTvListingsProvider.cs | 4 ++-- .../LiveTv/LiveTvDtoService.cs | 27 +++++++++++----------- .../LiveTv/LiveTvManager.cs | 23 +++++++++--------- .../LiveTv/LiveTvMediaSourceProvider.cs | 3 ++- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 3 ++- .../LiveTv/TunerHosts/LiveStream.cs | 3 ++- .../LiveTv/TunerHosts/M3UTunerHost.cs | 7 +++--- .../LiveTv/TunerHosts/M3uParser.cs | 4 ++-- .../Playlists/PlaylistManager.cs | 7 +++--- .../ScheduledTasks/ScheduledTaskWorker.cs | 4 ++-- .../Security/AuthenticationRepository.cs | 2 +- .../Serialization/JsonSerializer.cs | 3 ++- .../Session/HttpSessionController.cs | 2 +- .../Session/SessionManager.cs | 14 ++++++----- Emby.Server.Implementations/TV/TVSeriesManager.cs | 3 ++- MediaBrowser.Api/Images/ImageService.cs | 3 ++- .../Library/LibraryStructureService.cs | 3 ++- MediaBrowser.Api/Movies/MoviesService.cs | 6 ++--- MediaBrowser.Api/Playback/BaseStreamingService.cs | 8 ++++++- MediaBrowser.Api/Playback/MediaInfoService.cs | 3 ++- MediaBrowser.Api/SearchService.cs | 5 ++-- MediaBrowser.Api/Session/SessionsService.cs | 3 ++- MediaBrowser.Api/Subtitles/SubtitleService.cs | 4 ++-- MediaBrowser.Api/TvShowsService.cs | 3 ++- MediaBrowser.Api/UserLibrary/ItemsService.cs | 2 +- MediaBrowser.Api/UserLibrary/UserViewsService.cs | 3 ++- MediaBrowser.Api/VideosService.cs | 3 ++- MediaBrowser.Controller/Channels/Channel.cs | 7 +++--- MediaBrowser.Controller/Entities/BaseItem.cs | 14 +++++------ MediaBrowser.Controller/Entities/Folder.cs | 5 ++-- MediaBrowser.Controller/Entities/LinkedChild.cs | 5 ++-- MediaBrowser.Controller/Entities/TV/Series.cs | 3 ++- MediaBrowser.Controller/Entities/User.cs | 3 ++- .../Entities/UserViewBuilder.cs | 3 ++- MediaBrowser.Controller/LiveTv/LiveTvChannel.cs | 4 ++-- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 3 ++- MediaBrowser.Controller/Playlists/Playlist.cs | 3 ++- .../Providers/MetadataResult.cs | 3 ++- MediaBrowser.Providers/Manager/ProviderManager.cs | 8 +++---- .../MediaInfo/AudioImageProvider.cs | 7 +++--- .../Subtitles/SubtitleManager.cs | 5 ++-- jellyfin.ruleset | 4 ++++ 75 files changed, 240 insertions(+), 186 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index a21aff9f91..26adfde839 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -1082,7 +1082,7 @@ namespace Emby.Dlna.Didl public static string GetClientId(Guid idValue, StubType? stubType) { - var id = idValue.ToString("N"); + var id = idValue.ToString("N", CultureInfo.InvariantCulture); if (stubType.HasValue) { @@ -1096,7 +1096,7 @@ namespace Emby.Dlna.Didl { var url = string.Format("{0}/Items/{1}/Images/{2}/0/{3}/{4}/{5}/{6}/0/0", _serverAddress, - info.ItemId.ToString("N"), + info.ItemId.ToString("N", CultureInfo.InvariantCulture), info.Type, info.ImageTag, format, diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index 2b76d27025..d5d788021d 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Reflection; @@ -300,7 +301,7 @@ namespace Emby.Dlna profile = ReserializeProfile(tempProfile); - profile.Id = path.ToLowerInvariant().GetMD5().ToString("N"); + profile.Id = path.ToLowerInvariant().GetMD5().ToString("N", CultureInfo.InvariantCulture); _profiles[path] = new Tuple(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile); @@ -352,7 +353,7 @@ namespace Emby.Dlna Info = new DeviceProfileInfo { - Id = file.FullName.ToLowerInvariant().GetMD5().ToString("N"), + Id = file.FullName.ToLowerInvariant().GetMD5().ToString("N", CultureInfo.InvariantCulture), Name = _fileSystem.GetFileNameWithoutExtension(file), Type = type } diff --git a/Emby.Dlna/Eventing/EventManager.cs b/Emby.Dlna/Eventing/EventManager.cs index b4ff3ec1d5..4b542a820c 100644 --- a/Emby.Dlna/Eventing/EventManager.cs +++ b/Emby.Dlna/Eventing/EventManager.cs @@ -55,7 +55,7 @@ namespace Emby.Dlna.Eventing public EventSubscriptionResponse CreateEventSubscription(string notificationType, string requestedTimeoutString, string callbackUrl) { var timeout = ParseTimeout(requestedTimeoutString) ?? 300; - var id = "uuid:" + Guid.NewGuid().ToString("N"); + var id = "uuid:" + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); // Remove logging for now because some devices are sending this very frequently // TODO re-enable with dlna debug logging setting diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 206a873e1d..77bde0ca24 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -1,5 +1,6 @@ using System; using System.Net.Sockets; +using System.Globalization; using System.Threading; using System.Threading.Tasks; using Emby.Dlna.PlayTo; @@ -307,7 +308,7 @@ namespace Emby.Dlna.Main { guid = text.GetMD5(); } - return guid.ToString("N"); + return guid.ToString("N", CultureInfo.InvariantCulture); } private void SetProperies(SsdpDevice device, string fullDeviceType) diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index c0a4418711..a3a013096c 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using System.Net; using System.Threading; @@ -141,7 +142,7 @@ namespace Emby.Dlna.PlayTo return usn; } - return usn.GetMD5().ToString("N"); + return usn.GetMD5().ToString("N", CultureInfo.InvariantCulture); } private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken) @@ -156,7 +157,7 @@ namespace Emby.Dlna.PlayTo } else { - uuid = location.GetMD5().ToString("N"); + uuid = location.GetMD5().ToString("N", CultureInfo.InvariantCulture); } var sessionInfo = _sessionManager.LogSessionActivity("DLNA", _appHost.ApplicationVersion, uuid, null, uri.OriginalString, null); diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 6d209d8d01..a7d95eb209 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -454,14 +454,14 @@ namespace Emby.Drawing // Optimization if (imageEnhancers.Length == 0) { - return (originalImagePath + dateModified.Ticks).GetMD5().ToString("N"); + return (originalImagePath + dateModified.Ticks).GetMD5().ToString("N", CultureInfo.InvariantCulture); } // Cache name is created with supported enhancers combined with the last config change so we pick up new config changes var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList(); cacheKeys.Add(originalImagePath + dateModified.Ticks); - return string.Join("|", cacheKeys).GetMD5().ToString("N"); + return string.Join("|", cacheKeys).GetMD5().ToString("N", CultureInfo.InvariantCulture); } private async Task<(string path, DateTime dateModified)> GetSupportedImage(string originalImagePath, DateTime dateModified) @@ -480,7 +480,7 @@ namespace Emby.Drawing { try { - string filename = (originalImagePath + dateModified.Ticks.ToString(UsCulture)).GetMD5().ToString("N"); + string filename = (originalImagePath + dateModified.Ticks.ToString(UsCulture)).GetMD5().ToString("N", CultureInfo.InvariantCulture); string cacheExtension = _mediaEncoder().SupportsEncoder("libwebp") ? ".webp" : ".png"; var outputPath = Path.Combine(_appPaths.ImageCachePath, "converted-images", filename + cacheExtension); diff --git a/Emby.Notifications/NotificationManager.cs b/Emby.Notifications/NotificationManager.cs index 3d1d4722dd..a767e541e1 100644 --- a/Emby.Notifications/NotificationManager.cs +++ b/Emby.Notifications/NotificationManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -101,7 +102,7 @@ namespace Emby.Notifications var config = GetConfiguration(); return _userManager.Users - .Where(i => config.IsEnabledToSendToUser(request.NotificationType, i.Id.ToString("N"), i.Policy)) + .Where(i => config.IsEnabledToSendToUser(request.NotificationType, i.Id.ToString("N", CultureInfo.InvariantCulture), i.Policy)) .Select(i => i.Id); } @@ -197,7 +198,7 @@ namespace Emby.Notifications return _services.Select(i => new NameIdPair { Name = i.Name, - Id = i.Name.GetMD5().ToString("N") + Id = i.Name.GetMD5().ToString("N", CultureInfo.InvariantCulture) }).OrderBy(i => i.Name); } diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs index 0530a251cc..3e44c9c0a2 100644 --- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs +++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -75,7 +76,6 @@ namespace Emby.Server.Implementations.Activity _sessionManager.AuthenticationFailed += OnAuthenticationFailed; _sessionManager.AuthenticationSucceeded += OnAuthenticationSucceeded; _sessionManager.SessionEnded += OnSessionEnded; - _sessionManager.PlaybackStart += OnPlaybackStart; _sessionManager.PlaybackStopped += OnPlaybackStopped; @@ -117,7 +117,7 @@ namespace Emby.Server.Implementations.Activity { Name = string.Format(_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"), e.Provider, Notifications.Notifications.GetItemName(e.Item)), Type = "SubtitleDownloadFailure", - ItemId = e.Item.Id.ToString("N"), + ItemId = e.Item.Id.ToString("N", CultureInfo.InvariantCulture), ShortOverview = e.Exception.Message }); } diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index de46ab9655..91371b8336 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -102,7 +102,7 @@ namespace Emby.Server.Implementations.Activity } else { - statement.TryBind("@UserId", entry.UserId.ToString("N")); + statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture)); } statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); @@ -141,7 +141,7 @@ namespace Emby.Server.Implementations.Activity } else { - statement.TryBind("@UserId", entry.UserId.ToString("N")); + statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture)); } statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index ef2f59d303..4ff90a04b0 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1220,7 +1220,7 @@ namespace Emby.Server.Implementations // Generate self-signed cert var certHost = GetHostnameFromExternalDns(ServerConfigurationManager.Configuration.WanDdns); - var certPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.ProgramDataPath, "ssl", "cert_" + (certHost + "2").GetMD5().ToString("N") + ".pfx"); + var certPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.ProgramDataPath, "ssl", "cert_" + (certHost + "2").GetMD5().ToString("N", CultureInfo.InvariantCulture) + ".pfx"); const string Password = "embycert"; return new CertificateInfo diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index e9961e8bd7..8e5f5b5617 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -206,7 +207,7 @@ namespace Emby.Server.Implementations.Channels try { - return GetChannelProvider(i).IsEnabledFor(user.Id.ToString("N")); + return GetChannelProvider(i).IsEnabledFor(user.Id.ToString("N", CultureInfo.InvariantCulture)); } catch { @@ -511,7 +512,7 @@ namespace Emby.Server.Implementations.Channels IncludeItemTypes = new[] { typeof(Channel).Name }, OrderBy = new ValueTuple[] { new ValueTuple(ItemSortBy.SortName, SortOrder.Ascending) } - }).Select(i => GetChannelFeatures(i.ToString("N"))).ToArray(); + }).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray(); } public ChannelFeatures GetChannelFeatures(string id) @@ -552,7 +553,7 @@ namespace Emby.Server.Implementations.Channels SupportsSortOrderToggle = features.SupportsSortOrderToggle, SupportsLatestMedia = supportsLatest, Name = channel.Name, - Id = channel.Id.ToString("N"), + Id = channel.Id.ToString("N", CultureInfo.InvariantCulture), SupportsContentDownloading = features.SupportsContentDownloading, AutoRefreshLevels = features.AutoRefreshLevels }; @@ -740,7 +741,7 @@ namespace Emby.Server.Implementations.Channels bool sortDescending, CancellationToken cancellationToken) { - var userId = user == null ? null : user.Id.ToString("N"); + var userId = user == null ? null : user.Id.ToString("N", CultureInfo.InvariantCulture); var cacheLength = CacheLength; var cachePath = GetChannelDataCachePath(channel, userId, externalFolderId, sortField, sortDescending); @@ -836,7 +837,7 @@ namespace Emby.Server.Implementations.Channels ChannelItemSortField? sortField, bool sortDescending) { - var channelId = GetInternalChannelId(channel.Name).ToString("N"); + var channelId = GetInternalChannelId(channel.Name).ToString("N", CultureInfo.InvariantCulture); var userCacheKey = string.Empty; @@ -846,10 +847,10 @@ namespace Emby.Server.Implementations.Channels userCacheKey = hasCacheKey.GetCacheKey(userId) ?? string.Empty; } - var filename = string.IsNullOrEmpty(externalFolderId) ? "root" : externalFolderId.GetMD5().ToString("N"); + var filename = string.IsNullOrEmpty(externalFolderId) ? "root" : externalFolderId.GetMD5().ToString("N", CultureInfo.InvariantCulture); filename += userCacheKey; - var version = ((channel.DataVersion ?? string.Empty) + "2").GetMD5().ToString("N"); + var version = ((channel.DataVersion ?? string.Empty) + "2").GetMD5().ToString("N", CultureInfo.InvariantCulture); if (sortField.HasValue) { @@ -860,7 +861,7 @@ namespace Emby.Server.Implementations.Channels filename += "-sortDescending"; } - filename = filename.GetMD5().ToString("N"); + filename = filename.GetMD5().ToString("N", CultureInfo.InvariantCulture); return Path.Combine(_config.ApplicationPaths.CachePath, "channels", diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index 2b99e0ddfc..bb5057b1c2 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -182,7 +183,7 @@ namespace Emby.Server.Implementations.Collections public void AddToCollection(Guid collectionId, IEnumerable ids) { - AddToCollection(collectionId, ids.Select(i => i.ToString("N")), true, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem))); + AddToCollection(collectionId, ids.Select(i => i.ToString("N", CultureInfo.InvariantCulture)), true, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem))); } private void AddToCollection(Guid collectionId, IEnumerable ids, bool fireEvent, MetadataRefreshOptions refreshOptions) diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs index 01ef9851dc..87096e72f5 100644 --- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Threading; using MediaBrowser.Common.Configuration; @@ -182,7 +183,7 @@ namespace Emby.Server.Implementations.Data return new DisplayPreferences { - Id = guidId.ToString("N") + Id = guidId.ToString("N", CultureInfo.InvariantCulture) }; } } diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 1cefcec7ca..bb4c34f02f 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -696,7 +696,7 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBindNull("@EndDate"); } - saveItemStatement.TryBind("@ChannelId", item.ChannelId.Equals(Guid.Empty) ? null : item.ChannelId.ToString("N")); + saveItemStatement.TryBind("@ChannelId", item.ChannelId.Equals(Guid.Empty) ? null : item.ChannelId.ToString("N", CultureInfo.InvariantCulture)); if (item is IHasProgramAttributes hasProgramAttributes) { @@ -851,7 +851,7 @@ namespace Emby.Server.Implementations.Data } else { - saveItemStatement.TryBind("@TopParentId", topParent.Id.ToString("N")); + saveItemStatement.TryBind("@TopParentId", topParent.Id.ToString("N", CultureInfo.InvariantCulture)); } if (item is Trailer trailer && trailer.TrailerTypes.Length > 0) @@ -3548,12 +3548,12 @@ namespace Emby.Server.Implementations.Data whereClauses.Add("ChannelId=@ChannelId"); if (statement != null) { - statement.TryBind("@ChannelId", query.ChannelIds[0].ToString("N")); + statement.TryBind("@ChannelId", query.ChannelIds[0].ToString("N", CultureInfo.InvariantCulture)); } } else if (query.ChannelIds.Length > 1) { - var inClause = string.Join(",", query.ChannelIds.Select(i => "'" + i.ToString("N") + "'")); + var inClause = string.Join(",", query.ChannelIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'")); whereClauses.Add($"ChannelId in ({inClause})"); } @@ -4537,12 +4537,12 @@ namespace Emby.Server.Implementations.Data } if (statement != null) { - statement.TryBind("@TopParentId", queryTopParentIds[0].ToString("N")); + statement.TryBind("@TopParentId", queryTopParentIds[0].ToString("N", CultureInfo.InvariantCulture)); } } else if (queryTopParentIds.Length > 1) { - var val = string.Join(",", queryTopParentIds.Select(i => "'" + i.ToString("N") + "'")); + var val = string.Join(",", queryTopParentIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'")); if (enableItemsByName && includedItemByNameTypes.Count == 1) { @@ -4574,7 +4574,7 @@ namespace Emby.Server.Implementations.Data } if (query.AncestorIds.Length > 1) { - var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i.ToString("N") + "'")); + var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'")); whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause)); } if (!string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey)) @@ -4637,7 +4637,7 @@ namespace Emby.Server.Implementations.Data foreach (var folderId in query.BoxSetLibraryFolders) { - folderIdQueries.Add("data like '%" + folderId.ToString("N") + "%'"); + folderIdQueries.Add("data like '%" + folderId.ToString("N", CultureInfo.InvariantCulture) + "%'"); } whereClauses.Add("(" + string.Join(" OR ", folderIdQueries) + ")"); @@ -5161,7 +5161,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type var ancestorId = ancestorIds[i]; statement.TryBind("@AncestorId" + index, ancestorId.ToGuidBlob()); - statement.TryBind("@AncestorIdText" + index, ancestorId.ToString("N")); + statement.TryBind("@AncestorIdText" + index, ancestorId.ToString("N", CultureInfo.InvariantCulture)); } statement.Reset(); @@ -5579,6 +5579,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type { counts.TrailerCount = value; } + counts.ItemCount += value; } diff --git a/Emby.Server.Implementations/Devices/DeviceId.cs b/Emby.Server.Implementations/Devices/DeviceId.cs index 495c3436ab..7344dc72f3 100644 --- a/Emby.Server.Implementations/Devices/DeviceId.cs +++ b/Emby.Server.Implementations/Devices/DeviceId.cs @@ -1,8 +1,8 @@ using System; +using System.Globalization; using System.IO; using System.Text; using MediaBrowser.Common.Configuration; -using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Devices @@ -67,7 +67,7 @@ namespace Emby.Server.Implementations.Devices private static string GetNewId() { - return Guid.NewGuid().ToString("N"); + return Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); } private string GetDeviceId() diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs index 7d6529a675..d1704b3736 100644 --- a/Emby.Server.Implementations/Devices/DeviceManager.cs +++ b/Emby.Server.Implementations/Devices/DeviceManager.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Entities; @@ -195,7 +195,7 @@ namespace Emby.Server.Implementations.Devices private string GetDevicePath(string id) { - return Path.Combine(GetDevicesPath(), id.GetMD5().ToString("N")); + return Path.Combine(GetDevicesPath(), id.GetMD5().ToString("N", CultureInfo.InvariantCulture)); } public ContentUploadHistory GetCameraUploadHistory(string deviceId) diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 2f1b60be9c..6e7aa13139 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -213,7 +214,7 @@ namespace Emby.Server.Implementations.Dto if (options.ContainsField(ItemFields.DisplayPreferencesId)) { - dto.DisplayPreferencesId = item.DisplayPreferencesId.ToString("N"); + dto.DisplayPreferencesId = item.DisplayPreferencesId.ToString("N", CultureInfo.InvariantCulture); } if (user != null) @@ -444,7 +445,7 @@ namespace Emby.Server.Implementations.Dto /// item public string GetDtoId(BaseItem item) { - return item.Id.ToString("N"); + return item.Id.ToString("N", CultureInfo.InvariantCulture); } private static void SetBookProperties(BaseItemDto dto, Book item) @@ -608,7 +609,7 @@ namespace Emby.Server.Implementations.Dto if (dictionary.TryGetValue(person.Name, out Person entity)) { baseItemPerson.PrimaryImageTag = GetImageCacheTag(entity, ImageType.Primary); - baseItemPerson.Id = entity.Id.ToString("N"); + baseItemPerson.Id = entity.Id.ToString("N", CultureInfo.InvariantCulture); list.Add(baseItemPerson); } } @@ -893,7 +894,7 @@ namespace Emby.Server.Implementations.Dto //var artistItems = _libraryManager.GetArtists(new InternalItemsQuery //{ // EnableTotalRecordCount = false, - // ItemIds = new[] { item.Id.ToString("N") } + // ItemIds = new[] { item.Id.ToString("N", CultureInfo.InvariantCulture) } //}); //dto.ArtistItems = artistItems.Items @@ -903,7 +904,7 @@ namespace Emby.Server.Implementations.Dto // return new NameIdPair // { // Name = artist.Name, - // Id = artist.Id.ToString("N") + // Id = artist.Id.ToString("N", CultureInfo.InvariantCulture) // }; // }) // .ToList(); @@ -946,7 +947,7 @@ namespace Emby.Server.Implementations.Dto //var artistItems = _libraryManager.GetAlbumArtists(new InternalItemsQuery //{ // EnableTotalRecordCount = false, - // ItemIds = new[] { item.Id.ToString("N") } + // ItemIds = new[] { item.Id.ToString("N", CultureInfo.InvariantCulture) } //}); //dto.AlbumArtists = artistItems.Items @@ -956,7 +957,7 @@ namespace Emby.Server.Implementations.Dto // return new NameIdPair // { // Name = artist.Name, - // Id = artist.Id.ToString("N") + // Id = artist.Id.ToString("N", CultureInfo.InvariantCulture) // }; // }) // .ToList(); @@ -1044,7 +1045,7 @@ namespace Emby.Server.Implementations.Dto } else { - string id = item.Id.ToString("N"); + string id = item.Id.ToString("N", CultureInfo.InvariantCulture); mediaStreams = dto.MediaSources.Where(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase)) .SelectMany(i => i.MediaStreams) .ToArray(); diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 8369f4f593..9c0db2cf5e 100644 --- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -100,7 +100,7 @@ namespace Emby.Server.Implementations.EntryPoints _lastProgressMessageTimes[item.Id] = DateTime.UtcNow; var dict = new Dictionary(); - dict["ItemId"] = item.Id.ToString("N"); + dict["ItemId"] = item.Id.ToString("N", CultureInfo.InvariantCulture); dict["Progress"] = progress.ToString(CultureInfo.InvariantCulture); try @@ -116,7 +116,7 @@ namespace Emby.Server.Implementations.EntryPoints foreach (var collectionFolder in collectionFolders) { var collectionFolderDict = new Dictionary(); - collectionFolderDict["ItemId"] = collectionFolder.Id.ToString("N"); + collectionFolderDict["ItemId"] = collectionFolder.Id.ToString("N", CultureInfo.InvariantCulture); collectionFolderDict["Progress"] = (collectionFolder.GetRefreshProgress() ?? 0).ToString(CultureInfo.InvariantCulture); try @@ -378,15 +378,15 @@ namespace Emby.Server.Implementations.EntryPoints return new LibraryUpdateInfo { - ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), + ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture)).Distinct().ToArray(), - ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), + ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture)).Distinct().ToArray(), - ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), + ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture)).Distinct().ToArray(), - FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), + FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture)).Distinct().ToArray(), - FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), + FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture)).Distinct().ToArray(), CollectionFolders = GetTopParentIds(newAndRemoved, allUserRootChildren).ToArray() }; @@ -422,7 +422,7 @@ namespace Emby.Server.Implementations.EntryPoints var collectionFolders = _libraryManager.GetCollectionFolders(item, allUserRootChildren); foreach (var folder in allUserRootChildren) { - list.Add(folder.Id.ToString("N")); + list.Add(folder.Id.ToString("N", CultureInfo.InvariantCulture)); } } diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs index 091dd6a45b..141e729584 100644 --- a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Plugins; @@ -134,7 +135,7 @@ namespace Emby.Server.Implementations.EntryPoints /// The e. void userManager_UserDeleted(object sender, GenericEventArgs e) { - SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N")); + SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N", CultureInfo.InvariantCulture)); } void _userManager_UserPolicyUpdated(object sender, GenericEventArgs e) diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index a5badaceec..bae3422ff6 100644 --- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -8,7 +9,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Session; using Microsoft.Extensions.Logging; @@ -125,12 +125,12 @@ namespace Emby.Server.Implementations.EntryPoints .Select(i => { var dto = _userDataManager.GetUserDataDto(i, user); - dto.ItemId = i.Id.ToString("N"); + dto.ItemId = i.Id.ToString("N", CultureInfo.InvariantCulture); return dto; }) .ToArray(); - var userIdString = userId.ToString("N"); + var userIdString = userId.ToString("N", CultureInfo.InvariantCulture); return new UserDataChangeInfo { diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs index 331b5e29d7..9ca33d7db7 100644 --- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs @@ -195,7 +195,7 @@ namespace Emby.Server.Implementations.HttpClientManager } var url = options.Url; - var urlHash = url.ToLowerInvariant().GetMD5().ToString("N"); + var urlHash = url.ToLowerInvariant().GetMD5().ToString("N", CultureInfo.InvariantCulture); var responseCachePath = Path.Combine(_appPaths.CachePath, "httpclient", urlHash); diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 8517abed6c..ae8371a32f 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Diagnostics; using System.IO; using System.Linq; @@ -555,7 +556,7 @@ namespace Emby.Server.Implementations.IO throw new ArgumentNullException(nameof(file2)); } - var temp1 = Path.Combine(_tempPath, Guid.NewGuid().ToString("N")); + var temp1 = Path.Combine(_tempPath, Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture)); // Copying over will fail against hidden files SetHidden(file1, false); diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs index 46f209b4b4..d8faceadb2 100644 --- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -89,7 +90,7 @@ namespace Emby.Server.Implementations.Images ImageType imageType, CancellationToken cancellationToken) { - var outputPathWithoutExtension = Path.Combine(ApplicationPaths.TempDirectory, Guid.NewGuid().ToString("N")); + var outputPathWithoutExtension = Path.Combine(ApplicationPaths.TempDirectory, Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture)); Directory.CreateDirectory(Path.GetDirectoryName(outputPathWithoutExtension)); string outputPath = CreateImage(item, itemsWithImages, outputPathWithoutExtension, imageType, 0); diff --git a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs index 45a33a2969..a3c879f121 100644 --- a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs +++ b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Library; @@ -26,7 +27,7 @@ namespace Emby.Server.Implementations.Library EnableStreamSharing = false; _closeFn = closeFn; ConsumerCount = 1; - UniqueId = Guid.NewGuid().ToString("N"); + UniqueId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); } public Task Close() diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 4b5063ada6..30ff855cc2 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1187,12 +1187,12 @@ namespace Emby.Server.Implementations.Library if (libraryFolder != null && libraryFolder.HasImage(ImageType.Primary)) { - info.PrimaryImageItemId = libraryFolder.Id.ToString("N"); + info.PrimaryImageItemId = libraryFolder.Id.ToString("N", CultureInfo.InvariantCulture); } if (libraryFolder != null) { - info.ItemId = libraryFolder.Id.ToString("N"); + info.ItemId = libraryFolder.Id.ToString("N", CultureInfo.InvariantCulture); info.LibraryOptions = GetLibraryOptions(libraryFolder); if (refreshQueue != null) @@ -2135,12 +2135,12 @@ namespace Emby.Server.Implementations.Library string viewType, string sortName) { - var parentIdString = parentId.Equals(Guid.Empty) ? null : parentId.ToString("N"); - var idValues = "38_namedview_" + name + user.Id.ToString("N") + (parentIdString ?? string.Empty) + (viewType ?? string.Empty); + var parentIdString = parentId.Equals(Guid.Empty) ? null : parentId.ToString("N", CultureInfo.InvariantCulture); + var idValues = "38_namedview_" + name + user.Id.ToString("N", CultureInfo.InvariantCulture) + (parentIdString ?? string.Empty) + (viewType ?? string.Empty); var id = GetNewItemId(idValues, typeof(UserView)); - var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N")); + var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture)); var item = GetItemById(id) as UserView; @@ -2271,7 +2271,7 @@ namespace Emby.Server.Implementations.Library throw new ArgumentNullException(nameof(name)); } - var parentIdString = parentId.Equals(Guid.Empty) ? null : parentId.ToString("N"); + var parentIdString = parentId.Equals(Guid.Empty) ? null : parentId.ToString("N", CultureInfo.InvariantCulture); var idValues = "37_namedview_" + name + (parentIdString ?? string.Empty) + (viewType ?? string.Empty); if (!string.IsNullOrEmpty(uniqueId)) { @@ -2280,7 +2280,7 @@ namespace Emby.Server.Implementations.Library var id = GetNewItemId(idValues, typeof(UserView)); - var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N")); + var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture)); var item = GetItemById(id) as UserView; diff --git a/Emby.Server.Implementations/Library/LiveStreamHelper.cs b/Emby.Server.Implementations/Library/LiveStreamHelper.cs index c3082a78a7..33e6f24341 100644 --- a/Emby.Server.Implementations/Library/LiveStreamHelper.cs +++ b/Emby.Server.Implementations/Library/LiveStreamHelper.cs @@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Library var now = DateTime.UtcNow; MediaInfo mediaInfo = null; - var cacheFilePath = string.IsNullOrEmpty(cacheKey) ? null : Path.Combine(_appPaths.CachePath, "mediainfo", cacheKey.GetMD5().ToString("N") + ".json"); + var cacheFilePath = string.IsNullOrEmpty(cacheKey) ? null : Path.Combine(_appPaths.CachePath, "mediainfo", cacheKey.GetMD5().ToString("N", CultureInfo.InvariantCulture) + ".json"); if (!string.IsNullOrEmpty(cacheKey)) { diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 24ab8e7619..d83e1fc021 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -269,7 +269,7 @@ namespace Emby.Server.Implementations.Library private static void SetKeyProperties(IMediaSourceProvider provider, MediaSourceInfo mediaSource) { - var prefix = provider.GetType().FullName.GetMD5().ToString("N") + LiveStreamIdDelimeter; + var prefix = provider.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture) + LiveStreamIdDelimeter; if (!string.IsNullOrEmpty(mediaSource.OpenToken) && !mediaSource.OpenToken.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { @@ -626,7 +626,7 @@ namespace Emby.Server.Implementations.Library var now = DateTime.UtcNow; MediaInfo mediaInfo = null; - var cacheFilePath = string.IsNullOrEmpty(cacheKey) ? null : Path.Combine(_appPaths.CachePath, "mediainfo", cacheKey.GetMD5().ToString("N") + ".json"); + var cacheFilePath = string.IsNullOrEmpty(cacheKey) ? null : Path.Combine(_appPaths.CachePath, "mediainfo", cacheKey.GetMD5().ToString("N", CultureInfo.InvariantCulture) + ".json"); if (!string.IsNullOrEmpty(cacheKey)) { @@ -854,7 +854,7 @@ namespace Emby.Server.Implementations.Library var keys = key.Split(new[] { LiveStreamIdDelimeter }, 2); - var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N"), keys[0], StringComparison.OrdinalIgnoreCase)); + var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture), keys[0], StringComparison.OrdinalIgnoreCase)); var splitIndex = key.IndexOf(LiveStreamIdDelimeter); var keyId = key.Substring(splitIndex + 1); diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs index dfa1edaffd..36adc0b9c4 100644 --- a/Emby.Server.Implementations/Library/UserDataManager.cs +++ b/Emby.Server.Implementations/Library/UserDataManager.cs @@ -152,7 +152,7 @@ namespace Emby.Server.Implementations.Library /// System.String. private static string GetCacheKey(long internalUserId, Guid itemId) { - return internalUserId.ToString(CultureInfo.InvariantCulture) + "-" + itemId.ToString("N"); + return internalUserId.ToString(CultureInfo.InvariantCulture) + "-" + itemId.ToString("N", CultureInfo.InvariantCulture); } public UserItemData GetUserData(User user, BaseItem item) diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs index e9ce682ee1..71f16ac3e9 100644 --- a/Emby.Server.Implementations/Library/UserViewManager.cs +++ b/Emby.Server.Implementations/Library/UserViewManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using MediaBrowser.Controller.Channels; @@ -117,7 +118,7 @@ namespace Emby.Server.Implementations.Library if (!query.IncludeHidden) { - list = list.Where(i => !user.Configuration.MyMediaExcludes.Contains(i.Id.ToString("N"))).ToList(); + list = list.Where(i => !user.Configuration.MyMediaExcludes.Contains(i.Id.ToString("N", CultureInfo.InvariantCulture))).ToList(); } var sorted = _libraryManager.Sort(list, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).ToList(); @@ -127,7 +128,7 @@ namespace Emby.Server.Implementations.Library return list .OrderBy(i => { - var index = orders.IndexOf(i.Id.ToString("N")); + var index = orders.IndexOf(i.Id.ToString("N", CultureInfo.InvariantCulture)); if (index == -1) { @@ -136,7 +137,7 @@ namespace Emby.Server.Implementations.Library { if (!view.DisplayParentId.Equals(Guid.Empty)) { - index = orders.IndexOf(view.DisplayParentId.ToString("N")); + index = orders.IndexOf(view.DisplayParentId.ToString("N", CultureInfo.InvariantCulture)); } } } @@ -269,7 +270,7 @@ namespace Emby.Server.Implementations.Library { parents = _libraryManager.GetUserRootFolder().GetChildren(user, true) .Where(i => i is Folder) - .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N"))) + .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N", CultureInfo.InvariantCulture))) .ToList(); } diff --git a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs index 294348660f..b584cc649d 100644 --- a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -91,7 +92,7 @@ namespace Emby.Server.Implementations.Library.Validators continue; } - _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N"), item.Name, item.GetType().Name); + _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name, item.GetType().Name); _libraryManager.DeleteItem(item, new DeleteOptions { diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs index 7899cf01b3..d00c6cde11 100644 --- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -1,7 +1,7 @@ using System; +using System.Globalization; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; @@ -96,7 +96,7 @@ namespace Emby.Server.Implementations.Library.Validators foreach (var item in deadEntities) { - _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N"), item.Name, item.GetType().Name); + _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name, item.GetType().Name); _libraryManager.DeleteItem(item, new DeleteOptions { diff --git a/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs b/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs index da4645a11d..93ded9e7bd 100644 --- a/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Entities; @@ -76,7 +77,7 @@ namespace Emby.Server.Implementations.Library.Validators foreach (var item in deadEntities) { - _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N"), item.Name, item.GetType().Name); + _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name, item.GetType().Name); _libraryManager.DeleteItem(item, new DeleteOptions { diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 7b210d2313..d7411af502 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -681,7 +681,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } - timer.Id = Guid.NewGuid().ToString("N"); + timer.Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); LiveTvProgram programInfo = null; @@ -713,7 +713,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV public async Task CreateSeriesTimer(SeriesTimerInfo info, CancellationToken cancellationToken) { - info.Id = Guid.NewGuid().ToString("N"); + info.Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); // populate info.seriesID var program = GetProgramInfoFromCache(info.ProgramId); @@ -1059,7 +1059,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var json = _jsonSerializer.SerializeToString(mediaSource); mediaSource = _jsonSerializer.DeserializeFromString(json); - mediaSource.Id = Guid.NewGuid().ToString("N") + "_" + mediaSource.Id; + mediaSource.Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture) + "_" + mediaSource.Id; //if (mediaSource.DateLiveStreamOpened.HasValue && enableStreamSharing) //{ @@ -2529,7 +2529,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var timer = new TimerInfo { ChannelId = channelId, - Id = (seriesTimer.Id + parent.ExternalId).GetMD5().ToString("N"), + Id = (seriesTimer.Id + parent.ExternalId).GetMD5().ToString("N", CultureInfo.InvariantCulture), StartDate = parent.StartDate, EndDate = parent.EndDate.Value, ProgramId = parent.ExternalId, diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index 94225a0aa9..88693f22a4 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -211,7 +211,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings HasImage = program.Icon != null && !string.IsNullOrEmpty(program.Icon.Source), OfficialRating = program.Rating != null && !string.IsNullOrEmpty(program.Rating.Value) ? program.Rating.Value : null, CommunityRating = program.StarRating, - SeriesId = program.Episode == null ? null : program.Title.GetMD5().ToString("N") + SeriesId = program.Episode == null ? null : program.Title.GetMD5().ToString("N", CultureInfo.InvariantCulture) }; if (string.IsNullOrWhiteSpace(program.ProgramId)) @@ -227,7 +227,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings uniqueString = "-" + programInfo.EpisodeNumber.Value.ToString(CultureInfo.InvariantCulture); } - programInfo.ShowId = uniqueString.GetMD5().ToString("N"); + programInfo.ShowId = uniqueString.GetMD5().ToString("N", CultureInfo.InvariantCulture); // If we don't have valid episode info, assume it's a unique program, otherwise recordings might be skipped if (programInfo.IsSeries diff --git a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs index 1144c9ab17..e584664c94 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -52,7 +53,7 @@ namespace Emby.Server.Implementations.LiveTv ExternalId = info.Id, ChannelId = GetInternalChannelId(service.Name, info.ChannelId), Status = info.Status, - SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) ? null : GetInternalSeriesTimerId(info.SeriesTimerId).ToString("N"), + SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) ? null : GetInternalSeriesTimerId(info.SeriesTimerId).ToString("N", CultureInfo.InvariantCulture), PrePaddingSeconds = info.PrePaddingSeconds, PostPaddingSeconds = info.PostPaddingSeconds, IsPostPaddingRequired = info.IsPostPaddingRequired, @@ -69,7 +70,7 @@ namespace Emby.Server.Implementations.LiveTv if (!string.IsNullOrEmpty(info.ProgramId)) { - dto.ProgramId = GetInternalProgramId(info.ProgramId).ToString("N"); + dto.ProgramId = GetInternalProgramId(info.ProgramId).ToString("N", CultureInfo.InvariantCulture); } if (program != null) @@ -107,7 +108,7 @@ namespace Emby.Server.Implementations.LiveTv { var dto = new SeriesTimerInfoDto { - Id = GetInternalSeriesTimerId(info.Id).ToString("N"), + Id = GetInternalSeriesTimerId(info.Id).ToString("N", CultureInfo.InvariantCulture), Overview = info.Overview, EndDate = info.EndDate, Name = info.Name, @@ -139,7 +140,7 @@ namespace Emby.Server.Implementations.LiveTv if (!string.IsNullOrEmpty(info.ProgramId)) { - dto.ProgramId = GetInternalProgramId(info.ProgramId).ToString("N"); + dto.ProgramId = GetInternalProgramId(info.ProgramId).ToString("N", CultureInfo.InvariantCulture); } dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days.ToArray()); @@ -169,7 +170,7 @@ namespace Emby.Server.Implementations.LiveTv try { dto.ParentThumbImageTag = _imageProcessor.GetImageCacheTag(librarySeries, image); - dto.ParentThumbItemId = librarySeries.Id.ToString("N"); + dto.ParentThumbItemId = librarySeries.Id.ToString("N", CultureInfo.InvariantCulture); } catch (Exception ex) { @@ -185,7 +186,7 @@ namespace Emby.Server.Implementations.LiveTv { _imageProcessor.GetImageCacheTag(librarySeries, image) }; - dto.ParentBackdropItemId = librarySeries.Id.ToString("N"); + dto.ParentBackdropItemId = librarySeries.Id.ToString("N", CultureInfo.InvariantCulture); } catch (Exception ex) { @@ -213,7 +214,7 @@ namespace Emby.Server.Implementations.LiveTv try { dto.ParentPrimaryImageTag = _imageProcessor.GetImageCacheTag(program, image); - dto.ParentPrimaryImageItemId = program.Id.ToString("N"); + dto.ParentPrimaryImageItemId = program.Id.ToString("N", CultureInfo.InvariantCulture); } catch (Exception ex) { @@ -232,7 +233,7 @@ namespace Emby.Server.Implementations.LiveTv { _imageProcessor.GetImageCacheTag(program, image) }; - dto.ParentBackdropItemId = program.Id.ToString("N"); + dto.ParentBackdropItemId = program.Id.ToString("N", CultureInfo.InvariantCulture); } catch (Exception ex) { @@ -263,7 +264,7 @@ namespace Emby.Server.Implementations.LiveTv try { dto.ParentThumbImageTag = _imageProcessor.GetImageCacheTag(librarySeries, image); - dto.ParentThumbItemId = librarySeries.Id.ToString("N"); + dto.ParentThumbItemId = librarySeries.Id.ToString("N", CultureInfo.InvariantCulture); } catch (Exception ex) { @@ -279,7 +280,7 @@ namespace Emby.Server.Implementations.LiveTv { _imageProcessor.GetImageCacheTag(librarySeries, image) }; - dto.ParentBackdropItemId = librarySeries.Id.ToString("N"); + dto.ParentBackdropItemId = librarySeries.Id.ToString("N", CultureInfo.InvariantCulture); } catch (Exception ex) { @@ -320,7 +321,7 @@ namespace Emby.Server.Implementations.LiveTv try { dto.ParentPrimaryImageTag = _imageProcessor.GetImageCacheTag(program, image); - dto.ParentPrimaryImageItemId = program.Id.ToString("N"); + dto.ParentPrimaryImageItemId = program.Id.ToString("N", CultureInfo.InvariantCulture); } catch (Exception ex) { @@ -339,7 +340,7 @@ namespace Emby.Server.Implementations.LiveTv { _imageProcessor.GetImageCacheTag(program, image) }; - dto.ParentBackdropItemId = program.Id.ToString("N"); + dto.ParentBackdropItemId = program.Id.ToString("N", CultureInfo.InvariantCulture); } catch (Exception ex) { @@ -407,7 +408,7 @@ namespace Emby.Server.Implementations.LiveTv { var name = ServiceName + externalId + InternalVersionNumber; - return name.ToLowerInvariant().GetMD5().ToString("N"); + return name.ToLowerInvariant().GetMD5().ToString("N", CultureInfo.InvariantCulture); } public Guid GetInternalSeriesTimerId(string externalId) diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 9093d9740f..1e5198dd6c 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -258,7 +259,7 @@ namespace Emby.Server.Implementations.LiveTv } info.RequiresClosing = true; - var idPrefix = service.GetType().FullName.GetMD5().ToString("N") + "_"; + var idPrefix = service.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture) + "_"; info.LiveStreamId = idPrefix + info.Id; @@ -820,7 +821,7 @@ namespace Emby.Server.Implementations.LiveTv if (!string.IsNullOrWhiteSpace(query.SeriesTimerId)) { var seriesTimers = await GetSeriesTimersInternal(new SeriesTimerQuery { }, cancellationToken).ConfigureAwait(false); - var seriesTimer = seriesTimers.Items.FirstOrDefault(i => string.Equals(_tvDtoService.GetInternalSeriesTimerId(i.Id).ToString("N"), query.SeriesTimerId, StringComparison.OrdinalIgnoreCase)); + var seriesTimer = seriesTimers.Items.FirstOrDefault(i => string.Equals(_tvDtoService.GetInternalSeriesTimerId(i.Id).ToString("N", CultureInfo.InvariantCulture), query.SeriesTimerId, StringComparison.OrdinalIgnoreCase)); if (seriesTimer != null) { internalQuery.ExternalSeriesId = seriesTimer.SeriesId; @@ -997,7 +998,7 @@ namespace Emby.Server.Implementations.LiveTv if (!string.IsNullOrEmpty(timer.SeriesTimerId)) { program.SeriesTimerId = _tvDtoService.GetInternalSeriesTimerId(timer.SeriesTimerId) - .ToString("N"); + .ToString("N", CultureInfo.InvariantCulture); foundSeriesTimer = true; } @@ -1018,7 +1019,7 @@ namespace Emby.Server.Implementations.LiveTv if (seriesTimer != null) { program.SeriesTimerId = _tvDtoService.GetInternalSeriesTimerId(seriesTimer.Id) - .ToString("N"); + .ToString("N", CultureInfo.InvariantCulture); } } } @@ -1472,7 +1473,7 @@ namespace Emby.Server.Implementations.LiveTv dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) ? null - : _tvDtoService.GetInternalSeriesTimerId(info.SeriesTimerId).ToString("N"); + : _tvDtoService.GetInternalSeriesTimerId(info.SeriesTimerId).ToString("N", CultureInfo.InvariantCulture); dto.TimerId = string.IsNullOrEmpty(info.Id) ? null @@ -2027,7 +2028,7 @@ namespace Emby.Server.Implementations.LiveTv info.StartDate = program.StartDate; info.Name = program.Name; info.Overview = program.Overview; - info.ProgramId = programDto.Id.ToString("N"); + info.ProgramId = programDto.Id.ToString("N", CultureInfo.InvariantCulture); info.ExternalProgramId = program.ExternalId; if (program.EndDate.HasValue) @@ -2088,7 +2089,7 @@ namespace Emby.Server.Implementations.LiveTv if (service is ISupportsNewTimerIds supportsNewTimerIds) { newTimerId = await supportsNewTimerIds.CreateSeriesTimer(info, cancellationToken).ConfigureAwait(false); - newTimerId = _tvDtoService.GetInternalSeriesTimerId(newTimerId).ToString("N"); + newTimerId = _tvDtoService.GetInternalSeriesTimerId(newTimerId).ToString("N", CultureInfo.InvariantCulture); } else { @@ -2192,7 +2193,7 @@ namespace Emby.Server.Implementations.LiveTv info.EnabledUsers = _userManager.Users .Where(IsLiveTvEnabled) - .Select(i => i.Id.ToString("N")) + .Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture)) .ToArray(); return info; @@ -2219,7 +2220,7 @@ namespace Emby.Server.Implementations.LiveTv { var parts = id.Split(new[] { '_' }, 2); - var service = _services.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N"), parts[0], StringComparison.OrdinalIgnoreCase)); + var service = _services.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture), parts[0], StringComparison.OrdinalIgnoreCase)); if (service == null) { @@ -2269,7 +2270,7 @@ namespace Emby.Server.Implementations.LiveTv if (index == -1 || string.IsNullOrWhiteSpace(info.Id)) { - info.Id = Guid.NewGuid().ToString("N"); + info.Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); list.Add(info); config.TunerHosts = list.ToArray(); } @@ -2312,7 +2313,7 @@ namespace Emby.Server.Implementations.LiveTv if (index == -1 || string.IsNullOrWhiteSpace(info.Id)) { - info.Id = Guid.NewGuid().ToString("N"); + info.Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); list.Add(info); config.ListingProviders = list.ToArray(); } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index cd1731de55..52d60c004a 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -101,7 +102,7 @@ namespace Emby.Server.Implementations.LiveTv { var openKeys = new List(); openKeys.Add(item.GetType().Name); - openKeys.Add(item.Id.ToString("N")); + openKeys.Add(item.Id.ToString("N", CultureInfo.InvariantCulture)); openKeys.Add(source.Id ?? string.Empty); source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray()); } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index ed524cae30..db016ec70b 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Net; @@ -460,7 +461,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { id = "native"; } - id += "_" + channelId.GetMD5().ToString("N") + "_" + url.GetMD5().ToString("N"); + id += "_" + channelId.GetMD5().ToString("N", CultureInfo.InvariantCulture) + "_" + url.GetMD5().ToString("N", CultureInfo.InvariantCulture); var mediaSource = new MediaSourceInfo { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs index ece2cbd547..b4395e2e1d 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -42,7 +43,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts MediaSource = mediaSource; Logger = logger; EnableStreamSharing = true; - UniqueId = Guid.NewGuid().ToString("N"); + UniqueId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); if (tuner != null) { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 2d9bec53f0..6c5c80827d 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -43,7 +44,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts private string GetFullChannelIdPrefix(TunerHostInfo info) { - return ChannelIdPrefix + info.Url.GetMD5().ToString("N"); + return ChannelIdPrefix + info.Url.GetMD5().ToString("N", CultureInfo.InvariantCulture); } protected override async Task> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) @@ -61,7 +62,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts Name = Name, SourceType = Type, Status = LiveTvTunerStatus.Available, - Id = i.Url.GetMD5().ToString("N"), + Id = i.Url.GetMD5().ToString("N", CultureInfo.InvariantCulture), Url = i.Url }) .ToList(); @@ -173,7 +174,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts ReadAtNativeFramerate = false, - Id = channel.Path.GetMD5().ToString("N"), + Id = channel.Path.GetMD5().ToString("N", CultureInfo.InvariantCulture), IsInfiniteStream = true, IsRemote = isRemote, diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 814031b126..e8cd129f5c 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -92,11 +92,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts var channel = GetChannelnfo(extInf, tunerHostId, line); if (string.IsNullOrWhiteSpace(channel.Id)) { - channel.Id = channelIdPrefix + line.GetMD5().ToString("N"); + channel.Id = channelIdPrefix + line.GetMD5().ToString("N", CultureInfo.InvariantCulture); } else { - channel.Id = channelIdPrefix + channel.Id.GetMD5().ToString("N"); + channel.Id = channelIdPrefix + channel.Id.GetMD5().ToString("N", CultureInfo.InvariantCulture); } channel.Path = line; diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index 29836e0bff..40b568b40a 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -129,7 +130,7 @@ namespace Emby.Server.Implementations.Playlists { new Share { - UserId = options.UserId.Equals(Guid.Empty) ? null : options.UserId.ToString("N"), + UserId = options.UserId.Equals(Guid.Empty) ? null : options.UserId.ToString("N", CultureInfo.InvariantCulture), CanEdit = true } } @@ -144,7 +145,7 @@ namespace Emby.Server.Implementations.Playlists if (options.ItemIdList.Length > 0) { - AddToPlaylistInternal(playlist.Id.ToString("N"), options.ItemIdList, user, new DtoOptions(false) + AddToPlaylistInternal(playlist.Id.ToString("N", CultureInfo.InvariantCulture), options.ItemIdList, user, new DtoOptions(false) { EnableImages = true }); @@ -152,7 +153,7 @@ namespace Emby.Server.Implementations.Playlists return new PlaylistCreationResult { - Id = playlist.Id.ToString("N") + Id = playlist.Id.ToString("N", CultureInfo.InvariantCulture) }; } finally diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index 08bb39578b..83226b07f1 100644 --- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -1,5 +1,5 @@ using System; -using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -287,7 +287,7 @@ namespace Emby.Server.Implementations.ScheduledTasks { if (_id == null) { - _id = ScheduledTask.GetType().FullName.GetMD5().ToString("N"); + _id = ScheduledTask.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture); } return _id; diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs index 545e11bf9f..26a08cbe9a 100644 --- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs +++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs @@ -174,7 +174,7 @@ namespace Emby.Server.Implementations.Security if (!query.UserId.Equals(Guid.Empty)) { - statement.TryBind("@UserId", query.UserId.ToString("N")); + statement.TryBind("@UserId", query.UserId.ToString("N", CultureInfo.InvariantCulture)); } if (!string.IsNullOrEmpty(query.DeviceId)) diff --git a/Emby.Server.Implementations/Serialization/JsonSerializer.cs b/Emby.Server.Implementations/Serialization/JsonSerializer.cs index 8ae7fd90cc..36196ee36c 100644 --- a/Emby.Server.Implementations/Serialization/JsonSerializer.cs +++ b/Emby.Server.Implementations/Serialization/JsonSerializer.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; using System.Threading.Tasks; using MediaBrowser.Model.IO; @@ -245,7 +246,7 @@ namespace Emby.Server.Implementations.Serialization return null; } - return guid.ToString("N"); + return guid.ToString("N", CultureInfo.InvariantCulture); } /// diff --git a/Emby.Server.Implementations/Session/HttpSessionController.cs b/Emby.Server.Implementations/Session/HttpSessionController.cs index 9281f82b39..1104a7a85b 100644 --- a/Emby.Server.Implementations/Session/HttpSessionController.cs +++ b/Emby.Server.Implementations/Session/HttpSessionController.cs @@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.Session { var dict = new Dictionary(); - dict["ItemIds"] = string.Join(",", command.ItemIds.Select(i => i.ToString("N")).ToArray()); + dict["ItemIds"] = string.Join(",", command.ItemIds.Select(i => i.ToString("N", CultureInfo.InvariantCulture)).ToArray()); if (command.StartPositionTicks.HasValue) { diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 53ed5fc223..7ee573da5f 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -327,7 +327,7 @@ namespace Emby.Server.Implementations.Session { if (string.IsNullOrEmpty(info.MediaSourceId)) { - info.MediaSourceId = info.ItemId.ToString("N"); + info.MediaSourceId = info.ItemId.ToString("N", CultureInfo.InvariantCulture); } if (!info.ItemId.Equals(Guid.Empty) && info.Item == null && libraryItem != null) @@ -463,7 +463,7 @@ namespace Emby.Server.Implementations.Session Client = appName, DeviceId = deviceId, ApplicationVersion = appVersion, - Id = key.GetMD5().ToString("N"), + Id = key.GetMD5().ToString("N", CultureInfo.InvariantCulture), ServerId = _appHost.SystemId }; @@ -845,7 +845,7 @@ namespace Emby.Server.Implementations.Session // Normalize if (string.IsNullOrEmpty(info.MediaSourceId)) { - info.MediaSourceId = info.ItemId.ToString("N"); + info.MediaSourceId = info.ItemId.ToString("N", CultureInfo.InvariantCulture); } if (!info.ItemId.Equals(Guid.Empty) && info.Item == null && libraryItem != null) @@ -1029,7 +1029,7 @@ namespace Emby.Server.Implementations.Session private static async Task SendMessageToSession(SessionInfo session, string name, T data, CancellationToken cancellationToken) { var controllers = session.SessionControllers.ToArray(); - var messageId = Guid.NewGuid().ToString("N"); + var messageId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); foreach (var controller in controllers) { @@ -1234,7 +1234,7 @@ namespace Emby.Server.Implementations.Session AssertCanControl(session, controllingSession); if (!controllingSession.UserId.Equals(Guid.Empty)) { - command.ControllingUserId = controllingSession.UserId.ToString("N"); + command.ControllingUserId = controllingSession.UserId.ToString("N", CultureInfo.InvariantCulture); } } @@ -1484,7 +1484,7 @@ namespace Emby.Server.Implementations.Session DeviceId = deviceId, DeviceName = deviceName, UserId = user.Id, - AccessToken = Guid.NewGuid().ToString("N"), + AccessToken = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture), UserName = user.Name }; @@ -1822,6 +1822,7 @@ namespace Emby.Server.Implementations.Session CheckDisposed(); var sessions = Sessions.Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase)); + return SendMessageToSessions(sessions, name, data, cancellationToken); } @@ -1831,6 +1832,7 @@ namespace Emby.Server.Implementations.Session var sessions = Sessions .Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase) || IsAdminSession(i)); + return SendMessageToSessions(sessions, name, data, cancellationToken); } diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index 630ef4893b..4c2f24e6f2 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dto; @@ -73,7 +74,7 @@ namespace Emby.Server.Implementations.TV { parents = _libraryManager.GetUserRootFolder().GetChildren(user, true) .Where(i => i is Folder) - .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N"))) + .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N", CultureInfo.InvariantCulture))) .ToArray(); } diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 10bbc9e5d8..23c7339d27 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -537,7 +538,7 @@ namespace MediaBrowser.Api.Images if (item == null) { - throw new ResourceNotFoundException(string.Format("Item {0} not found.", itemId.ToString("N"))); + throw new ResourceNotFoundException(string.Format("Item {0} not found.", itemId.ToString("N", CultureInfo.InvariantCulture))); } } diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index d6bcf7878b..7266bf9f92 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -272,7 +273,7 @@ namespace MediaBrowser.Api.Library // Changing capitalization. Handle windows case insensitivity if (string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase)) { - var tempPath = Path.Combine(rootFolderPath, Guid.NewGuid().ToString("N")); + var tempPath = Path.Combine(rootFolderPath, Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture)); Directory.Move(currentPath, tempPath); currentPath = tempPath; } diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 91766255fd..d601fb5007 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; @@ -11,7 +12,6 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Services; @@ -268,7 +268,7 @@ namespace MediaBrowser.Api.Movies EnableGroupByMetadataKey = true, DtoOptions = dtoOptions - }).GroupBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) + }).GroupBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture)) .Select(x => x.First()) .Take(itemLimit) .ToList(); @@ -309,7 +309,7 @@ namespace MediaBrowser.Api.Movies EnableGroupByMetadataKey = true, DtoOptions = dtoOptions - }).GroupBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) + }).GroupBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture)) .Select(x => x.First()) .Take(itemLimit) .ToList(); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 3994016240..114d3f7a24 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -142,7 +142,7 @@ namespace MediaBrowser.Api.Playback data += "-" + (state.Request.DeviceId ?? string.Empty) + "-" + (state.Request.PlaySessionId ?? string.Empty); - var filename = data.GetMD5().ToString("N"); + var filename = data.GetMD5().ToString("N", CultureInfo.InvariantCulture); var ext = outputFileExtension.ToLowerInvariant(); var folder = ServerConfigurationManager.ApplicationPaths.TranscodingTempPath; @@ -215,6 +215,12 @@ namespace MediaBrowser.Api.Playback var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions(); +<<<<<<< HEAD +======= + var transcodingId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); + var commandLineArgs = GetCommandLineArguments(outputPath, encodingOptions, state, true); + +>>>>>>> Use CultureInvariant string conversion for Guids var process = new Process() { StartInfo = new ProcessStartInfo() diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index ab3994a639..da8f99a3dd 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -306,7 +307,7 @@ namespace MediaBrowser.Api.Playback { result.MediaSources = Clone(result.MediaSources); - result.PlaySessionId = Guid.NewGuid().ToString("N"); + result.PlaySessionId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); } return result; diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index ecf07c9122..6c67d4fb15 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; @@ -305,7 +306,7 @@ namespace MediaBrowser.Api if (tag != null) { hint.ThumbImageTag = tag; - hint.ThumbImageItemId = itemWithImage.Id.ToString("N"); + hint.ThumbImageItemId = itemWithImage.Id.ToString("N", CultureInfo.InvariantCulture); } } } @@ -326,7 +327,7 @@ namespace MediaBrowser.Api if (tag != null) { hint.BackdropImageTag = tag; - hint.BackdropImageItemId = itemWithImage.Id.ToString("N"); + hint.BackdropImageItemId = itemWithImage.Id.ToString("N", CultureInfo.InvariantCulture); } } } diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index 4109b12bfa..76392e27c9 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -316,7 +317,7 @@ namespace MediaBrowser.Api.Session _authRepo.Create(new AuthenticationInfo { AppName = request.App, - AccessToken = Guid.NewGuid().ToString("N"), + AccessToken = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture), DateCreated = DateTime.UtcNow, DeviceId = _appHost.SystemId, DeviceName = _appHost.FriendlyName, diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index 08aa540a54..52043d3df6 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -168,7 +168,7 @@ namespace MediaBrowser.Api.Subtitles builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0"); builder.AppendLine("#EXT-X-PLAYLIST-TYPE:VOD"); - long positionTicks = 0; + long positionTicks = 0; var accessToken = _authContext.GetAuthorizationInfo(Request).Token; @@ -206,7 +206,7 @@ namespace MediaBrowser.Api.Subtitles { var item = (Video)_libraryManager.GetItemById(request.Id); - var idString = request.Id.ToString("N"); + var idString = request.Id.ToString("N", CultureInfo.InvariantCulture); var mediaSource = _mediaSourceManager.GetStaticMediaSources(item, false, null) .First(i => string.Equals(i.Id, request.MediaSourceId ?? idString)); diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index b0900a5548..2951fa6b47 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Dto; @@ -470,7 +471,7 @@ namespace MediaBrowser.Api if (!string.IsNullOrWhiteSpace(request.StartItemId)) { - episodes = episodes.SkipWhile(i => !string.Equals(i.Id.ToString("N"), request.StartItemId, StringComparison.OrdinalIgnoreCase)).ToList(); + episodes = episodes.SkipWhile(i => !string.Equals(i.Id.ToString("N", CultureInfo.InvariantCulture), request.StartItemId, StringComparison.OrdinalIgnoreCase)).ToList(); } // This must be the last filter diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index f842230ee3..c605cd3962 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -99,7 +99,7 @@ namespace MediaBrowser.Api.UserLibrary { ancestorIds = _libraryManager.GetUserRootFolder().GetChildren(user, true) .Where(i => i is Folder) - .Where(i => !excludeFolderIds.Contains(i.Id.ToString("N"))) + .Where(i => !excludeFolderIds.Contains(i.Id.ToString("N", CultureInfo.InvariantCulture))) .Select(i => i.Id) .ToArray(); } diff --git a/MediaBrowser.Api/UserLibrary/UserViewsService.cs b/MediaBrowser.Api/UserLibrary/UserViewsService.cs index 1d61c5c1e8..2fa5d8933c 100644 --- a/MediaBrowser.Api/UserLibrary/UserViewsService.cs +++ b/MediaBrowser.Api/UserLibrary/UserViewsService.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; @@ -116,7 +117,7 @@ namespace MediaBrowser.Api.UserLibrary .Select(i => new SpecialViewOption { Name = i.Name, - Id = i.Id.ToString("N") + Id = i.Id.ToString("N", CultureInfo.InvariantCulture) }) .OrderBy(i => i.Name) diff --git a/MediaBrowser.Api/VideosService.cs b/MediaBrowser.Api/VideosService.cs index 061f724380..474036f5cb 100644 --- a/MediaBrowser.Api/VideosService.cs +++ b/MediaBrowser.Api/VideosService.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using System.Threading; using MediaBrowser.Controller.Configuration; @@ -168,7 +169,7 @@ namespace MediaBrowser.Api foreach (var item in items.Where(i => i.Id != primaryVersion.Id)) { - item.SetPrimaryVersionId(primaryVersion.Id.ToString("N")); + item.SetPrimaryVersionId(primaryVersion.Id.ToString("N", CultureInfo.InvariantCulture)); item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None); diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index adf03fb661..89159973b8 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using System.Threading; using MediaBrowser.Common.Progress; @@ -14,14 +15,14 @@ namespace MediaBrowser.Controller.Channels { if (user.Policy.BlockedChannels != null) { - if (user.Policy.BlockedChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (user.Policy.BlockedChannels.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase)) { return false; } } else { - if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase)) { return false; } @@ -60,7 +61,7 @@ namespace MediaBrowser.Controller.Channels public static string GetInternalMetadataPath(string basePath, Guid id) { - return System.IO.Path.Combine(basePath, "channels", id.ToString("N"), "metadata"); + return System.IO.Path.Combine(basePath, "channels", id.ToString("N", CultureInfo.InvariantCulture), "metadata"); } public override bool CanDelete() diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 10a603e42c..2ae856b020 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -503,7 +503,7 @@ namespace MediaBrowser.Controller.Entities foreach (var folder in collectionFolders) { - if (allowed.Contains(folder.Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (allowed.Contains(folder.Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase)) { return true; } @@ -664,10 +664,10 @@ namespace MediaBrowser.Controller.Entities { if (SourceType == SourceType.Channel) { - return System.IO.Path.Combine(basePath, "channels", ChannelId.ToString("N"), Id.ToString("N")); + return System.IO.Path.Combine(basePath, "channels", ChannelId.ToString("N", CultureInfo.InvariantCulture), Id.ToString("N", CultureInfo.InvariantCulture)); } - var idString = Id.ToString("N"); + var idString = Id.ToString("N", CultureInfo.InvariantCulture); basePath = System.IO.Path.Combine(basePath, "library"); @@ -1095,7 +1095,7 @@ namespace MediaBrowser.Controller.Entities var info = new MediaSourceInfo { - Id = item.Id.ToString("N"), + Id = item.Id.ToString("N", CultureInfo.InvariantCulture), Protocol = protocol ?? MediaProtocol.File, MediaStreams = MediaSourceManager.GetMediaStreams(item.Id), Name = GetMediaSourceName(item), @@ -1113,7 +1113,7 @@ namespace MediaBrowser.Controller.Entities if (info.Protocol == MediaProtocol.File) { - info.ETag = item.DateModified.Ticks.ToString(CultureInfo.InvariantCulture).GetMD5().ToString("N"); + info.ETag = item.DateModified.Ticks.ToString(CultureInfo.InvariantCulture).GetMD5().ToString("N", CultureInfo.InvariantCulture); } var video = item as Video; @@ -1626,7 +1626,7 @@ namespace MediaBrowser.Controller.Entities public virtual string CreatePresentationUniqueKey() { - return Id.ToString("N"); + return Id.ToString("N", CultureInfo.InvariantCulture); } [IgnoreDataMember] @@ -2736,7 +2736,7 @@ namespace MediaBrowser.Controller.Entities { var list = GetEtagValues(user); - return string.Join("|", list.ToArray()).GetMD5().ToString("N"); + return string.Join("|", list.ToArray()).GetMD5().ToString("N", CultureInfo.InvariantCulture); } protected virtual List GetEtagValues(User user) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index c056bc0b4e..d841b7ef84 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -177,7 +178,7 @@ namespace MediaBrowser.Controller.Entities { if (user.Policy.BlockedMediaFolders != null) { - if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) || + if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase) || // Backwards compatibility user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase)) @@ -187,7 +188,7 @@ namespace MediaBrowser.Controller.Entities } else { - if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase)) { return false; } diff --git a/MediaBrowser.Controller/Entities/LinkedChild.cs b/MediaBrowser.Controller/Entities/LinkedChild.cs index bb2d03246a..8230604888 100644 --- a/MediaBrowser.Controller/Entities/LinkedChild.cs +++ b/MediaBrowser.Controller/Entities/LinkedChild.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using MediaBrowser.Model.IO; using MediaBrowser.Model.Serialization; @@ -29,7 +30,7 @@ namespace MediaBrowser.Controller.Entities if (string.IsNullOrEmpty(child.Path)) { - child.LibraryItemId = item.Id.ToString("N"); + child.LibraryItemId = item.Id.ToString("N", CultureInfo.InvariantCulture); } return child; @@ -37,7 +38,7 @@ namespace MediaBrowser.Controller.Entities public LinkedChild() { - Id = Guid.NewGuid().ToString("N"); + Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); } } diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index eae834f6f0..1aacc13c9a 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -91,7 +92,7 @@ namespace MediaBrowser.Controller.Entities.TV } var folders = LibraryManager.GetCollectionFolders(this) - .Select(i => i.Id.ToString("N")) + .Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture)) .ToArray(); if (folders.Length == 0) diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs index 9952ba418b..968d725798 100644 --- a/MediaBrowser.Controller/Entities/User.cs +++ b/MediaBrowser.Controller/Entities/User.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -230,7 +231,7 @@ namespace MediaBrowser.Controller.Entities // TODO: Remove idPath and just use usernamePath for future releases var usernamePath = System.IO.Path.Combine(parentPath, username); - var idPath = System.IO.Path.Combine(parentPath, Id.ToString("N")); + var idPath = System.IO.Path.Combine(parentPath, Id.ToString("N", CultureInfo.InvariantCulture)); if (!Directory.Exists(usernamePath) && Directory.Exists(idPath)) { Directory.Move(idPath, usernamePath); diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index e483c8f349..454bdc4ae2 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.Movies; @@ -987,7 +988,7 @@ namespace MediaBrowser.Controller.Entities private UserView GetUserViewWithName(string name, string type, string sortName, BaseItem parent) { - return _userViewManager.GetUserSubView(parent.Id, parent.Id.ToString("N"), type, sortName); + return _userViewManager.GetUserSubView(parent.Id, parent.Id.ToString("N", CultureInfo.InvariantCulture), type, sortName); } private UserView GetUserView(string type, string localizationKey, string sortName, BaseItem parent) diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 55f47aae9b..351662b294 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -89,7 +89,7 @@ namespace MediaBrowser.Controller.LiveTv var info = new MediaSourceInfo { - Id = Id.ToString("N"), + Id = Id.ToString("N", CultureInfo.InvariantCulture), Protocol = PathProtocol ?? MediaProtocol.File, MediaStreams = new List(), Name = Name, @@ -111,7 +111,7 @@ namespace MediaBrowser.Controller.LiveTv protected override string GetInternalMetadataPath(string basePath) { - return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N"), "metadata"); + return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N", CultureInfo.InvariantCulture), "metadata"); } public override bool CanDelete() diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 8bde6a5da8..bdaf10d005 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; @@ -188,7 +189,7 @@ namespace MediaBrowser.Controller.LiveTv protected override string GetInternalMetadataPath(string basePath) { - return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N")); + return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N", CultureInfo.InvariantCulture)); } public override bool CanDelete() diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index e832607251..aff687f882 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -239,7 +240,7 @@ namespace MediaBrowser.Controller.Playlists return base.IsVisible(user); } - var userId = user.Id.ToString("N"); + var userId = user.Id.ToString("N", CultureInfo.InvariantCulture); foreach (var share in shares) { if (string.Equals(share.UserId, userId, StringComparison.OrdinalIgnoreCase)) diff --git a/MediaBrowser.Controller/Providers/MetadataResult.cs b/MediaBrowser.Controller/Providers/MetadataResult.cs index f4b915c06f..ebff81b7f8 100644 --- a/MediaBrowser.Controller/Providers/MetadataResult.cs +++ b/MediaBrowser.Controller/Providers/MetadataResult.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using MediaBrowser.Controller.Entities; namespace MediaBrowser.Controller.Providers @@ -55,7 +56,7 @@ namespace MediaBrowser.Controller.Providers foreach (var i in UserDataList) { - if (string.Equals(userId, i.UserId.ToString("N"), StringComparison.OrdinalIgnoreCase)) + if (string.Equals(userId, i.UserId.ToString("N", CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase)) { userData = i; } diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 860ea13cf6..a22eaaa514 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -934,7 +934,7 @@ namespace MediaBrowser.Providers.Manager public void OnRefreshStart(BaseItem item) { - //_logger.LogInformation("OnRefreshStart {0}", item.Id.ToString("N")); + //_logger.LogInformation("OnRefreshStart {0}", item.Id.ToString("N", CultureInfo.InvariantCulture)); var id = item.Id; lock (_activeRefreshes) @@ -947,7 +947,7 @@ namespace MediaBrowser.Providers.Manager public void OnRefreshComplete(BaseItem item) { - //_logger.LogInformation("OnRefreshComplete {0}", item.Id.ToString("N")); + //_logger.LogInformation("OnRefreshComplete {0}", item.Id.ToString("N", CultureInfo.InvariantCulture)); lock (_activeRefreshes) { _activeRefreshes.Remove(item.Id); @@ -971,7 +971,7 @@ namespace MediaBrowser.Providers.Manager public void OnRefreshProgress(BaseItem item, double progress) { - //_logger.LogInformation("OnRefreshProgress {0} {1}", item.Id.ToString("N"), progress); + //_logger.LogInformation("OnRefreshProgress {0} {1}", item.Id.ToString("N", CultureInfo.InvariantCulture), progress); var id = item.Id; lock (_activeRefreshes) @@ -985,7 +985,7 @@ namespace MediaBrowser.Providers.Manager else { // TODO: Need to hunt down the conditions for this happening - //throw new Exception(string.Format("Refresh for item {0} {1} is not in progress", item.GetType().Name, item.Id.ToString("N"))); + //throw new Exception(string.Format("Refresh for item {0} {1} is not in progress", item.GetType().Name, item.Id.ToString("N", CultureInfo.InvariantCulture))); } } } diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 61a8a122b9..7023ef706b 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -99,11 +100,11 @@ namespace MediaBrowser.Providers.MediaInfo if (!string.IsNullOrWhiteSpace(item.Album) && !string.IsNullOrWhiteSpace(albumArtist)) { - filename = (item.Album + "-" + albumArtist).GetMD5().ToString("N"); + filename = (item.Album + "-" + albumArtist).GetMD5().ToString("N", CultureInfo.InvariantCulture); } else { - filename = item.Id.ToString("N"); + filename = item.Id.ToString("N", CultureInfo.InvariantCulture); } filename += ".jpg"; @@ -111,7 +112,7 @@ namespace MediaBrowser.Providers.MediaInfo else { // If it's an audio book or audio podcast, allow unique image per item - filename = item.Id.ToString("N") + ".jpg"; + filename = item.Id.ToString("N", CultureInfo.InvariantCulture) + ".jpg"; } var prefix = filename.Substring(0, 1); diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs index 7fc6909f55..b4a4c36e54 100644 --- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs +++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs @@ -1,12 +1,11 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; -using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; @@ -296,7 +295,7 @@ namespace MediaBrowser.Providers.Subtitles private string GetProviderId(string name) { - return name.ToLowerInvariant().GetMD5().ToString("N"); + return name.ToLowerInvariant().GetMD5().ToString("N", CultureInfo.InvariantCulture); } private ISubtitleProvider GetProvider(string id) diff --git a/jellyfin.ruleset b/jellyfin.ruleset index 1249a60c05..e7e02a7d5b 100644 --- a/jellyfin.ruleset +++ b/jellyfin.ruleset @@ -27,6 +27,10 @@ + + -- cgit v1.2.3 From 25917db07a835bf0e5c6afdc0fec165851fffab2 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 9 Aug 2019 23:50:40 +0200 Subject: Fix doc releated warnings --- .../AppBase/BaseApplicationPaths.cs | 37 +++++---- .../AppBase/BaseConfigurationManager.cs | 92 ++++++++++++---------- Emby.Server.Implementations/ApplicationHost.cs | 6 +- .../ConfigurationOptions.cs | 4 +- .../Emby.Server.Implementations.csproj | 1 + .../ServerApplicationPaths.cs | 27 ++++--- 6 files changed, 91 insertions(+), 76 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs index 00cfa0c9a9..f67a09daa3 100644 --- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs +++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs @@ -10,6 +10,8 @@ namespace Emby.Server.Implementations.AppBase /// public abstract class BaseApplicationPaths : IApplicationPaths { + private string _dataPath; + /// /// Initializes a new instance of the class. /// @@ -30,27 +32,27 @@ namespace Emby.Server.Implementations.AppBase } /// - /// Gets the path to the program data folder + /// Gets the path to the program data folder. /// /// The program data path. - public string ProgramDataPath { get; private set; } + public string ProgramDataPath { get; } /// - /// Gets the path to the web UI resources folder + /// Gets the path to the web UI resources folder. /// /// The web UI resources path. - public string WebPath { get; set; } + public string WebPath { get; } /// - /// Gets the path to the system folder + /// Gets the path to the system folder. /// + /// The path to the system folder. public string ProgramSystemPath { get; } = AppContext.BaseDirectory; /// - /// Gets the folder path to the data directory + /// Gets the folder path to the data directory. /// /// The data directory. - private string _dataPath; public string DataPath { get => _dataPath; @@ -58,8 +60,9 @@ namespace Emby.Server.Implementations.AppBase } /// - /// Gets the magic strings used for virtual path manipulation. + /// Gets the magic string used for virtual path manipulation. /// + /// The magic string used for virtual path manipulation. public string VirtualDataPath { get; } = "%AppDataPath%"; /// @@ -69,43 +72,43 @@ namespace Emby.Server.Implementations.AppBase public string ImageCachePath => Path.Combine(CachePath, "images"); /// - /// Gets the path to the plugin directory + /// Gets the path to the plugin directory. /// /// The plugins path. public string PluginsPath => Path.Combine(ProgramDataPath, "plugins"); /// - /// Gets the path to the plugin configurations directory + /// Gets the path to the plugin configurations directory. /// /// The plugin configurations path. public string PluginConfigurationsPath => Path.Combine(PluginsPath, "configurations"); /// - /// Gets the path to the log directory + /// Gets the path to the log directory. /// /// The log directory path. - public string LogDirectoryPath { get; private set; } + public string LogDirectoryPath { get; } /// - /// Gets the path to the application configuration root directory + /// Gets the path to the application configuration root directory. /// /// The configuration directory path. - public string ConfigurationDirectoryPath { get; private set; } + public string ConfigurationDirectoryPath { get; } /// - /// Gets the path to the system configuration file + /// Gets the path to the system configuration file. /// /// The system configuration file path. public string SystemConfigurationFilePath => Path.Combine(ConfigurationDirectoryPath, "system.xml"); /// - /// Gets the folder path to the cache directory + /// Gets or sets the folder path to the cache directory. /// /// The cache directory. public string CachePath { get; set; } /// - /// Gets the folder path to the temp directory within the cache folder + /// Gets the folder path to the temp directory within the cache folder. /// /// The temp directory. public string TempDirectory => Path.Combine(CachePath, "temp"); diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs index af60a8dce4..4832c19c4e 100644 --- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs +++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -19,11 +20,44 @@ namespace Emby.Server.Implementations.AppBase /// public abstract class BaseConfigurationManager : IConfigurationManager { + private readonly IFileSystem _fileSystem; + + private readonly ConcurrentDictionary _configurations = new ConcurrentDictionary(); + + private ConfigurationStore[] _configurationStores = Array.Empty(); + private IConfigurationFactory[] _configurationFactories = Array.Empty(); + /// - /// Gets the type of the configuration. + /// The _configuration loaded. /// - /// The type of the configuration. - protected abstract Type ConfigurationType { get; } + private bool _configurationLoaded; + + /// + /// The _configuration sync lock. + /// + private object _configurationSyncLock = new object(); + + /// + /// The _configuration. + /// + private BaseApplicationConfiguration _configuration; + + /// + /// Initializes a new instance of the class. + /// + /// The application paths. + /// The logger factory. + /// The XML serializer. + /// The file system + protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILoggerFactory loggerFactory, IXmlSerializer xmlSerializer, IFileSystem fileSystem) + { + CommonApplicationPaths = applicationPaths; + XmlSerializer = xmlSerializer; + _fileSystem = fileSystem; + Logger = loggerFactory.CreateLogger(GetType().Name); + + UpdateCachePath(); + } /// /// Occurs when [configuration updated]. @@ -40,6 +74,12 @@ namespace Emby.Server.Implementations.AppBase /// public event EventHandler NamedConfigurationUpdated; + /// + /// Gets the type of the configuration. + /// + /// The type of the configuration. + protected abstract Type ConfigurationType { get; } + /// /// Gets the logger. /// @@ -56,20 +96,7 @@ namespace Emby.Server.Implementations.AppBase /// /// The application paths. public IApplicationPaths CommonApplicationPaths { get; private set; } - public readonly IFileSystem FileSystem; - /// - /// The _configuration loaded - /// - private bool _configurationLoaded; - /// - /// The _configuration sync lock - /// - private object _configurationSyncLock = new object(); - /// - /// The _configuration - /// - private BaseApplicationConfiguration _configuration; /// /// Gets the system configuration /// @@ -90,26 +117,6 @@ namespace Emby.Server.Implementations.AppBase } } - private ConfigurationStore[] _configurationStores = { }; - private IConfigurationFactory[] _configurationFactories = { }; - - /// - /// Initializes a new instance of the class. - /// - /// The application paths. - /// The logger factory. - /// The XML serializer. - /// The file system - protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILoggerFactory loggerFactory, IXmlSerializer xmlSerializer, IFileSystem fileSystem) - { - CommonApplicationPaths = applicationPaths; - XmlSerializer = xmlSerializer; - FileSystem = fileSystem; - Logger = loggerFactory.CreateLogger(GetType().Name); - - UpdateCachePath(); - } - public virtual void AddParts(IEnumerable factories) { _configurationFactories = factories.ToArray(); @@ -171,6 +178,7 @@ namespace Emby.Server.Implementations.AppBase private void UpdateCachePath() { string cachePath; + // If the configuration file has no entry (i.e. not set in UI) if (string.IsNullOrWhiteSpace(CommonConfiguration.CachePath)) { @@ -207,12 +215,16 @@ namespace Emby.Server.Implementations.AppBase var newPath = newConfig.CachePath; if (!string.IsNullOrWhiteSpace(newPath) - && !string.Equals(CommonConfiguration.CachePath ?? string.Empty, newPath)) + && !string.Equals(CommonConfiguration.CachePath ?? string.Empty, newPath, StringComparison.Ordinal)) { // Validate if (!Directory.Exists(newPath)) { - throw new FileNotFoundException(string.Format("{0} does not exist.", newPath)); + throw new FileNotFoundException( + string.Format( + CultureInfo.InvariantCulture, + "{0} does not exist.", + newPath)); } EnsureWriteAccess(newPath); @@ -223,11 +235,9 @@ namespace Emby.Server.Implementations.AppBase { var file = Path.Combine(path, Guid.NewGuid().ToString()); File.WriteAllText(file, string.Empty); - FileSystem.DeleteFile(file); + _fileSystem.DeleteFile(file); } - private readonly ConcurrentDictionary _configurations = new ConcurrentDictionary(); - private string GetConfigurationFile(string key) { return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLowerInvariant() + ".xml"); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index f0aa60428b..0493fd9f5a 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -418,7 +418,7 @@ namespace Emby.Server.Implementations public string ApplicationVersion { get; } = typeof(ApplicationHost).Assembly.GetName().Version.ToString(3); /// - /// Gets the current application user agent + /// Gets the current application user agent. /// /// The application user agent. public string ApplicationUserAgent => Name.Replace(' ', '-') + "/" + ApplicationVersion; @@ -467,8 +467,8 @@ namespace Emby.Server.Implementations /// /// Creates an instance of type and resolves all constructor dependencies /// - /// /// The type - /// T + /// /// The type. + /// T. public T CreateInstance() => ActivatorUtilities.CreateInstance(_serviceProvider); diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index 9bc60972a1..62408ee703 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -6,8 +6,8 @@ namespace Emby.Server.Implementations { public static readonly Dictionary Configuration = new Dictionary { - {"HttpListenerHost:DefaultRedirectPath", "web/index.html"}, - {"MusicBrainz:BaseUrl", "https://www.musicbrainz.org"} + { "HttpListenerHost:DefaultRedirectPath", "web/index.html" }, + { "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" } }; } } diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index abbaef26b8..f07f8e3bfd 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -44,6 +44,7 @@ netstandard2.0 false + true diff --git a/Emby.Server.Implementations/ServerApplicationPaths.cs b/Emby.Server.Implementations/ServerApplicationPaths.cs index adaf23234f..2f5a8af802 100644 --- a/Emby.Server.Implementations/ServerApplicationPaths.cs +++ b/Emby.Server.Implementations/ServerApplicationPaths.cs @@ -10,8 +10,12 @@ namespace Emby.Server.Implementations /// public class ServerApplicationPaths : BaseApplicationPaths, IServerApplicationPaths { + private string _defaultTranscodingTempPath; + private string _transcodingTempPath; + private string _internalMetadataPath; + /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public ServerApplicationPaths( string programDataPath, @@ -30,7 +34,7 @@ namespace Emby.Server.Implementations public string ApplicationResourcesPath { get; } = AppContext.BaseDirectory; /// - /// Gets the path to the base root media directory + /// Gets the path to the base root media directory. /// /// The root folder path. public string RootFolderPath => Path.Combine(ProgramDataPath, "root"); @@ -48,7 +52,7 @@ namespace Emby.Server.Implementations public string LocalizationPath => Path.Combine(ProgramDataPath, "localization"); /// - /// Gets the path to the People directory + /// Gets the path to the People directory. /// /// The people path. public string PeoplePath => Path.Combine(InternalMetadataPath, "People"); @@ -56,37 +60,37 @@ namespace Emby.Server.Implementations public string ArtistsPath => Path.Combine(InternalMetadataPath, "artists"); /// - /// Gets the path to the Genre directory + /// Gets the path to the Genre directory. /// /// The genre path. public string GenrePath => Path.Combine(InternalMetadataPath, "Genre"); /// - /// Gets the path to the Genre directory + /// Gets the path to the Genre directory. /// /// The genre path. public string MusicGenrePath => Path.Combine(InternalMetadataPath, "MusicGenre"); /// - /// Gets the path to the Studio directory + /// Gets the path to the Studio directory. /// /// The studio path. public string StudioPath => Path.Combine(InternalMetadataPath, "Studio"); /// - /// Gets the path to the Year directory + /// Gets the path to the Year directory. /// /// The year path. public string YearPath => Path.Combine(InternalMetadataPath, "Year"); /// - /// Gets the path to the General IBN directory + /// Gets the path to the General IBN directory. /// /// The general path. public string GeneralPath => Path.Combine(InternalMetadataPath, "general"); /// - /// Gets the path to the Ratings IBN directory + /// Gets the path to the Ratings IBN directory. /// /// The ratings path. public string RatingsPath => Path.Combine(InternalMetadataPath, "ratings"); @@ -98,15 +102,13 @@ namespace Emby.Server.Implementations public string MediaInfoImagesPath => Path.Combine(InternalMetadataPath, "mediainfo"); /// - /// Gets the path to the user configuration directory + /// Gets the path to the user configuration directory. /// /// The user configuration directory path. public string UserConfigurationDirectoryPath => Path.Combine(ConfigurationDirectoryPath, "users"); - private string _defaultTranscodingTempPath; public string DefaultTranscodingTempPath => _defaultTranscodingTempPath ?? (_defaultTranscodingTempPath = Path.Combine(ProgramDataPath, "transcoding-temp")); - private string _transcodingTempPath; public string TranscodingTempPath { get => _transcodingTempPath ?? (_transcodingTempPath = DefaultTranscodingTempPath); @@ -139,7 +141,6 @@ namespace Emby.Server.Implementations return path; } - private string _internalMetadataPath; public string InternalMetadataPath { get => _internalMetadataPath ?? (_internalMetadataPath = Path.Combine(DataPath, "metadata")); -- cgit v1.2.3