From c6188e26afa0034c5c255a19b2fc71aa42311e26 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Mon, 18 Feb 2019 22:47:02 +0100 Subject: Got to start somewhere --- Emby.Server.Implementations/ApplicationHost.cs | 43 +++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 7d77500ab..1b88fae0e 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -181,11 +181,17 @@ namespace Emby.Server.Implementations /// The logger. protected ILogger Logger { get; set; } + private IPlugin[] _plugins; + /// /// Gets or sets the plugins. /// /// The plugins. - public IPlugin[] Plugins { get; protected set; } + public IPlugin[] Plugins + { + get => _plugins; + protected set => _plugins = value; + } /// /// Gets or sets the logger factory. @@ -1047,6 +1053,41 @@ namespace Emby.Server.Implementations CollectionFolder.JsonSerializer = JsonSerializer; CollectionFolder.ApplicationHost = this; AuthenticatedAttribute.AuthService = AuthService; + + InstallationManager.PluginInstalled += PluginInstalled; + } + + private async void PluginInstalled(object sender, GenericEventArgs args) + { + string dir = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(args.Argument.targetFilename)); + var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.TopDirectoryOnly) + .Select(x => Assembly.LoadFrom(x)) + .SelectMany(x => x.ExportedTypes) + .Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface && !x.IsGenericType) + .ToList(); + + types.AddRange(types); + + var plugins = types.Where(x => x.IsAssignableFrom(typeof(IPlugin))) + .Select(CreateInstanceSafe) + .Where(x => x != null) + .Cast() + .Select(LoadPlugin) + .Where(x => x != null) + .ToArray(); + + int oldLen = _plugins.Length; + Array.Resize(ref _plugins, _plugins.Length + plugins.Length); + plugins.CopyTo(_plugins, oldLen); + + var entries = types.Where(x => x.IsAssignableFrom(typeof(IServerEntryPoint))) + .Select(CreateInstanceSafe) + .Where(x => x != null) + .Cast() + .ToList(); + + await Task.WhenAll(StartEntryPoints(entries, true)); + await Task.WhenAll(StartEntryPoints(entries, false)); } /// -- cgit v1.2.3 From 7f42dcc60fd3aaf30f2408f6bddeb2b8bf921cdf Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 8 Mar 2019 20:32:14 +0100 Subject: Remove more unused stuff --- Emby.Server.Implementations/ApplicationHost.cs | 11 +++++------ .../HttpClientManager/HttpClientManager.cs | 18 ------------------ .../LiveTv/Listings/SchedulesDirect.cs | 10 +--------- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 -- .../LiveTv/TunerHosts/SharedHttpStream.cs | 6 ------ MediaBrowser.Common/Net/HttpRequestOptions.cs | 21 +-------------------- 6 files changed, 7 insertions(+), 61 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index f7d9bad1b..2f396f814 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Net; +using System.Net.Http; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; @@ -34,7 +35,6 @@ using Emby.Server.Implementations.IO; using Emby.Server.Implementations.Library; using Emby.Server.Implementations.LiveTv; using Emby.Server.Implementations.Localization; -using Emby.Server.Implementations.Middleware; using Emby.Server.Implementations.Net; using Emby.Server.Implementations.Playlists; using Emby.Server.Implementations.Reflection; @@ -1479,12 +1479,12 @@ namespace Emby.Server.Implementations LogErrorResponseBody = false, LogErrors = false, LogRequest = false, - TimeoutMs = 10000, BufferContent = false, CancellationToken = cancellationToken })) { - return GetLocalApiUrl(response.ReadToEnd().Trim()); + string res = await response.ReadToEndAsync().ConfigureAwait(false); + return GetLocalApiUrl(res.Trim()); } } catch (Exception ex) @@ -1604,16 +1604,15 @@ namespace Emby.Server.Implementations LogErrorResponseBody = false, LogErrors = logPing, LogRequest = logPing, - TimeoutMs = 5000, BufferContent = false, CancellationToken = cancellationToken - }, "POST").ConfigureAwait(false)) + }, HttpMethod.Post).ConfigureAwait(false)) { using (var reader = new StreamReader(response.Content)) { - var result = reader.ReadToEnd(); + var result = await reader.ReadToEndAsync().ConfigureAwait(false); var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase); _validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid); diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs index 581d6bafd..b82d55d0e 100644 --- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs @@ -352,11 +352,6 @@ namespace Emby.Server.Implementations.HttpClientManager } } - if (options.ResourcePool != null) - { - await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false); - } - if (options.LogRequest) { _logger.LogDebug("HttpClientManager {0}: {1}", httpMethod.ToString(), options.Url); @@ -397,10 +392,6 @@ namespace Emby.Server.Implementations.HttpClientManager { throw GetCancellationException(options, options.CancellationToken, ex); } - finally - { - options.ResourcePool?.Release(); - } } private HttpResponseInfo GetResponseInfo(HttpResponseMessage httpResponse, Stream content, long? contentLength, IDisposable disposable) @@ -483,11 +474,6 @@ namespace Emby.Server.Implementations.HttpClientManager var httpWebRequest = GetRequestMessage(options, HttpMethod.Get); - if (options.ResourcePool != null) - { - await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false); - } - options.Progress.Report(0); if (options.LogRequest) @@ -528,10 +514,6 @@ namespace Emby.Server.Implementations.HttpClientManager throw GetException(ex, options); } - finally - { - options.ResourcePool?.Release(); - } } private Exception GetException(Exception ex, HttpRequestOptions options) diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 4137760d0..f3f747718 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -96,8 +96,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings Url = ApiUrl + "/schedules", UserAgent = UserAgent, CancellationToken = cancellationToken, - // The data can be large so give it some extra time - TimeoutMs = 60000, LogErrorResponseBody = true, RequestContent = requestString }; @@ -115,9 +113,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings Url = ApiUrl + "/programs", UserAgent = UserAgent, CancellationToken = cancellationToken, - LogErrorResponseBody = true, - // The data can be large so give it some extra time - TimeoutMs = 60000 + LogErrorResponseBody = true }; httpOptions.RequestHeaders["token"] = token; @@ -483,8 +479,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings CancellationToken = cancellationToken, RequestContent = imageIdString, LogErrorResponseBody = true, - // The data can be large so give it some extra time - TimeoutMs = 60000 }; try @@ -871,8 +865,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings UserAgent = UserAgent, CancellationToken = cancellationToken, LogErrorResponseBody = true, - // The data can be large so give it some extra time - TimeoutMs = 60000 }; httpOptions.RequestHeaders["token"] = token; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 24b100edd..761275f8f 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -138,7 +138,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Url = string.Format("{0}/discover.json", GetApiUrl(info)), CancellationToken = cancellationToken, - TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(10).TotalMilliseconds), BufferContent = false }, "GET").ConfigureAwait(false)) @@ -191,7 +190,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Url = string.Format("{0}/tuners.html", GetApiUrl(info)), CancellationToken = cancellationToken, - TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds), BufferContent = false })) { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index d74cf3be2..e8b34da0c 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -47,13 +47,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts CancellationToken = CancellationToken.None, BufferContent = false, - // Increase a little bit - TimeoutMs = 30000, - EnableHttpCompression = false, - - LogResponse = true, - LogResponseHeaders = true }; foreach (var header in mediaSource.RequiredHttpHeaders) diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs index 874383fed..38e0ff0f5 100644 --- a/MediaBrowser.Common/Net/HttpRequestOptions.cs +++ b/MediaBrowser.Common/Net/HttpRequestOptions.cs @@ -28,18 +28,13 @@ namespace MediaBrowser.Common.Net get => GetHeaderValue(HeaderNames.Accept); set => RequestHeaders[HeaderNames.Accept] = value; } + /// /// Gets or sets the cancellation token. /// /// The cancellation token. public CancellationToken CancellationToken { get; set; } - /// - /// Gets or sets the resource pool. - /// - /// The resource pool. - public SemaphoreSlim ResourcePool { get; set; } - /// /// Gets or sets the user agent. /// @@ -86,8 +81,6 @@ namespace MediaBrowser.Common.Net public bool LogRequest { get; set; } public bool LogRequestAsDebug { get; set; } public bool LogErrors { get; set; } - public bool LogResponse { get; set; } - public bool LogResponseHeaders { get; set; } public bool LogErrorResponseBody { get; set; } public bool EnableKeepAlive { get; set; } @@ -95,7 +88,6 @@ namespace MediaBrowser.Common.Net public CacheMode CacheMode { get; set; } public TimeSpan CacheLength { get; set; } - public int TimeoutMs { get; set; } public bool EnableDefaultUserAgent { get; set; } public bool AppendCharsetToMimeType { get; set; } @@ -119,17 +111,6 @@ namespace MediaBrowser.Common.Net LogRequest = true; LogErrors = true; CacheMode = CacheMode.None; - - TimeoutMs = 20000; - } - - public void SetPostData(IDictionary values) - { - var strings = values.Keys.Select(key => string.Format("{0}={1}", key, values[key])); - var postContent = string.Join("&", strings.ToArray()); - - RequestContent = postContent; - RequestContentType = "application/x-www-form-urlencoded"; } } -- cgit v1.2.3 From 09921a00aaad31c0ea4a0650e8d0ddb890dca735 Mon Sep 17 00:00:00 2001 From: Phallacy Date: Fri, 22 Mar 2019 00:01:23 -0700 Subject: made password resets an interface and per user --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Library/DefaultPasswordResetProvider.cs | 118 +++++++++++++ Emby.Server.Implementations/Library/UserManager.cs | 192 +++++++-------------- MediaBrowser.Api/Session/SessionsService.cs | 11 ++ .../Authentication/IPasswordResetProvider.cs | 20 +++ MediaBrowser.Controller/Library/IUserManager.cs | 3 +- MediaBrowser.Model/Users/UserPolicy.cs | 1 + 7 files changed, 220 insertions(+), 127 deletions(-) create mode 100644 Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs create mode 100644 MediaBrowser.Controller/Authentication/IPasswordResetProvider.cs (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 484942946..fc1b2eda8 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1088,7 +1088,7 @@ namespace Emby.Server.Implementations MediaSourceManager.AddParts(GetExports()); NotificationManager.AddParts(GetExports(), GetExports()); - UserManager.AddParts(GetExports()); + UserManager.AddParts(GetExports(), GetExports()); IsoManager.AddParts(GetExports()); } diff --git a/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs b/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs new file mode 100644 index 000000000..ae6fe8239 --- /dev/null +++ b/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Authentication; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Users; +using ServiceStack; +using TvDbSharper.Dto; + +namespace Emby.Server.Implementations.Library +{ + public class DefaultPasswordResetProvider : IPasswordResetProvider + { + public string Name => "Default Password Reset Provider"; + + public bool IsEnabled => true; + + private readonly string _passwordResetFileBase; + private readonly string _passwordResetFileBaseDir; + private readonly string _passwordResetFileBaseName = "passwordreset"; + + private IJsonSerializer _jsonSerializer; + private IUserManager _userManager; + + public DefaultPasswordResetProvider(IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IUserManager userManager) + { + _passwordResetFileBaseDir = configurationManager.ApplicationPaths.ProgramDataPath; + _passwordResetFileBase = Path.Combine(_passwordResetFileBaseDir, _passwordResetFileBaseName); + _jsonSerializer = jsonSerializer; + _userManager = userManager; + } + + public async Task RedeemPasswordResetPin(string pin) + { + HashSet usersreset = new HashSet(); + foreach (var resetfile in Directory.EnumerateFiles(_passwordResetFileBaseDir, $"{_passwordResetFileBaseName}*")) + { + var spr = (SerializablePasswordReset) _jsonSerializer.DeserializeFromFile(typeof(SerializablePasswordReset), resetfile); + if (spr.ExpirationDate > DateTime.Now) + { + File.Delete(resetfile); + } + else + { + if (spr.Pin == pin) + { + var resetUser = _userManager.GetUserByName(spr.UserName); + if (!string.IsNullOrEmpty(resetUser.Password)) + { + await _userManager.ChangePassword(resetUser, pin).ConfigureAwait(false); + usersreset.Add(resetUser.Name); + } + } + } + } + + if (usersreset.Count < 1) + { + throw new ResourceNotFoundException($"No Users found with a password reset request matching pin {pin}"); + } + else + { + return new PinRedeemResult + { + Success = true, + UsersReset = usersreset.ToArray() + }; + } + throw new System.NotImplementedException(); + } + + public async Task StartForgotPasswordProcess(MediaBrowser.Controller.Entities.User user, bool isInNetwork) + { + string pin = new Random().Next(99999999).ToString("00000000",CultureInfo.InvariantCulture); + DateTime expireTime = DateTime.Now.AddMinutes(30); + string filePath = _passwordResetFileBase + user.Name.ToLowerInvariant() + ".json"; + SerializablePasswordReset spr = new SerializablePasswordReset + { + ExpirationDate = expireTime, + Pin = pin, + PinFile = filePath, + UserName = user.Name + }; + + try + { + await Task.Run(() => File.WriteAllText(filePath, _jsonSerializer.SerializeToString(spr))).ConfigureAwait(false); + } + catch (Exception e) + { + throw new Exception($"Error serializing or writing password reset for {user.Name} to location:{filePath}", e); + } + + return new ForgotPasswordResult + { + Action = ForgotPasswordAction.PinCode, + PinExpirationDate = expireTime, + PinFile = filePath + }; + } + + private class SerializablePasswordReset : PasswordPinCreationResult + { + public string Pin { get; set; } + + public string UserName { get; set; } + } + } +} diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 4cf703add..500bb8d66 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -79,6 +79,10 @@ namespace Emby.Server.Implementations.Library private IAuthenticationProvider[] _authenticationProviders; private DefaultAuthenticationProvider _defaultAuthenticationProvider; + private IPasswordResetProvider[] _passwordResetProviders; + private DefaultPasswordResetProvider _defaultPasswordResetProvider; + private Dictionary _activeResets = new Dictionary(); + public UserManager( ILoggerFactory loggerFactory, IServerConfigurationManager configurationManager, @@ -102,8 +106,6 @@ namespace Emby.Server.Implementations.Library _fileSystem = fileSystem; ConfigurationManager = configurationManager; _users = Array.Empty(); - - DeletePinFile(); } public NameIdPair[] GetAuthenticationProviders() @@ -120,11 +122,29 @@ namespace Emby.Server.Implementations.Library .ToArray(); } - public void AddParts(IEnumerable authenticationProviders) + public NameIdPair[] GetPasswordResetProviders() + { + return _passwordResetProviders + .Where(i => i.IsEnabled) + .OrderBy(i => i is DefaultPasswordResetProvider ? 0 : 1) + .ThenBy(i => i.Name) + .Select(i => new NameIdPair + { + Name = i.Name, + Id = GetPasswordResetProviderId(i) + }) + .ToArray(); + } + + public void AddParts(IEnumerable authenticationProviders,IEnumerable passwordResetProviders) { _authenticationProviders = authenticationProviders.ToArray(); _defaultAuthenticationProvider = _authenticationProviders.OfType().First(); + + _passwordResetProviders = passwordResetProviders.ToArray(); + + _defaultPasswordResetProvider = passwordResetProviders.OfType().First(); } #region UserUpdated Event @@ -342,11 +362,21 @@ namespace Emby.Server.Implementations.Library return provider.GetType().FullName; } + private static string GetPasswordResetProviderId(IPasswordResetProvider provider) + { + return provider.GetType().FullName; + } + private IAuthenticationProvider GetAuthenticationProvider(User user) { return GetAuthenticationProviders(user).First(); } + private IPasswordResetProvider GetPasswordResetProvider(User user) + { + return GetPasswordResetProviders(user).First(); + } + private IAuthenticationProvider[] GetAuthenticationProviders(User user) { var authenticationProviderId = user == null ? null : user.Policy.AuthenticationProviderId; @@ -366,6 +396,25 @@ namespace Emby.Server.Implementations.Library return providers; } + private IPasswordResetProvider[] GetPasswordResetProviders(User user) + { + var passwordResetProviderId = user == null ? null : user.Policy.PasswordResetProviderId; + + var providers = _passwordResetProviders.Where(i => i.IsEnabled).ToArray(); + + if (!string.IsNullOrEmpty(passwordResetProviderId)) + { + providers = providers.Where(i => string.Equals(passwordResetProviderId, GetPasswordResetProviderId(i), StringComparison.OrdinalIgnoreCase)).ToArray(); + } + + if (providers.Length == 0) + { + providers = new IPasswordResetProvider[] { _defaultPasswordResetProvider }; + } + + return providers; + } + private async Task AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser) { try @@ -844,159 +893,52 @@ namespace Emby.Server.Implementations.Library Id = Guid.NewGuid(), DateCreated = DateTime.UtcNow, DateModified = DateTime.UtcNow, - UsesIdForConfigurationPath = true, - //Salt = BCrypt.GenerateSalt() - }; - } - - private string PasswordResetFile => Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "passwordreset.txt"); - - private string _lastPin; - private PasswordPinCreationResult _lastPasswordPinCreationResult; - private int _pinAttempts; - - private async Task CreatePasswordResetPin() - { - var num = new Random().Next(1, 9999); - - var path = PasswordResetFile; - - var pin = num.ToString("0000", CultureInfo.InvariantCulture); - _lastPin = pin; - - var time = TimeSpan.FromMinutes(5); - var expiration = DateTime.UtcNow.Add(time); - - var text = new StringBuilder(); - - var localAddress = (await _appHost.GetLocalApiUrl(CancellationToken.None).ConfigureAwait(false)) ?? string.Empty; - - text.AppendLine("Use your web browser to visit:"); - text.AppendLine(string.Empty); - text.AppendLine(localAddress + "/web/index.html#!/forgotpasswordpin.html"); - text.AppendLine(string.Empty); - text.AppendLine("Enter the following pin code:"); - text.AppendLine(string.Empty); - text.AppendLine(pin); - text.AppendLine(string.Empty); - - var localExpirationTime = expiration.ToLocalTime(); - // Tuesday, 22 August 2006 06:30 AM - text.AppendLine("The pin code will expire at " + localExpirationTime.ToString("f1", CultureInfo.CurrentCulture)); - - File.WriteAllText(path, text.ToString(), Encoding.UTF8); - - var result = new PasswordPinCreationResult - { - PinFile = path, - ExpirationDate = expiration + UsesIdForConfigurationPath = true }; - - _lastPasswordPinCreationResult = result; - _pinAttempts = 0; - - return result; } public async Task StartForgotPasswordProcess(string enteredUsername, bool isInNetwork) { - DeletePinFile(); - var user = string.IsNullOrWhiteSpace(enteredUsername) ? null : GetUserByName(enteredUsername); var action = ForgotPasswordAction.InNetworkRequired; - string pinFile = null; - DateTime? expirationDate = null; - if (user != null && !user.Policy.IsAdministrator) + if (user != null && isInNetwork) { - action = ForgotPasswordAction.ContactAdmin; + var passwordResetProvider = GetPasswordResetProvider(user); + _activeResets.Add(user.Name, passwordResetProvider); + return await passwordResetProvider.StartForgotPasswordProcess(user, isInNetwork).ConfigureAwait(false); } else { - if (isInNetwork) + return new ForgotPasswordResult { - action = ForgotPasswordAction.PinCode; - } - - var result = await CreatePasswordResetPin().ConfigureAwait(false); - pinFile = result.PinFile; - expirationDate = result.ExpirationDate; + Action = action, + PinFile = string.Empty + }; } - - return new ForgotPasswordResult - { - Action = action, - PinFile = pinFile, - PinExpirationDate = expirationDate - }; } public async Task RedeemPasswordResetPin(string pin) { - DeletePinFile(); - - var usersReset = new List(); - - var valid = !string.IsNullOrWhiteSpace(_lastPin) && - string.Equals(_lastPin, pin, StringComparison.OrdinalIgnoreCase) && - _lastPasswordPinCreationResult != null && - _lastPasswordPinCreationResult.ExpirationDate > DateTime.UtcNow; - - if (valid) + foreach (var provider in _passwordResetProviders) { - _lastPin = null; - _lastPasswordPinCreationResult = null; - - foreach (var user in Users) + var result = await provider.RedeemPasswordResetPin(pin).ConfigureAwait(false); + if (result.Success) { - await ResetPassword(user).ConfigureAwait(false); - - if (user.Policy.IsDisabled) - { - user.Policy.IsDisabled = false; - UpdateUserPolicy(user, user.Policy, true); - } - usersReset.Add(user.Name); - } - } - else - { - _pinAttempts++; - if (_pinAttempts >= 3) - { - _lastPin = null; - _lastPasswordPinCreationResult = null; + return result; } } return new PinRedeemResult { - Success = valid, - UsersReset = usersReset.ToArray() + Success = false, + UsersReset = Array.Empty() }; } - private void DeletePinFile() - { - try - { - _fileSystem.DeleteFile(PasswordResetFile); - } - catch - { - - } - } - - class PasswordPinCreationResult - { - public string PinFile { get; set; } - public DateTime ExpirationDate { get; set; } - } - public UserPolicy GetUserPolicy(User user) { var path = GetPolicyFilePath(user); diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index f011e6e41..4109b12bf 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -245,6 +245,12 @@ namespace MediaBrowser.Api.Session { } + [Route("/Auth/PasswordResetProviders", "GET")] + [Authenticated(Roles = "Admin")] + public class GetPasswordResetProviders : IReturn + { + } + [Route("/Auth/Keys/{Key}", "DELETE")] [Authenticated(Roles = "Admin")] public class RevokeKey @@ -294,6 +300,11 @@ namespace MediaBrowser.Api.Session return _userManager.GetAuthenticationProviders(); } + public object Get(GetPasswordResetProviders request) + { + return _userManager.GetPasswordResetProviders(); + } + public void Delete(RevokeKey request) { _sessionManager.RevokeToken(request.Key); diff --git a/MediaBrowser.Controller/Authentication/IPasswordResetProvider.cs b/MediaBrowser.Controller/Authentication/IPasswordResetProvider.cs new file mode 100644 index 000000000..9e5cd8816 --- /dev/null +++ b/MediaBrowser.Controller/Authentication/IPasswordResetProvider.cs @@ -0,0 +1,20 @@ +using System; +using System.Threading.Tasks; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Users; + +namespace MediaBrowser.Controller.Authentication +{ + public interface IPasswordResetProvider + { + string Name { get; } + bool IsEnabled { get; } + Task StartForgotPasswordProcess(User user, bool isInNetwork); + Task RedeemPasswordResetPin(string pin); + } + public class PasswordPinCreationResult + { + public string PinFile { get; set; } + public DateTime ExpirationDate { get; set; } + } +} diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index 925d91a37..7f7370893 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -200,8 +200,9 @@ namespace MediaBrowser.Controller.Library /// System.String. string MakeValidUsername(string username); - void AddParts(IEnumerable authenticationProviders); + void AddParts(IEnumerable authenticationProviders, IEnumerable passwordResetProviders); NameIdPair[] GetAuthenticationProviders(); + NameIdPair[] GetPasswordResetProviders(); } } diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 5415fd5e8..f63ab2bb4 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -75,6 +75,7 @@ namespace MediaBrowser.Model.Users public int RemoteClientBitrateLimit { get; set; } public string AuthenticationProviderId { get; set; } + public string PasswordResetProviderId { get; set; } public UserPolicy() { -- cgit v1.2.3 From 414a318a0d422a893401d1ecf84526043df36210 Mon Sep 17 00:00:00 2001 From: Phlogi Date: Sun, 24 Mar 2019 11:59:40 +0100 Subject: WAN Address should use public ports instead of local ports. https://github.com/jellyfin/jellyfin/issues/601#issuecomment-475941080 --- Emby.Server.Implementations/ApplicationHost.cs | 39 ++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 484942946..5f4c30f0f 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1476,7 +1476,7 @@ namespace Emby.Server.Implementations CancellationToken = cancellationToken }).ConfigureAwait(false)) { - return GetLocalApiUrl(response.ReadToEnd().Trim()); + return GetWanApiUrl(response.ReadToEnd().Trim()); } } catch (Exception ex) @@ -1493,16 +1493,45 @@ namespace Emby.Server.Implementations return GetLocalApiUrl("[" + ipAddress.Address + "]"); } - return GetLocalApiUrl(ipAddress.Address); + return GetLocalApiUrlWithPort(ipAddress.Address); } - public string GetLocalApiUrl(string host) + public string GetLocalApiUrlWithPort(string host) { + if (EnableHttps) + { + return string.Format("http://{0}:{1}", + host, + HttpsPort.ToString(CultureInfo.InvariantCulture)); + } return string.Format("http://{0}:{1}", - host, - HttpPort.ToString(CultureInfo.InvariantCulture)); + host, + HttpPort.ToString(CultureInfo.InvariantCulture)); } + public string GetWanApiUrl(IpAddressInfo ipAddress) + { + if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) + { + return GetLocalApiUrl("[" + ipAddress.Address + "]"); + } + + return GetWanApiUrlWithPort(ipAddress.Address); + } + + public string GetWanApiUrlWithPort(string host) + { + if (EnableHttps) + { + return string.Format("http://{0}:{1}", + host, + ServerConfiguration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture)); + } + return string.Format("http://{0}:{1}", + host, + ServerConfiguration.PublicPort.ToString(CultureInfo.InvariantCulture)); + } + public Task> GetLocalIpAddresses(CancellationToken cancellationToken) { return GetLocalIpAddressesInternal(true, 0, cancellationToken); -- cgit v1.2.3 From 69cc5814d85733f5bec9cac03e78caa1324406fe Mon Sep 17 00:00:00 2001 From: Phlogi Date: Sun, 24 Mar 2019 12:11:46 +0100 Subject: Change WAN IP behaviour: Use ServerConfiguration.WanDdns if set in configuration. --- Emby.Server.Implementations/ApplicationHost.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 5f4c30f0f..7e236002a 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1372,7 +1372,15 @@ namespace Emby.Server.Implementations public async Task GetSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); + + if ( String.IsNullOrEmpty(ServerConfiguration.WanDdns) ){ + var wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); + } else { + // Use the (dynmic) domain name set in the configuration if available instead of querying + // an external service to get the IP address + // The domain resolution to the ip should be part of the client, not the server. + var wanAddress = ServerConfiguration.WanDdns; + } return new SystemInfo { -- cgit v1.2.3 From 4ffec8ad260fb8829ea220137934596de19a1c1b Mon Sep 17 00:00:00 2001 From: Phlogi Date: Sun, 24 Mar 2019 12:19:10 +0100 Subject: Fix build, missing changes. --- Emby.Server.Implementations/ApplicationHost.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 7e236002a..1ea9c599b 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1498,7 +1498,7 @@ namespace Emby.Server.Implementations { if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) { - return GetLocalApiUrl("[" + ipAddress.Address + "]"); + return GetLocalApiUrlWithPort("[" + ipAddress.Address + "]"); } return GetLocalApiUrlWithPort(ipAddress.Address); @@ -1521,7 +1521,7 @@ namespace Emby.Server.Implementations { if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) { - return GetLocalApiUrl("[" + ipAddress.Address + "]"); + return GetWanApiUrlWithPort("[" + ipAddress.Address + "]"); } return GetWanApiUrlWithPort(ipAddress.Address); -- cgit v1.2.3 From f30af9cd5f484dad763eb67b5b7076cd03bd59df Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Sun, 24 Mar 2019 16:47:42 +0100 Subject: Update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Phlogi --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 1ea9c599b..1ecbeedad 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1373,7 +1373,7 @@ namespace Emby.Server.Implementations { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - if ( String.IsNullOrEmpty(ServerConfiguration.WanDdns) ){ + if (string.IsNullOrEmpty(ServerConfiguration.WanDdns)){ var wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); } else { // Use the (dynmic) domain name set in the configuration if available instead of querying -- cgit v1.2.3 From cf36aaef2b1724931b94bf12b95d2b6c43f68133 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Sun, 24 Mar 2019 16:47:48 +0100 Subject: Update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Phlogi --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 1ecbeedad..6b7796be7 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1508,7 +1508,7 @@ namespace Emby.Server.Implementations { if (EnableHttps) { - return string.Format("http://{0}:{1}", + return string.Format("https://{0}:{1}", host, HttpsPort.ToString(CultureInfo.InvariantCulture)); } -- cgit v1.2.3 From 598b1c99660547d7c8e3b253c4664a6faa78a03d Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Sun, 24 Mar 2019 16:47:59 +0100 Subject: Update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Phlogi --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 6b7796be7..20a3c23ae 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1531,7 +1531,7 @@ namespace Emby.Server.Implementations { if (EnableHttps) { - return string.Format("http://{0}:{1}", + return string.Format("https://{0}:{1}", host, ServerConfiguration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture)); } -- cgit v1.2.3 From 7ebb043249d9c13c3bf2cc41c52d71c4e73f40f9 Mon Sep 17 00:00:00 2001 From: Phlogi Date: Sun, 24 Mar 2019 16:50:39 +0100 Subject: Removed comment, renamed methods consistently. --- Emby.Server.Implementations/ApplicationHost.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 20a3c23ae..1a64c8eaa 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1376,9 +1376,6 @@ namespace Emby.Server.Implementations if (string.IsNullOrEmpty(ServerConfiguration.WanDdns)){ var wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); } else { - // Use the (dynmic) domain name set in the configuration if available instead of querying - // an external service to get the IP address - // The domain resolution to the ip should be part of the client, not the server. var wanAddress = ServerConfiguration.WanDdns; } @@ -1498,13 +1495,13 @@ namespace Emby.Server.Implementations { if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) { - return GetLocalApiUrlWithPort("[" + ipAddress.Address + "]"); + return GetLocalApiUrl("[" + ipAddress.Address + "]"); } - return GetLocalApiUrlWithPort(ipAddress.Address); + return GetLocalApiUrl(ipAddress.Address); } - public string GetLocalApiUrlWithPort(string host) + public string GetLocalApiUrl(string host) { if (EnableHttps) { @@ -1521,13 +1518,13 @@ namespace Emby.Server.Implementations { if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) { - return GetWanApiUrlWithPort("[" + ipAddress.Address + "]"); + return GetWanApiUrl("[" + ipAddress.Address + "]"); } - return GetWanApiUrlWithPort(ipAddress.Address); + return GetWanApiUrl(ipAddress.Address); } - public string GetWanApiUrlWithPort(string host) + public string GetWanApiUrl(string host) { if (EnableHttps) { -- cgit v1.2.3 From 030fcaac156e9d75d4e7e84b0bea1291b91c0079 Mon Sep 17 00:00:00 2001 From: Phlogi Date: Sun, 24 Mar 2019 17:02:03 +0100 Subject: Proper access to configuration objects --- Emby.Server.Implementations/ApplicationHost.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 1a64c8eaa..fea23a3d7 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1372,11 +1372,10 @@ namespace Emby.Server.Implementations public async Task GetSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); + var wanAddress = ServerConfigurationManager.Configuration.WanDdns; - if (string.IsNullOrEmpty(ServerConfiguration.WanDdns)){ + if (string.IsNullOrEmpty(wanAddress)){ var wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); - } else { - var wanAddress = ServerConfiguration.WanDdns; } return new SystemInfo @@ -1530,11 +1529,11 @@ namespace Emby.Server.Implementations { return string.Format("https://{0}:{1}", host, - ServerConfiguration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture)); + ServerConfigurationManager.Configuration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture)); } return string.Format("http://{0}:{1}", host, - ServerConfiguration.PublicPort.ToString(CultureInfo.InvariantCulture)); + ServerConfigurationManager.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture)); } public Task> GetLocalIpAddresses(CancellationToken cancellationToken) -- cgit v1.2.3 From d18252542d81e1c279b10af0198be30a8b94edea Mon Sep 17 00:00:00 2001 From: Phlogi Date: Sun, 24 Mar 2019 17:11:21 +0100 Subject: Also add the WAN switch to the public system info. --- Emby.Server.Implementations/ApplicationHost.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index fea23a3d7..a20838daf 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1375,7 +1375,7 @@ namespace Emby.Server.Implementations var wanAddress = ServerConfigurationManager.Configuration.WanDdns; if (string.IsNullOrEmpty(wanAddress)){ - var wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); + wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); } return new SystemInfo @@ -1426,7 +1426,11 @@ namespace Emby.Server.Implementations public async Task GetPublicSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); + var wanAddress = ServerConfigurationManager.Configuration.WanDdns; + + if (string.IsNullOrEmpty(wanAddress)){ + wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); + } return new PublicSystemInfo { Version = ApplicationVersion, -- cgit v1.2.3 From fb7f29de18bc6089e247041c7aa15b2ad7677339 Mon Sep 17 00:00:00 2001 From: Phlogi Date: Sun, 24 Mar 2019 18:33:21 +0100 Subject: Format the WAN API Url correctly with https and Port. --- Emby.Server.Implementations/ApplicationHost.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index a20838daf..8f66ff5f9 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1372,7 +1372,7 @@ namespace Emby.Server.Implementations public async Task GetSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = ServerConfigurationManager.Configuration.WanDdns; + var wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); if (string.IsNullOrEmpty(wanAddress)){ wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); @@ -1426,7 +1426,7 @@ namespace Emby.Server.Implementations public async Task GetPublicSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = ServerConfigurationManager.Configuration.WanDdns; + var wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); if (string.IsNullOrEmpty(wanAddress)){ wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); -- cgit v1.2.3 From 087d4153aed8a82651a057ddf898dea7f97ded4a Mon Sep 17 00:00:00 2001 From: Phlogi Date: Sun, 24 Mar 2019 21:47:18 +0100 Subject: Fix check for available WAN address. --- Emby.Server.Implementations/ApplicationHost.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8f66ff5f9..52d525552 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1372,10 +1372,13 @@ namespace Emby.Server.Implementations public async Task GetSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); + var wanAddress = System.String.Empty; - if (string.IsNullOrEmpty(wanAddress)){ + if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)){ wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); + } else + { + wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); } return new SystemInfo @@ -1425,11 +1428,14 @@ namespace Emby.Server.Implementations public async Task GetPublicSystemInfo(CancellationToken cancellationToken) { - var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); + var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); + var wanAddress = System.String.Empty; - if (string.IsNullOrEmpty(wanAddress)){ + if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)){ wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); + } else + { + wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); } return new PublicSystemInfo { -- cgit v1.2.3 From 2c4c56d6d638ee22617c000719aabcef5b949d32 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Mon, 25 Mar 2019 10:17:40 +0100 Subject: Formatting update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Phlogi --- Emby.Server.Implementations/ApplicationHost.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 52d525552..410f5becd 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1376,7 +1376,8 @@ namespace Emby.Server.Implementations if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)){ wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); - } else + } + else { wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); } -- cgit v1.2.3 From 89f2dfd78a5c73c9d9d5cc832ff0427fa732ae3e Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Mon, 25 Mar 2019 10:17:53 +0100 Subject: Update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Phlogi --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 410f5becd..8ff17f35c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1430,7 +1430,7 @@ namespace Emby.Server.Implementations public async Task GetPublicSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = System.String.Empty; + var wanAddress = string.Empty; if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)){ wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); -- cgit v1.2.3 From 3474568ce2864d05fc47575fed3bfe5c7b21a435 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Mon, 25 Mar 2019 10:18:04 +0100 Subject: Update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Phlogi --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8ff17f35c..ba705f1f2 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1372,7 +1372,7 @@ namespace Emby.Server.Implementations public async Task GetSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = System.String.Empty; + var wanAddress = string.Empty; if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)){ wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); -- cgit v1.2.3 From f7e7d726880f87c18e799420ee6eb0ab42d86a47 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Mon, 25 Mar 2019 10:18:18 +0100 Subject: Formatting update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Phlogi --- Emby.Server.Implementations/ApplicationHost.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index ba705f1f2..5c5e8e5bf 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1374,7 +1374,8 @@ namespace Emby.Server.Implementations var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); var wanAddress = string.Empty; - if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)){ + if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) + { wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); } else -- cgit v1.2.3 From e36d424b5f61e2785c26af49db7d120d66933935 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Mon, 25 Mar 2019 10:18:47 +0100 Subject: Formatting update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Phlogi --- Emby.Server.Implementations/ApplicationHost.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 5c5e8e5bf..9ace9a48f 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1433,7 +1433,8 @@ namespace Emby.Server.Implementations var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); var wanAddress = string.Empty; - if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)){ + if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) + { wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); } else { -- cgit v1.2.3 From 6480cfcc87b65331b15bf787633f978b30e2e829 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Mon, 25 Mar 2019 10:19:08 +0100 Subject: Formatting update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Phlogi --- Emby.Server.Implementations/ApplicationHost.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 9ace9a48f..7c8fb7f62 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1436,7 +1436,8 @@ namespace Emby.Server.Implementations if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) { wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); - } else + } + else { wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); } -- cgit v1.2.3 From 6566c9136057f7b272b0d35501ed85034034d11e Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Mon, 25 Mar 2019 21:27:03 +0100 Subject: Seperate changes from #1023 The unrelated changes from #1023 (and more) --- .../Activity/ActivityLogEntryPoint.cs | 33 ++++++--- Emby.Server.Implementations/ApplicationHost.cs | 5 +- .../Channels/ChannelManager.cs | 9 --- Emby.Server.Implementations/Dto/DtoService.cs | 28 +++----- .../Security/AuthenticationRepository.cs | 4 -- .../Services/StringMapTypeDeserializer.cs | 6 +- .../Session/SessionManager.cs | 78 +++++++--------------- MediaBrowser.Controller/Entities/UserView.cs | 5 +- .../Entities/UserViewBuilder.cs | 12 ++-- 9 files changed, 72 insertions(+), 108 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs index 98cd97c31..f32ad7196 100644 --- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs +++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs @@ -3,12 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Updates; using MediaBrowser.Controller; using MediaBrowser.Controller.Authentication; -using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; @@ -29,31 +27,39 @@ namespace Emby.Server.Implementations.Activity { public class ActivityLogEntryPoint : IServerEntryPoint { + private readonly ILogger _logger; private readonly IInstallationManager _installationManager; private readonly ISessionManager _sessionManager; private readonly ITaskManager _taskManager; private readonly IActivityManager _activityManager; private readonly ILocalizationManager _localization; - private readonly ILibraryManager _libraryManager; private readonly ISubtitleManager _subManager; private readonly IUserManager _userManager; - private readonly IServerConfigurationManager _config; private readonly IServerApplicationHost _appHost; private readonly IDeviceManager _deviceManager; - public ActivityLogEntryPoint(ISessionManager sessionManager, IDeviceManager deviceManager, ITaskManager taskManager, IActivityManager activityManager, ILocalizationManager localization, IInstallationManager installationManager, ILibraryManager libraryManager, ISubtitleManager subManager, IUserManager userManager, IServerConfigurationManager config, IServerApplicationHost appHost) + public ActivityLogEntryPoint( + ILogger logger, + ISessionManager sessionManager, + IDeviceManager deviceManager, + ITaskManager taskManager, + IActivityManager activityManager, + ILocalizationManager localization, + IInstallationManager installationManager, + ISubtitleManager subManager, + IUserManager userManager, + IServerApplicationHost appHost) { + _logger = logger; _sessionManager = sessionManager; + _deviceManager = deviceManager; _taskManager = taskManager; _activityManager = activityManager; _localization = localization; _installationManager = installationManager; - _libraryManager = libraryManager; _subManager = subManager; _userManager = userManager; - _config = config; _appHost = appHost; - _deviceManager = deviceManager; } public Task RunAsync() @@ -124,7 +130,7 @@ namespace Emby.Server.Implementations.Activity if (item == null) { - //_logger.LogWarning("PlaybackStopped reported with null media info."); + _logger.LogWarning("PlaybackStopped reported with null media info."); return; } @@ -155,7 +161,7 @@ namespace Emby.Server.Implementations.Activity if (item == null) { - //_logger.LogWarning("PlaybackStart reported with null media info."); + _logger.LogWarning("PlaybackStart reported with null media info."); return; } @@ -203,6 +209,7 @@ namespace Emby.Server.Implementations.Activity { return NotificationType.AudioPlayback.ToString(); } + if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) { return NotificationType.VideoPlayback.ToString(); @@ -217,6 +224,7 @@ namespace Emby.Server.Implementations.Activity { return NotificationType.AudioPlaybackStopped.ToString(); } + if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) { return NotificationType.VideoPlaybackStopped.ToString(); @@ -415,6 +423,7 @@ namespace Emby.Server.Implementations.Activity { vals.Add(e.Result.ErrorMessage); } + if (!string.IsNullOrEmpty(e.Result.LongErrorMessage)) { vals.Add(e.Result.LongErrorMessage); @@ -424,7 +433,7 @@ namespace Emby.Server.Implementations.Activity { Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name), Type = NotificationType.TaskFailed.ToString(), - Overview = string.Join(Environment.NewLine, vals.ToArray()), + Overview = string.Join(Environment.NewLine, vals), ShortOverview = runningTime, Severity = LogLevel.Error }); @@ -503,6 +512,7 @@ namespace Emby.Server.Implementations.Activity { values.Add(CreateValueString(span.Hours, "hour")); } + // Number of minutes if (span.Minutes >= 1) { @@ -526,6 +536,7 @@ namespace Emby.Server.Implementations.Activity builder.Append(values[i]); } + // Return result return builder.ToString(); } diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 484942946..ff49c74a3 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -831,10 +831,10 @@ namespace Emby.Server.Implementations DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ProviderManager, this, () => MediaSourceManager, () => LiveTvManager); serviceCollection.AddSingleton(DtoService); - ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LoggerFactory, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager); + ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LoggerFactory, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, ProviderManager); serviceCollection.AddSingleton(ChannelManager); - SessionManager = new SessionManager(UserDataManager, LoggerFactory, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager); + SessionManager = new SessionManager(UserDataManager, LoggerFactory, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, this, AuthenticationRepository, DeviceManager, MediaSourceManager); serviceCollection.AddSingleton(SessionManager); serviceCollection.AddSingleton( @@ -1035,7 +1035,6 @@ namespace Emby.Server.Implementations Video.LiveTvManager = LiveTvManager; Folder.UserViewManager = UserViewManager; UserView.TVSeriesManager = TVSeriesManager; - UserView.PlaylistManager = PlaylistManager; UserView.CollectionManager = CollectionManager; BaseItem.MediaSourceManager = MediaSourceManager; CollectionFolder.XmlSerializer = XmlSerializer; diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 7e50650d7..e9961e8bd 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Common.Progress; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; @@ -20,7 +19,6 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Channels; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Globalization; using MediaBrowser.Model.IO; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Serialization; @@ -40,11 +38,8 @@ namespace Emby.Server.Implementations.Channels private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; private readonly IJsonSerializer _jsonSerializer; - private readonly IHttpClient _httpClient; private readonly IProviderManager _providerManager; - private readonly ILocalizationManager _localization; - public ChannelManager( IUserManager userManager, IDtoService dtoService, @@ -54,8 +49,6 @@ namespace Emby.Server.Implementations.Channels IFileSystem fileSystem, IUserDataManager userDataManager, IJsonSerializer jsonSerializer, - ILocalizationManager localization, - IHttpClient httpClient, IProviderManager providerManager) { _userManager = userManager; @@ -66,8 +59,6 @@ namespace Emby.Server.Implementations.Channels _fileSystem = fileSystem; _userDataManager = userDataManager; _jsonSerializer = jsonSerializer; - _localization = localization; - _httpClient = httpClient; _providerManager = providerManager; } diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 7b28a22a8..2f1b60be9 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -89,14 +89,11 @@ namespace Emby.Server.Implementations.Dto var channelTuples = new List>(); var index = 0; - var allCollectionFolders = _libraryManager.GetUserRootFolder().Children.OfType().ToList(); - foreach (var item in items) { - var dto = GetBaseItemDtoInternal(item, options, allCollectionFolders, user, owner); + var dto = GetBaseItemDtoInternal(item, options, user, owner); - var tvChannel = item as LiveTvChannel; - if (tvChannel != null) + if (item is LiveTvChannel tvChannel) { channelTuples.Add(new Tuple(dto, tvChannel)); } @@ -105,9 +102,7 @@ namespace Emby.Server.Implementations.Dto programTuples.Add(new Tuple(item, dto)); } - var byName = item as IItemByName; - - if (byName != null) + if (item is IItemByName byName) { if (options.ContainsField(ItemFields.ItemCounts)) { @@ -130,8 +125,7 @@ namespace Emby.Server.Implementations.Dto if (programTuples.Count > 0) { - var task = _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user); - Task.WaitAll(task); + _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user).GetAwaiter().GetResult(); } if (channelTuples.Count > 0) @@ -144,8 +138,7 @@ namespace Emby.Server.Implementations.Dto public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) { - var allCollectionFolders = _libraryManager.GetUserRootFolder().Children.OfType().ToList(); - var dto = GetBaseItemDtoInternal(item, options, allCollectionFolders, user, owner); + var dto = GetBaseItemDtoInternal(item, options, user, owner); var tvChannel = item as LiveTvChannel; if (tvChannel != null) { @@ -188,7 +181,7 @@ namespace Emby.Server.Implementations.Dto }); } - private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, List allCollectionFolders, User user = null, BaseItem owner = null) + private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) { var dto = new BaseItemDto { @@ -312,6 +305,7 @@ namespace Emby.Server.Implementations.Dto { path = path.TrimStart('.'); } + if (!string.IsNullOrEmpty(path) && containers.Contains(path, StringComparer.OrdinalIgnoreCase)) { fileExtensionContainer = path; @@ -325,8 +319,7 @@ namespace Emby.Server.Implementations.Dto public BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List taggedItems, User user = null) { - var allCollectionFolders = _libraryManager.GetUserRootFolder().Children.OfType().ToList(); - var dto = GetBaseItemDtoInternal(item, options, allCollectionFolders, user); + var dto = GetBaseItemDtoInternal(item, options, user); if (taggedItems != null && options.ContainsField(ItemFields.ItemCounts)) { @@ -1051,14 +1044,15 @@ namespace Emby.Server.Implementations.Dto } else { - mediaStreams = dto.MediaSources.Where(i => string.Equals(i.Id, item.Id.ToString("N"), StringComparison.OrdinalIgnoreCase)) + string id = item.Id.ToString("N"); + mediaStreams = dto.MediaSources.Where(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase)) .SelectMany(i => i.MediaStreams) .ToArray(); } } else { - mediaStreams = _mediaSourceManager().GetStaticMediaSources(item, true).First().MediaStreams.ToArray(); + mediaStreams = _mediaSourceManager().GetStaticMediaSources(item, true)[0].MediaStreams.ToArray(); } dto.MediaStreams = mediaStreams; diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs index c81a93767..29b8dfd3d 100644 --- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs +++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs @@ -15,13 +15,9 @@ namespace Emby.Server.Implementations.Security { public class AuthenticationRepository : BaseSqliteRepository, IAuthenticationRepository { - private readonly IServerConfigurationManager _config; - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - public AuthenticationRepository(ILoggerFactory loggerFactory, IServerConfigurationManager config) : base(loggerFactory.CreateLogger(nameof(AuthenticationRepository))) { - _config = config; DbFilePath = Path.Combine(config.ApplicationPaths.DataPath, "authentication.db"); } diff --git a/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs b/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs index f835aa1b5..7d42b2b51 100644 --- a/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs +++ b/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs @@ -48,7 +48,7 @@ namespace Emby.Server.Implementations.Services foreach (var propertyInfo in RestPath.GetSerializableProperties(type)) { - var propertySetFn = TypeAccessor.GetSetPropertyMethod(type, propertyInfo); + var propertySetFn = TypeAccessor.GetSetPropertyMethod(propertyInfo); var propertyType = propertyInfo.PropertyType; var propertyParseStringFn = GetParseFn(propertyType); var propertySerializer = new PropertySerializerEntry(propertySetFn, propertyParseStringFn, propertyType); @@ -110,9 +110,9 @@ namespace Emby.Server.Implementations.Services } } - internal class TypeAccessor + internal static class TypeAccessor { - public static Action GetSetPropertyMethod(Type type, PropertyInfo propertyInfo) + public static Action GetSetPropertyMethod(PropertyInfo propertyInfo) { if (!propertyInfo.CanWrite || propertyInfo.GetIndexParameters().Length > 0) { diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 985748caf..dc23551db 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -7,7 +7,6 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Events; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Authentication; using MediaBrowser.Controller.Devices; @@ -25,7 +24,6 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; using MediaBrowser.Model.Library; using MediaBrowser.Model.Querying; -using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Session; using Microsoft.Extensions.Logging; @@ -53,8 +51,6 @@ namespace Emby.Server.Implementations.Session private readonly IImageProcessor _imageProcessor; private readonly IMediaSourceManager _mediaSourceManager; - private readonly IHttpClient _httpClient; - private readonly IJsonSerializer _jsonSerializer; private readonly IServerApplicationHost _appHost; private readonly IAuthenticationRepository _authRepo; @@ -96,9 +92,7 @@ namespace Emby.Server.Implementations.Session IMusicManager musicManager, IDtoService dtoService, IImageProcessor imageProcessor, - IJsonSerializer jsonSerializer, IServerApplicationHost appHost, - IHttpClient httpClient, IAuthenticationRepository authRepo, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager) @@ -110,9 +104,7 @@ namespace Emby.Server.Implementations.Session _musicManager = musicManager; _dtoService = dtoService; _imageProcessor = imageProcessor; - _jsonSerializer = jsonSerializer; _appHost = appHost; - _httpClient = httpClient; _authRepo = authRepo; _deviceManager = deviceManager; _mediaSourceManager = mediaSourceManager; @@ -347,8 +339,7 @@ namespace Emby.Server.Implementations.Session var runtimeTicks = libraryItem.RunTimeTicks; MediaSourceInfo mediaSource = null; - var hasMediaSources = libraryItem as IHasMediaSources; - if (hasMediaSources != null) + if (libraryItem is IHasMediaSources hasMediaSources) { mediaSource = await GetMediaSource(libraryItem, info.MediaSourceId, info.LiveStreamId).ConfigureAwait(false); @@ -1841,64 +1832,49 @@ namespace Emby.Server.Implementations.Session var data = dataFn(); - var tasks = sessions.Select(session => Task.Run(async () => + IEnumerable GetTasks() { - try - { - await SendMessageToSession(session, name, data, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) + foreach (var session in sessions) { - _logger.LogError("Error sending message", ex); + yield return SendMessageToSession(session, name, data, cancellationToken); } + } - }, cancellationToken)).ToArray(); - - return Task.WhenAll(tasks); + return Task.WhenAll(GetTasks()); } public Task SendMessageToUserSessions(List userIds, string name, T data, CancellationToken cancellationToken) { CheckDisposed(); - var sessions = Sessions.Where(i => userIds.Any(i.ContainsUser)).ToList(); + var sessions = Sessions.Where(i => userIds.Any(i.ContainsUser)); - var tasks = sessions.Select(session => Task.Run(async () => + IEnumerable GetTasks() { - try - { - await SendMessageToSession(session, name, data, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) + foreach (var session in sessions) { - _logger.LogError("Error sending message", ex); + yield return SendMessageToSession(session, name, data, cancellationToken); } + } - }, cancellationToken)).ToArray(); - - return Task.WhenAll(tasks); + return Task.WhenAll(GetTasks()); } public Task SendMessageToUserDeviceSessions(string deviceId, string name, T data, CancellationToken cancellationToken) { CheckDisposed(); - var sessions = Sessions.Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase)).ToList(); + var sessions = Sessions.Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase)); - var tasks = sessions.Select(session => Task.Run(async () => + IEnumerable GetTasks() { - try - { - await SendMessageToSession(session, name, data, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) + foreach (var session in sessions) { - _logger.LogError("Error sending message", ex); + yield return SendMessageToSession(session, name, data, cancellationToken); } + } - }, cancellationToken)).ToArray(); - - return Task.WhenAll(tasks); + return Task.WhenAll(GetTasks()); } public Task SendMessageToUserDeviceAndAdminSessions(string deviceId, string name, T data, CancellationToken cancellationToken) @@ -1906,23 +1882,17 @@ namespace Emby.Server.Implementations.Session CheckDisposed(); var sessions = Sessions - .Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase) || IsAdminSession(i)) - .ToList(); + .Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase) || IsAdminSession(i)); - var tasks = sessions.Select(session => Task.Run(async () => + IEnumerable GetTasks() { - try - { - await SendMessageToSession(session, name, data, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) + foreach (var session in sessions) { - _logger.LogError("Error sending message", ex); + yield return SendMessageToSession(session, name, data, cancellationToken); } + } - }, cancellationToken)).ToArray(); - - return Task.WhenAll(tasks); + return Task.WhenAll(GetTasks()); } private bool IsAdminSession(SessionInfo s) diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 3e2191376..4a6d32dce 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.TV; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Serialization; @@ -17,7 +16,6 @@ namespace MediaBrowser.Controller.Entities public Guid? UserId { get; set; } public static ITVSeriesManager TVSeriesManager; - public static IPlaylistManager PlaylistManager; [IgnoreDataMember] public string CollectionType => ViewType; @@ -38,6 +36,7 @@ namespace MediaBrowser.Controller.Entities { list.Add(Id); } + return list; } @@ -65,7 +64,7 @@ namespace MediaBrowser.Controller.Entities parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent; } - return new UserViewBuilder(UserViewManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, ConfigurationManager, PlaylistManager) + return new UserViewBuilder(UserViewManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, ConfigurationManager) .GetUserItems(parent, this, CollectionType, query); } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 683218a9e..e483c8f34 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -5,7 +5,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.TV; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; @@ -21,9 +20,14 @@ namespace MediaBrowser.Controller.Entities private readonly IUserDataManager _userDataManager; private readonly ITVSeriesManager _tvSeriesManager; private readonly IServerConfigurationManager _config; - private readonly IPlaylistManager _playlistManager; - public UserViewBuilder(IUserViewManager userViewManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, IServerConfigurationManager config, IPlaylistManager playlistManager) + public UserViewBuilder( + IUserViewManager userViewManager, + ILibraryManager libraryManager, + ILogger logger, + IUserDataManager userDataManager, + ITVSeriesManager tvSeriesManager, + IServerConfigurationManager config) { _userViewManager = userViewManager; _libraryManager = libraryManager; @@ -31,7 +35,6 @@ namespace MediaBrowser.Controller.Entities _userDataManager = userDataManager; _tvSeriesManager = tvSeriesManager; _config = config; - _playlistManager = playlistManager; } public QueryResult GetUserItems(Folder queryParent, Folder displayParent, string viewType, InternalItemsQuery query) @@ -110,6 +113,7 @@ namespace MediaBrowser.Controller.Entities { return GetResult(GetMediaFolders(user).OfType().SelectMany(i => i.GetChildren(user, true)), queryParent, query); } + return queryParent.GetItems(query); } } -- cgit v1.2.3 From 4c8f8cf64cc81fb5f1bb32aeb8349ce38badf457 Mon Sep 17 00:00:00 2001 From: Phlogi Date: Mon, 25 Mar 2019 21:34:55 +0100 Subject: Removed trailing spaces, renamed get wan IP function. --- Emby.Server.Implementations/ApplicationHost.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 7c8fb7f62..b5582ae4f 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1376,7 +1376,7 @@ namespace Emby.Server.Implementations if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) { - wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); + wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); } else { @@ -1435,7 +1435,7 @@ namespace Emby.Server.Implementations if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) { - wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false); + wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); } else { @@ -1478,7 +1478,7 @@ namespace Emby.Server.Implementations return null; } - public async Task GetWanApiUrl(CancellationToken cancellationToken) + public async Task GetWanApiUrlFromExternal(CancellationToken cancellationToken) { const string Url = "http://ipv4.icanhazip.com"; try @@ -1524,7 +1524,7 @@ namespace Emby.Server.Implementations } return string.Format("http://{0}:{1}", host, - HttpPort.ToString(CultureInfo.InvariantCulture)); + HttpPort.ToString(CultureInfo.InvariantCulture)); } public string GetWanApiUrl(IpAddressInfo ipAddress) -- cgit v1.2.3 From 1b03f078b92021b8f3c2e7c148f1e67debd27fac Mon Sep 17 00:00:00 2001 From: Phlogi Date: Mon, 25 Mar 2019 21:43:50 +0100 Subject: No need to assign empty string. --- Emby.Server.Implementations/ApplicationHost.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index b5582ae4f..49da67292 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1372,15 +1372,14 @@ namespace Emby.Server.Implementations public async Task GetSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = string.Empty; if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) { - wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); + var wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); } else { - wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); + var wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); } return new SystemInfo @@ -1431,15 +1430,14 @@ namespace Emby.Server.Implementations public async Task GetPublicSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - var wanAddress = string.Empty; if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) { - wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); + var wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); } else { - wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); + var wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); } return new PublicSystemInfo { -- cgit v1.2.3 From b44a70ff368f228fc27a184e2139d288bada85cc Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Mon, 25 Mar 2019 22:25:32 +0100 Subject: Simplify/remove/clean code * Remove useless runtime check (we only support one) * Remove unused args * Remove a global constant And ofc fix some warnings ;) --- Emby.Server.Implementations/ApplicationHost.cs | 18 +++++------- .../Cryptography/CryptographyProvider.cs | 3 +- .../Data/SqliteDisplayPreferencesRepository.cs | 3 +- .../EntryPoints/LibraryChangedNotifier.cs | 4 +-- .../HttpServer/Security/AuthService.cs | 4 +-- .../HttpServer/StreamWriter.cs | 3 -- .../LiveTv/EmbyTV/EmbyTV.cs | 4 +-- .../LiveTv/LiveTvManager.cs | 4 +-- .../LiveTv/TunerHosts/M3UTunerHost.cs | 14 ++++------ .../LiveTv/TunerHosts/M3uParser.cs | 20 ++++++++------ .../Updates/InstallationManager.cs | 32 ++++------------------ Jellyfin.Server/Program.cs | 1 - MediaBrowser.Common/Extensions/BaseExtensions.cs | 10 ++++--- jellyfin.ruleset | 3 ++ 14 files changed, 50 insertions(+), 73 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 484942946..e15cb68e9 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -200,7 +200,7 @@ namespace Emby.Server.Implementations /// /// The disposable parts /// - protected readonly List _disposableParts = new List(); + private readonly List _disposableParts = new List(); /// /// Gets the configuration manager. @@ -216,8 +216,9 @@ namespace Emby.Server.Implementations { #if BETA return PackageVersionClass.Beta; -#endif +#else return PackageVersionClass.Release; +#endif } } @@ -340,7 +341,6 @@ namespace Emby.Server.Implementations protected IProcessFactory ProcessFactory { get; private set; } - protected ICryptoProvider CryptographyProvider = new CryptographyProvider(); protected readonly IXmlSerializer XmlSerializer; protected ISocketFactory SocketFactory { get; private set; } @@ -369,9 +369,6 @@ namespace Emby.Server.Implementations { _configuration = configuration; - // hack alert, until common can target .net core - BaseExtensions.CryptographyProvider = CryptographyProvider; - XmlSerializer = new MyXmlSerializer(fileSystem, loggerFactory); NetworkManager = networkManager; @@ -735,13 +732,12 @@ namespace Emby.Server.Implementations ApplicationHost.StreamHelper = new StreamHelper(); serviceCollection.AddSingleton(StreamHelper); - serviceCollection.AddSingleton(CryptographyProvider); + serviceCollection.AddSingleton(typeof(ICryptoProvider), typeof(CryptographyProvider)); SocketFactory = new SocketFactory(); serviceCollection.AddSingleton(SocketFactory); - InstallationManager = new InstallationManager(LoggerFactory, this, ApplicationPaths, HttpClient, JsonSerializer, ServerConfigurationManager, FileSystemManager, CryptographyProvider, ZipClient, PackageRuntime); - serviceCollection.AddSingleton(InstallationManager); + serviceCollection.AddSingleton(typeof(IInstallationManager), typeof(InstallationManager)); ZipClient = new ZipClient(); serviceCollection.AddSingleton(ZipClient); @@ -908,8 +904,6 @@ namespace Emby.Server.Implementations _serviceProvider = serviceCollection.BuildServiceProvider(); } - public virtual string PackageRuntime => "netcore"; - public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths) { // Distinct these to prevent users from reporting problems that aren't actually problems @@ -1049,6 +1043,8 @@ namespace Emby.Server.Implementations /// protected void FindParts() { + InstallationManager = _serviceProvider.GetService(); + if (!ServerConfigurationManager.Configuration.IsPortAuthorized) { ServerConfigurationManager.Configuration.IsPortAuthorized = true; diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs index 982bba625..6d7193ce2 100644 --- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs +++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs @@ -4,7 +4,6 @@ using System.Globalization; using System.IO; using System.Security.Cryptography; using System.Text; -using System.Linq; using MediaBrowser.Model.Cryptography; namespace Emby.Server.Implementations.Cryptography @@ -136,7 +135,7 @@ namespace Emby.Server.Implementations.Cryptography { return PBKDF2(DefaultHashMethod, bytes, salt, _defaultIterations); } - + public byte[] ComputeHash(PasswordHash hash) { int iterations = _defaultIterations; diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs index 3d60925da..47552806d 100644 --- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs @@ -90,9 +90,10 @@ namespace Emby.Server.Implementations.Data { throw new ArgumentNullException(nameof(displayPreferences)); } + if (string.IsNullOrEmpty(displayPreferences.Id)) { - throw new ArgumentNullException(nameof(displayPreferences.Id)); + throw new ArgumentException("Display preferences has an invalid Id", nameof(displayPreferences)); } cancellationToken.ThrowIfCancellationRequested(); diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 038965647..8369f4f59 100644 --- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -388,7 +388,7 @@ namespace Emby.Server.Implementations.EntryPoints FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), - CollectionFolders = GetTopParentIds(newAndRemoved, user, allUserRootChildren).ToArray() + CollectionFolders = GetTopParentIds(newAndRemoved, allUserRootChildren).ToArray() }; } @@ -407,7 +407,7 @@ namespace Emby.Server.Implementations.EntryPoints return item.SourceType == SourceType.Library; } - private IEnumerable GetTopParentIds(List items, User user, List allUserRootChildren) + private IEnumerable GetTopParentIds(List items, List allUserRootChildren) { var list = new List(); diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs index 499a334fc..1027883ed 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs @@ -45,7 +45,7 @@ namespace Emby.Server.Implementations.HttpServer.Security // This code is executed before the service var auth = AuthorizationContext.GetAuthorizationInfo(request); - if (!IsExemptFromAuthenticationToken(auth, authAttribtues, request)) + if (!IsExemptFromAuthenticationToken(authAttribtues, request)) { ValidateSecurityToken(request, auth.Token); } @@ -122,7 +122,7 @@ namespace Emby.Server.Implementations.HttpServer.Security } } - private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, IRequest request) + private bool IsExemptFromAuthenticationToken(IAuthenticationAttributes authAttribtues, IRequest request) { if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard) { diff --git a/Emby.Server.Implementations/HttpServer/StreamWriter.cs b/Emby.Server.Implementations/HttpServer/StreamWriter.cs index cf30bbc32..324f9085e 100644 --- a/Emby.Server.Implementations/HttpServer/StreamWriter.cs +++ b/Emby.Server.Implementations/HttpServer/StreamWriter.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -14,8 +13,6 @@ namespace Emby.Server.Implementations.HttpServer /// public class StreamWriter : IAsyncStreamWriter, IHasHeaders { - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - /// /// Gets or sets the source stream. /// diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 58b3b6a69..7b210d231 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -261,7 +261,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV public string HomePageUrl => "https://github.com/jellyfin/jellyfin"; - public async Task RefreshSeriesTimers(CancellationToken cancellationToken, IProgress progress) + public async Task RefreshSeriesTimers(CancellationToken cancellationToken) { var seriesTimers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false); @@ -271,7 +271,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } - public async Task RefreshTimers(CancellationToken cancellationToken, IProgress progress) + public async Task RefreshTimers(CancellationToken cancellationToken) { var timers = await GetTimersAsync(cancellationToken).ConfigureAwait(false); diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index f7ef16fb0..9093d9740 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1087,8 +1087,8 @@ namespace Emby.Server.Implementations.LiveTv if (coreService != null) { - await coreService.RefreshSeriesTimers(cancellationToken, new SimpleProgress()).ConfigureAwait(false); - await coreService.RefreshTimers(cancellationToken, new SimpleProgress()).ConfigureAwait(false); + await coreService.RefreshSeriesTimers(cancellationToken).ConfigureAwait(false); + await coreService.RefreshTimers(cancellationToken).ConfigureAwait(false); } // Load these now which will prefetch metadata diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 588dcb843..2d9bec53f 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -10,14 +10,12 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Serialization; -using MediaBrowser.Model.System; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; @@ -52,9 +50,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { var channelIdPrefix = GetFullChannelIdPrefix(info); - var result = await new M3uParser(Logger, _httpClient, _appHost).Parse(info.Url, channelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false); - - return result.Cast().ToList(); + return await new M3uParser(Logger, _httpClient, _appHost).Parse(info.Url, channelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false); } public Task> GetTunerInfos(CancellationToken cancellationToken) @@ -73,7 +69,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return Task.FromResult(list); } - private string[] _disallowedSharedStreamExtensions = new string[] + private static readonly string[] _disallowedSharedStreamExtensions = new string[] { ".mkv", ".mp4", @@ -88,9 +84,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts if (tunerCount > 0) { var tunerHostId = info.Id; - var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase)).ToList(); + var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase)); - if (liveStreams.Count >= tunerCount) + if (liveStreams.Count() >= tunerCount) { throw new LiveTvConflictException("M3U simultaneous stream limit has been reached."); } @@ -98,7 +94,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts var sources = await GetChannelStreamMediaSources(info, channelInfo, cancellationToken).ConfigureAwait(false); - var mediaSource = sources.First(); + var mediaSource = sources[0]; if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping) { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index ad124bb0f..814031b12 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -11,7 +11,6 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.LiveTv.TunerHosts @@ -62,12 +61,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return Task.FromResult((Stream)File.OpenRead(url)); } - const string ExtInfPrefix = "#EXTINF:"; + private const string ExtInfPrefix = "#EXTINF:"; + private List GetChannels(TextReader reader, string channelIdPrefix, string tunerHostId) { var channels = new List(); string line; - string extInf = ""; + string extInf = string.Empty; while ((line = reader.ReadLine()) != null) { @@ -101,7 +101,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts channel.Path = line; channels.Add(channel); - extInf = ""; + extInf = string.Empty; } } @@ -110,8 +110,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts private ChannelInfo GetChannelnfo(string extInf, string tunerHostId, string mediaUrl) { - var channel = new ChannelInfo(); - channel.TunerHostId = tunerHostId; + var channel = new ChannelInfo() + { + TunerHostId = tunerHostId + }; extInf = extInf.Trim(); @@ -137,13 +139,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { channelIdValues.Add(channelId); } + if (!string.IsNullOrWhiteSpace(tvgId)) { channelIdValues.Add(tvgId); } + if (channelIdValues.Count > 0) { - channel.Id = string.Join("_", channelIdValues.ToArray()); + channel.Id = string.Join("_", channelIdValues); } return channel; @@ -152,7 +156,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts private string GetChannelNumber(string extInf, Dictionary attributes, string mediaUrl) { var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null; + var nameInExtInf = nameParts.Length > 1 ? nameParts[nameParts.Length - 1].Trim() : null; string numberString = null; string attributeValue; diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 301802b8a..7310de55d 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -12,7 +12,6 @@ using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Progress; using MediaBrowser.Common.Updates; using MediaBrowser.Controller.Configuration; -using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.Events; using MediaBrowser.Model.IO; using MediaBrowser.Model.Serialization; @@ -39,11 +38,10 @@ namespace Emby.Server.Implementations.Updates /// /// The completed installations /// - private ConcurrentBag CompletedInstallationsInternal { get; set; } + private ConcurrentBag _completedInstallationsInternal; - public IEnumerable CompletedInstallations => CompletedInstallationsInternal; + public IEnumerable CompletedInstallations => _completedInstallationsInternal; - #region PluginUninstalled Event /// /// Occurs when [plugin uninstalled]. /// @@ -57,9 +55,7 @@ namespace Emby.Server.Implementations.Updates { PluginUninstalled?.Invoke(this, new GenericEventArgs { Argument = plugin }); } - #endregion - #region PluginUpdated Event /// /// Occurs when [plugin updated]. /// @@ -77,9 +73,7 @@ namespace Emby.Server.Implementations.Updates _applicationHost.NotifyPendingRestart(); } - #endregion - #region PluginInstalled Event /// /// Occurs when [plugin updated]. /// @@ -96,7 +90,6 @@ namespace Emby.Server.Implementations.Updates _applicationHost.NotifyPendingRestart(); } - #endregion /// /// The _logger @@ -115,12 +108,8 @@ namespace Emby.Server.Implementations.Updates /// The application host. private readonly IApplicationHost _applicationHost; - private readonly ICryptoProvider _cryptographyProvider; private readonly IZipClient _zipClient; - // netframework or netcore - private readonly string _packageRuntime; - public InstallationManager( ILoggerFactory loggerFactory, IApplicationHost appHost, @@ -129,9 +118,7 @@ namespace Emby.Server.Implementations.Updates IJsonSerializer jsonSerializer, IServerConfigurationManager config, IFileSystem fileSystem, - ICryptoProvider cryptographyProvider, - IZipClient zipClient, - string packageRuntime) + IZipClient zipClient) { if (loggerFactory == null) { @@ -139,18 +126,16 @@ namespace Emby.Server.Implementations.Updates } CurrentInstallations = new List>(); - CompletedInstallationsInternal = new ConcurrentBag(); + _completedInstallationsInternal = new ConcurrentBag(); + _logger = loggerFactory.CreateLogger(nameof(InstallationManager)); _applicationHost = appHost; _appPaths = appPaths; _httpClient = httpClient; _jsonSerializer = jsonSerializer; _config = config; _fileSystem = fileSystem; - _cryptographyProvider = cryptographyProvider; _zipClient = zipClient; - _packageRuntime = packageRuntime; - _logger = loggerFactory.CreateLogger(nameof(InstallationManager)); } private static Version GetPackageVersion(PackageVersionInfo version) @@ -222,11 +207,6 @@ namespace Emby.Server.Implementations.Updates continue; } - if (string.IsNullOrEmpty(version.runtimes) || version.runtimes.IndexOf(_packageRuntime, StringComparison.OrdinalIgnoreCase) == -1) - { - continue; - } - versions.Add(version); } @@ -448,7 +428,7 @@ namespace Emby.Server.Implementations.Updates CurrentInstallations.Remove(tuple); } - CompletedInstallationsInternal.Add(installationInfo); + _completedInstallationsInternal.Add(installationInfo); PackageInstallationCompleted?.Invoke(this, installationEventArgs); } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 82a76c637..d4b10c8c8 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -19,7 +19,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.IO; -using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; diff --git a/MediaBrowser.Common/Extensions/BaseExtensions.cs b/MediaBrowser.Common/Extensions/BaseExtensions.cs index db0514bb1..40c16b957 100644 --- a/MediaBrowser.Common/Extensions/BaseExtensions.cs +++ b/MediaBrowser.Common/Extensions/BaseExtensions.cs @@ -1,6 +1,7 @@ using System; +using System.Text; using System.Text.RegularExpressions; -using MediaBrowser.Model.Cryptography; +using System.Security.Cryptography; namespace MediaBrowser.Common.Extensions { @@ -9,8 +10,6 @@ namespace MediaBrowser.Common.Extensions /// public static class BaseExtensions { - public static ICryptoProvider CryptographyProvider { get; set; } - /// /// Strips the HTML. /// @@ -31,7 +30,10 @@ namespace MediaBrowser.Common.Extensions /// Guid. public static Guid GetMD5(this string str) { - return CryptographyProvider.GetMD5(str); + using (var provider = MD5.Create()) + { + return new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(str))); + } } } } diff --git a/jellyfin.ruleset b/jellyfin.ruleset index 0a04b4c55..262121a32 100644 --- a/jellyfin.ruleset +++ b/jellyfin.ruleset @@ -20,6 +20,9 @@ + + + -- cgit v1.2.3 From 122cba2aa755df7d7c3e63aaa441f639b126b55c Mon Sep 17 00:00:00 2001 From: Phlogi Date: Mon, 25 Mar 2019 22:26:05 +0100 Subject: Correct use of local variable wanAddress. --- Emby.Server.Implementations/ApplicationHost.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 49da67292..fd14cb89d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1373,13 +1373,15 @@ namespace Emby.Server.Implementations { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); + string wanAddress; + if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) { - var wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); + wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); } else { - var wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); + wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); } return new SystemInfo @@ -1431,13 +1433,15 @@ namespace Emby.Server.Implementations { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); + string wanAddress; + if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) { - var wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); + wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); } else { - var wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); + wanAddress = GetWanApiUrl(ServerConfigurationManager.Configuration.WanDdns); } return new PublicSystemInfo { -- cgit v1.2.3 From a332092769cec5a3b17b7fb49b2d7c66bfe289bd Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Tue, 26 Mar 2019 19:20:40 +0100 Subject: Reduce complexity http routes --- Emby.Server.Implementations/ApplicationHost.cs | 37 +------- .../HttpServer/HttpListenerHost.cs | 50 +++------- .../Services/ServiceController.cs | 54 +++++------ .../Services/ServiceHandler.cs | 103 ++++++++++----------- .../Services/SwaggerService.cs | 20 ++-- Jellyfin.Server/Program.cs | 5 +- 6 files changed, 105 insertions(+), 164 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 484942946..ce08f2a28 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -617,8 +617,6 @@ namespace Emby.Server.Implementations DiscoverTypes(); - SetHttpLimit(); - await RegisterResources(serviceCollection).ConfigureAwait(false); FindParts(); @@ -918,8 +916,7 @@ namespace Emby.Server.Implementations .Distinct(); logger.LogInformation("Arguments: {Args}", commandLineArgs); - // FIXME: @bond this logs the kernel version, not the OS version - logger.LogInformation("Operating system: {OS} {OSVersion}", OperatingSystem.Name, Environment.OSVersion.Version); + logger.LogInformation("Operating system: {OS}", OperatingSystem.Name); logger.LogInformation("Architecture: {Architecture}", RuntimeInformation.OSArchitecture); logger.LogInformation("64-Bit Process: {Is64Bit}", Environment.Is64BitProcess); logger.LogInformation("User Interactive: {IsUserInteractive}", Environment.UserInteractive); @@ -929,19 +926,6 @@ namespace Emby.Server.Implementations logger.LogInformation("Application directory: {ApplicationPath}", appPaths.ProgramSystemPath); } - private void SetHttpLimit() - { - try - { - // Increase the max http request limit - ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); - } - catch (Exception ex) - { - Logger.LogError(ex, "Error setting http limit"); - } - } - private X509Certificate2 GetCertificate(CertificateInfo info) { var certificateLocation = info?.Path; @@ -1483,6 +1467,7 @@ namespace Emby.Server.Implementations { Logger.LogError(ex, "Error getting WAN Ip address information"); } + return null; } @@ -1756,24 +1741,6 @@ namespace Emby.Server.Implementations { } - /// - /// Called when [application updated]. - /// - /// The package. - protected void OnApplicationUpdated(PackageVersionInfo package) - { - Logger.LogInformation("Application has been updated to version {0}", package.versionStr); - - ApplicationUpdated?.Invoke( - this, - new GenericEventArgs() - { - Argument = package - }); - - NotifyPendingRestart(); - } - private bool _disposed = false; /// diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index e8d47cad5..79b8f52d7 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Globalization; using System.IO; using System.Linq; using System.Net.Sockets; @@ -11,7 +10,6 @@ using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.Net; using Emby.Server.Implementations.Services; -using Emby.Server.Implementations.SocketSharp; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller; @@ -127,12 +125,12 @@ namespace Emby.Server.Implementations.HttpServer private List GetRequestFilterAttributes(Type requestDtoType) { - var attributes = requestDtoType.GetTypeInfo().GetCustomAttributes(true).OfType().ToList(); + var attributes = requestDtoType.GetCustomAttributes(true).OfType().ToList(); var serviceType = GetServiceTypeByRequest(requestDtoType); if (serviceType != null) { - attributes.AddRange(serviceType.GetTypeInfo().GetCustomAttributes(true).OfType()); + attributes.AddRange(serviceType.GetCustomAttributes(true).OfType()); } attributes.Sort((x, y) => x.Priority - y.Priority); @@ -154,7 +152,7 @@ namespace Emby.Server.Implementations.HttpServer QueryString = e.QueryString ?? new QueryCollection() }; - connection.Closed += Connection_Closed; + connection.Closed += OnConnectionClosed; lock (_webSocketConnections) { @@ -164,7 +162,7 @@ namespace Emby.Server.Implementations.HttpServer WebSocketConnected?.Invoke(this, new GenericEventArgs(connection)); } - private void Connection_Closed(object sender, EventArgs e) + private void OnConnectionClosed(object sender, EventArgs e) { lock (_webSocketConnections) { @@ -322,14 +320,14 @@ namespace Emby.Server.Implementations.HttpServer private static string NormalizeConfiguredLocalAddress(string address) { - var index = address.Trim('/').IndexOf('/'); - + var add = address.AsSpan().Trim('/'); + int index = add.IndexOf('/'); if (index != -1) { - address = address.Substring(index + 1); + add = add.Slice(index + 1); } - return address.Trim('/'); + return add.TrimStart('/').ToString(); } private bool ValidateHost(string host) @@ -399,8 +397,8 @@ namespace Emby.Server.Implementations.HttpServer if (urlString.IndexOf("https://", StringComparison.OrdinalIgnoreCase) == -1) { // These are hacks, but if these ever occur on ipv6 in the local network they could be incorrectly redirected - if (urlString.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) != -1 || - urlString.IndexOf("dlna/", StringComparison.OrdinalIgnoreCase) != -1) + if (urlString.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) != -1 + || urlString.IndexOf("dlna/", StringComparison.OrdinalIgnoreCase) != -1) { return true; } @@ -572,7 +570,7 @@ namespace Emby.Server.Implementations.HttpServer if (handler != null) { - await handler.ProcessRequestAsync(this, httpReq, httpRes, Logger, httpReq.OperationName, cancellationToken).ConfigureAwait(false); + await handler.ProcessRequestAsync(this, httpReq, httpRes, Logger, cancellationToken).ConfigureAwait(false); } else { @@ -613,21 +611,11 @@ namespace Emby.Server.Implementations.HttpServer { var pathInfo = httpReq.PathInfo; - var pathParts = pathInfo.TrimStart('/').Split('/'); - if (pathParts.Length == 0) - { - Logger.LogError("Path parts empty for PathInfo: {PathInfo}, Url: {RawUrl}", pathInfo, httpReq.RawUrl); - return null; - } - - var restPath = ServiceHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, out string contentType); + pathInfo = ServiceHandler.GetSanitizedPathInfo(pathInfo, out string contentType); + var restPath = ServiceController.GetRestPathForRequest(httpReq.HttpMethod, pathInfo); if (restPath != null) { - return new ServiceHandler - { - RestPath = restPath, - ResponseContentType = contentType - }; + return new ServiceHandler(restPath, contentType); } Logger.LogError("Could not find handler for {PathInfo}", pathInfo); @@ -655,11 +643,6 @@ namespace Emby.Server.Implementations.HttpServer } else { - // TODO what is this? - var httpsUrl = url - .Replace("http://", "https://", StringComparison.OrdinalIgnoreCase) - .Replace(":" + _config.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture), ":" + _config.Configuration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase); - RedirectToUrl(httpRes, url); } } @@ -684,10 +667,7 @@ namespace Emby.Server.Implementations.HttpServer UrlPrefixes = urlPrefixes.ToArray(); ServiceController = new ServiceController(); - Logger.LogInformation("Calling ServiceStack AppHost.Init"); - - var types = services.Select(r => r.GetType()).ToArray(); - + var types = services.Select(r => r.GetType()); ServiceController.Init(this, types); ResponseFilters = new Action[] diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index 5796956d8..5e3d529c6 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -1,26 +1,17 @@ using System; using System.Collections.Generic; -using System.Reflection; using System.Threading.Tasks; using Emby.Server.Implementations.HttpServer; using MediaBrowser.Model.Services; namespace Emby.Server.Implementations.Services { - public delegate Task InstanceExecFn(IRequest requestContext, object intance, object request); public delegate object ActionInvokerFn(object intance, object request); public delegate void VoidActionInvokerFn(object intance, object request); public class ServiceController { - public static ServiceController Instance; - - public ServiceController() - { - Instance = this; - } - - public void Init(HttpListenerHost appHost, Type[] serviceTypes) + public void Init(HttpListenerHost appHost, IEnumerable serviceTypes) { foreach (var serviceType in serviceTypes) { @@ -37,7 +28,11 @@ namespace Emby.Server.Implementations.Services foreach (var mi in serviceType.GetActions()) { var requestType = mi.GetParameters()[0].ParameterType; - if (processedReqs.Contains(requestType)) continue; + if (processedReqs.Contains(requestType)) + { + continue; + } + processedReqs.Add(requestType); ServiceExecGeneral.CreateServiceRunnersFor(requestType, actions); @@ -55,18 +50,6 @@ namespace Emby.Server.Implementations.Services } } - public static Type FirstGenericType(Type type) - { - while (type != null) - { - if (type.GetTypeInfo().IsGenericType) - return type; - - type = type.GetTypeInfo().BaseType; - } - return null; - } - public readonly RestPath.RestPathMap RestPathMap = new RestPath.RestPathMap(); public void RegisterRestPaths(HttpListenerHost appHost, Type requestType, Type serviceType) @@ -84,17 +67,24 @@ namespace Emby.Server.Implementations.Services public void RegisterRestPath(RestPath restPath) { - if (!restPath.Path.StartsWith("/")) + if (restPath.Path[0] != '/') + { throw new ArgumentException(string.Format("Route '{0}' on '{1}' must start with a '/'", restPath.Path, restPath.RequestType.GetMethodName())); + } + if (restPath.Path.IndexOfAny(InvalidRouteChars) != -1) + { throw new ArgumentException(string.Format("Route '{0}' on '{1}' contains invalid chars. ", restPath.Path, restPath.RequestType.GetMethodName())); + } - if (!RestPathMap.TryGetValue(restPath.FirstMatchHashKey, out List pathsAtFirstMatch)) + if (RestPathMap.TryGetValue(restPath.FirstMatchHashKey, out List pathsAtFirstMatch)) { - pathsAtFirstMatch = new List(); - RestPathMap[restPath.FirstMatchHashKey] = pathsAtFirstMatch; + pathsAtFirstMatch.Add(restPath); + } + else + { + RestPathMap[restPath.FirstMatchHashKey] = new List() { restPath }; } - pathsAtFirstMatch.Add(restPath); } public RestPath GetRestPathForRequest(string httpMethod, string pathInfo) @@ -155,17 +145,15 @@ namespace Emby.Server.Implementations.Services return null; } - public Task Execute(HttpListenerHost appHost, object requestDto, IRequest req) + public Task Execute(HttpListenerHost httpHost, object requestDto, IRequest req) { req.Dto = requestDto; var requestType = requestDto.GetType(); req.OperationName = requestType.Name; - var serviceType = appHost.GetServiceTypeByRequest(requestType); - - var service = appHost.CreateInstance(serviceType); + var serviceType = httpHost.GetServiceTypeByRequest(requestType); - //var service = typeFactory.CreateInstance(serviceType); + var service = httpHost.CreateInstance(serviceType); var serviceRequiresContext = service as IRequiresRequest; if (serviceRequiresContext != null) diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index 3c8adfc98..243d2cca2 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -11,6 +11,18 @@ namespace Emby.Server.Implementations.Services { public class ServiceHandler { + private readonly ServiceController _serviceController; + + public RestPath RestPath { get; } + + public string ResponseContentType { get; } + + internal ServiceHandler(RestPath restPath, string responseContentType) + { + RestPath = restPath; + ResponseContentType = responseContentType; + } + protected static Task CreateContentTypeRequest(HttpListenerHost host, IRequest httpReq, Type requestType, string contentType) { if (!string.IsNullOrEmpty(contentType) && httpReq.ContentLength > 0) @@ -21,21 +33,22 @@ namespace Emby.Server.Implementations.Services return deserializer(requestType, httpReq.InputStream); } } + return Task.FromResult(host.CreateInstance(requestType)); } - public static RestPath FindMatchingRestPath(string httpMethod, string pathInfo, out string contentType) + public RestPath FindMatchingRestPath(string httpMethod, string pathInfo, out string contentType) { pathInfo = GetSanitizedPathInfo(pathInfo, out contentType); - return ServiceController.Instance.GetRestPathForRequest(httpMethod, pathInfo); + return _serviceController.GetRestPathForRequest(httpMethod, pathInfo); } public static string GetSanitizedPathInfo(string pathInfo, out string contentType) { contentType = null; var pos = pathInfo.LastIndexOf('.'); - if (pos >= 0) + if (pos != -1) { var format = pathInfo.Substring(pos + 1); contentType = GetFormatContentType(format); @@ -44,58 +57,38 @@ namespace Emby.Server.Implementations.Services pathInfo = pathInfo.Substring(0, pos); } } + return pathInfo; } private static string GetFormatContentType(string format) { //built-in formats - if (format == "json") - return "application/json"; - if (format == "xml") - return "application/xml"; - - return null; - } - - public RestPath GetRestPath(string httpMethod, string pathInfo) - { - if (this.RestPath == null) + switch (format) { - this.RestPath = FindMatchingRestPath(httpMethod, pathInfo, out string contentType); - - if (contentType != null) - ResponseContentType = contentType; + case "json": return "application/json"; + case "xml": return "application/xml"; + default: return null; } - return this.RestPath; } - public RestPath RestPath { get; set; } - - // Set from SSHHF.GetHandlerForPathInfo() - public string ResponseContentType { get; set; } - - public async Task ProcessRequestAsync(HttpListenerHost appHost, IRequest httpReq, IResponse httpRes, ILogger logger, string operationName, CancellationToken cancellationToken) + public async Task ProcessRequestAsync(HttpListenerHost httpHost, IRequest httpReq, IResponse httpRes, ILogger logger, CancellationToken cancellationToken) { - var restPath = GetRestPath(httpReq.Verb, httpReq.PathInfo); - if (restPath == null) - { - throw new NotSupportedException("No RestPath found for: " + httpReq.Verb + " " + httpReq.PathInfo); - } - - SetRoute(httpReq, restPath); + httpReq.Items["__route"] = RestPath; if (ResponseContentType != null) + { httpReq.ResponseContentType = ResponseContentType; + } - var request = httpReq.Dto = await CreateRequest(appHost, httpReq, restPath, logger).ConfigureAwait(false); + var request = httpReq.Dto = await CreateRequest(httpHost, httpReq, RestPath, logger).ConfigureAwait(false); - appHost.ApplyRequestFilters(httpReq, httpRes, request); + httpHost.ApplyRequestFilters(httpReq, httpRes, request); - var response = await appHost.ServiceController.Execute(appHost, request, httpReq).ConfigureAwait(false); + var response = await httpHost.ServiceController.Execute(httpHost, request, httpReq).ConfigureAwait(false); // Apply response filters - foreach (var responseFilter in appHost.ResponseFilters) + foreach (var responseFilter in httpHost.ResponseFilters) { responseFilter(httpReq, httpRes, response); } @@ -152,7 +145,11 @@ namespace Emby.Server.Implementations.Services foreach (var name in request.QueryString.Keys) { - if (name == null) continue; //thank you ASP.NET + if (name == null) + { + // thank you ASP.NET + continue; + } var values = request.QueryString[name]; if (values.Count == 1) @@ -175,7 +172,11 @@ namespace Emby.Server.Implementations.Services { foreach (var name in formData.Keys) { - if (name == null) continue; //thank you ASP.NET + if (name == null) + { + // thank you ASP.NET + continue; + } var values = formData.GetValues(name); if (values.Count == 1) @@ -210,7 +211,12 @@ namespace Emby.Server.Implementations.Services foreach (var name in request.QueryString.Keys) { - if (name == null) continue; //thank you ASP.NET + if (name == null) + { + // thank you ASP.NET + continue; + } + map[name] = request.QueryString[name]; } @@ -221,7 +227,12 @@ namespace Emby.Server.Implementations.Services { foreach (var name in formData.Keys) { - if (name == null) continue; //thank you ASP.NET + if (name == null) + { + // thank you ASP.NET + continue; + } + map[name] = formData[name]; } } @@ -229,17 +240,5 @@ namespace Emby.Server.Implementations.Services return map; } - - private static void SetRoute(IRequest req, RestPath route) - { - req.Items["__route"] = route; - } - - private static RestPath GetRoute(IRequest req) - { - req.Items.TryGetValue("__route", out var route); - return route as RestPath; - } } - } diff --git a/Emby.Server.Implementations/Services/SwaggerService.cs b/Emby.Server.Implementations/Services/SwaggerService.cs index 3e6970eef..d22386436 100644 --- a/Emby.Server.Implementations/Services/SwaggerService.cs +++ b/Emby.Server.Implementations/Services/SwaggerService.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Services; +using Emby.Server.Implementations.HttpServer; namespace Emby.Server.Implementations.Services { @@ -109,10 +109,16 @@ namespace Emby.Server.Implementations.Services public class SwaggerService : IService, IRequiresRequest { + private readonly IHttpServer _httpServer; private SwaggerSpec _spec; public IRequest Request { get; set; } + public SwaggerService(IHttpServer httpServer) + { + _httpServer = httpServer; + } + public object Get(GetSwaggerSpec request) { return _spec ?? (_spec = GetSpec()); @@ -181,7 +187,8 @@ namespace Emby.Server.Implementations.Services { var paths = new SortedDictionary>(); - var all = ServiceController.Instance.RestPathMap.OrderBy(i => i.Key, StringComparer.OrdinalIgnoreCase).ToList(); + // REVIEW: this can be done better + var all = ((HttpListenerHost)_httpServer).ServiceController.RestPathMap.OrderBy(i => i.Key, StringComparer.OrdinalIgnoreCase).ToList(); foreach (var current in all) { @@ -192,11 +199,8 @@ namespace Emby.Server.Implementations.Services continue; } - if (info.Path.StartsWith("/mediabrowser", StringComparison.OrdinalIgnoreCase)) - { - continue; - } - if (info.Path.StartsWith("/jellyfin", StringComparison.OrdinalIgnoreCase)) + if (info.Path.StartsWith("/mediabrowser", StringComparison.OrdinalIgnoreCase) + || info.Path.StartsWith("/jellyfin", StringComparison.OrdinalIgnoreCase)) { continue; } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 82a76c637..fab584bef 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -19,7 +19,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.IO; -using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -119,6 +118,10 @@ namespace Jellyfin.Server SQLitePCL.Batteries_V2.Init(); + // Increase the max http request limit + // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others. + ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); + // Allow all https requests ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; }); -- cgit v1.2.3 From 3001f21f8d8592586add36661a0be0679e427d63 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 28 Mar 2019 19:11:05 +0100 Subject: Hacky fix for a hacky issue --- Emby.Server.Implementations/ApplicationHost.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 1c9a4776a..ce8483a32 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1042,8 +1042,6 @@ namespace Emby.Server.Implementations CollectionFolder.JsonSerializer = JsonSerializer; CollectionFolder.ApplicationHost = this; AuthenticatedAttribute.AuthService = AuthService; - - InstallationManager.PluginInstalled += PluginInstalled; } private async void PluginInstalled(object sender, GenericEventArgs args) @@ -1085,6 +1083,7 @@ namespace Emby.Server.Implementations protected void FindParts() { InstallationManager = _serviceProvider.GetService(); + InstallationManager.PluginInstalled += PluginInstalled; if (!ServerConfigurationManager.Configuration.IsPortAuthorized) { -- cgit v1.2.3 From 38fcd31917af1d904ea61de0f90918d44122d2e4 Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Tue, 2 Apr 2019 18:19:19 -0400 Subject: Search all subdirectories for Plugins This was added in #801 which broke the previous plugin install behaviour. Previously plugins could be loaded from subdirectories but this search was only for the highest level. Change it to search all subdirectories instead to restore the previous behaviour. Also modifies the same option from #934, though I'm not 100% sure if this is needed here. --- Emby.Server.Implementations/ApplicationHost.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 41ca2a102..dbdf246a2 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1047,7 +1047,7 @@ namespace Emby.Server.Implementations private async void PluginInstalled(object sender, GenericEventArgs args) { string dir = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(args.Argument.targetFilename)); - var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.TopDirectoryOnly) + var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.AllDirectories) .Select(x => Assembly.LoadFrom(x)) .SelectMany(x => x.ExportedTypes) .Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface && !x.IsGenericType) @@ -1346,7 +1346,7 @@ namespace Emby.Server.Implementations { if (Directory.Exists(ApplicationPaths.PluginsPath)) { - foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)) + foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.AllDirectories)) { Logger.LogInformation("Loading assembly {Path}", file); yield return Assembly.LoadFrom(file); -- cgit v1.2.3 From 05a4161fd388d7ecda2f1b4a6ec6d02ee7b4488e Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Wed, 3 Apr 2019 19:43:02 -0400 Subject: Correct the installation and removal of plugins Upgrading plugins was broken for various reasons. There are four fixes and a minor one: 1. Use a directory name based only on the `Name` of the plugin, not the source filename, which contains the version. Avoids strange duplication of the plugin. 2. Use the new directory name for the deletes if it's present, so that installation and removal happen at that directory level and we don't leave empty folders laying around. Ensures we properly remove additional resources in plugins too, not just the main `.dll` file. 3. Ignore the incoming `target` when installing, and always set it ourself to the proper directory, which would matter when reinstalling. 4. Deletes an existing target directory before installing if it exists. Note that not calling any of the plugin removal code is intentional; I suspect that would delete configurations unexpectedly when upgrading which would be annoying. This way, it just replaces the files and then reloads. 5. (Minor) Added some actual debug messages around the plugin download section so failures can be more accurately seen. --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Updates/InstallationManager.cs | 41 ++++++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index dbdf246a2..05f8a8a5e 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1046,7 +1046,7 @@ namespace Emby.Server.Implementations private async void PluginInstalled(object sender, GenericEventArgs args) { - string dir = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(args.Argument.targetFilename)); + string dir = Path.Combine(ApplicationPaths.PluginsPath, args.Argument.name); var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.AllDirectories) .Select(x => Assembly.LoadFrom(x)) .SelectMany(x => x.ExportedTypes) diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 7310de55d..e5ba813a6 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -85,9 +85,11 @@ namespace Emby.Server.Implementations.Updates private void OnPluginInstalled(PackageVersionInfo package) { _logger.LogInformation("New plugin installed: {0} {1} {2}", package.name, package.versionStr ?? string.Empty, package.classification); + _logger.LogDebug("{String}", package.name); PluginInstalled?.Invoke(this, new GenericEventArgs { Argument = package }); + _logger.LogDebug("{String}", package.name); _applicationHost.NotifyPendingRestart(); } @@ -518,12 +520,12 @@ namespace Emby.Server.Implementations.Updates return; } - if (target == null) - { - target = Path.Combine(_appPaths.PluginsPath, Path.GetFileNameWithoutExtension(package.targetFilename)); - } + // Always override the passed-in target (which is a file) and figure it out again + target = Path.Combine(_appPaths.PluginsPath, package.name); + _logger.LogDebug("Installing plugin to {Filename}.", target); // Download to temporary file so that, if interrupted, it won't destroy the existing installation + _logger.LogDebug("Downloading ZIP."); var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions { Url = package.sourceUrl, @@ -536,9 +538,17 @@ namespace Emby.Server.Implementations.Updates // TODO: Validate with a checksum, *properly* + // Check if the target directory already exists, and remove it if so + if (Directory.Exists(target)) + { + _logger.LogDebug("Deleting existing plugin at {Filename}.", target); + Directory.Delete(target, true); + } + // Success - move it to the real target try { + _logger.LogDebug("Extracting ZIP {TempFile} to {Filename}.", tempFile, target); using (var stream = File.OpenRead(tempFile)) { _zipClient.ExtractAllFromZip(stream, target, true); @@ -552,6 +562,7 @@ namespace Emby.Server.Implementations.Updates try { + _logger.LogDebug("Deleting temporary file {Filename}.", tempFile); _fileSystem.DeleteFile(tempFile); } catch (IOException ex) @@ -574,7 +585,18 @@ namespace Emby.Server.Implementations.Updates _applicationHost.RemovePlugin(plugin); var path = plugin.AssemblyFilePath; - _logger.LogInformation("Deleting plugin file {0}", path); + bool is_path_directory = false; + // Check if we have a plugin directory we should remove too + if (Path.GetDirectoryName(plugin.AssemblyFilePath) != _appPaths.PluginsPath) + { + path = Path.GetDirectoryName(plugin.AssemblyFilePath); + is_path_directory = true; + _logger.LogInformation("Deleting plugin directory {0}", path); + } + else + { + _logger.LogInformation("Deleting plugin file {0}", path); + } // Make this case-insensitive to account for possible incorrect assembly naming var file = _fileSystem.GetFilePaths(Path.GetDirectoryName(path)) @@ -585,7 +607,14 @@ namespace Emby.Server.Implementations.Updates path = file; } - _fileSystem.DeleteFile(path); + if (is_path_directory) + { + Directory.Delete(path, true); + } + else + { + _fileSystem.DeleteFile(path); + } var list = _config.Configuration.UninstalledPlugins.ToList(); var filename = Path.GetFileName(path); -- cgit v1.2.3 From 34ab99caf18ee862a1dc29a6afb83253db35c219 Mon Sep 17 00:00:00 2001 From: Anthony Lavado Date: Tue, 16 Apr 2019 01:16:02 -0400 Subject: Move the ProductName to the public endpoint Moves the ProductName field over from the private system/info point to the public one, for easier identification --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 05f8a8a5e..82042f5ca 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1425,7 +1425,6 @@ namespace Emby.Server.Implementations HasPendingRestart = HasPendingRestart, IsShuttingDown = IsShuttingDown, Version = ApplicationVersion, - ProductName = ApplicationProductName, WebSocketPortNumber = HttpPort, CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(), Id = SystemId, @@ -1482,6 +1481,7 @@ namespace Emby.Server.Implementations return new PublicSystemInfo { Version = ApplicationVersion, + ProductName = ApplicationProductName, Id = SystemId, OperatingSystem = OperatingSystem.Id.ToString(), WanAddress = wanAddress, -- cgit v1.2.3 From 8f703f4744b2701843e316210263c8e4cd3256bd Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Thu, 18 Apr 2019 13:19:16 +0200 Subject: Remove unused event Release builds were failing because of this unused event. --- .../Activity/ActivityLogEntryPoint.cs | 14 -------------- Emby.Server.Implementations/ApplicationHost.cs | 21 ++++++++------------- MediaBrowser.Common/IApplicationHost.cs | 5 ----- 3 files changed, 8 insertions(+), 32 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs index 98cd97c31..190e4d55c 100644 --- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs +++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs @@ -83,8 +83,6 @@ namespace Emby.Server.Implementations.Activity _deviceManager.CameraImageUploaded += OnCameraImageUploaded; - _appHost.ApplicationUpdated += OnApplicationUpdated; - return Task.CompletedTask; } @@ -275,16 +273,6 @@ namespace Emby.Server.Implementations.Activity }); } - private void OnApplicationUpdated(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("MessageApplicationUpdatedTo"), e.Argument.versionStr), - Type = NotificationType.ApplicationUpdateInstalled.ToString(), - Overview = e.Argument.description - }); - } - private void OnUserPolicyUpdated(object sender, GenericEventArgs e) { CreateLogEntry(new ActivityLogEntry @@ -460,8 +448,6 @@ namespace Emby.Server.Implementations.Activity _userManager.UserLockedOut -= OnUserLockedOut; _deviceManager.CameraImageUploaded -= OnCameraImageUploaded; - - _appHost.ApplicationUpdated -= OnApplicationUpdated; } /// diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 9804f28cf..0ebbeea57 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -154,11 +154,6 @@ namespace Emby.Server.Implementations /// public event EventHandler HasPendingRestartChanged; - /// - /// Occurs when [application updated]. - /// - public event EventHandler> ApplicationUpdated; - /// /// Gets a value indicating whether this instance has changes that require the entire application to restart. /// @@ -1392,9 +1387,9 @@ namespace Emby.Server.Implementations public async Task GetSystemInfo(CancellationToken cancellationToken) { var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - - string wanAddress; - + + string wanAddress; + if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) { wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); @@ -1451,10 +1446,10 @@ namespace Emby.Server.Implementations public async Task GetPublicSystemInfo(CancellationToken cancellationToken) { - var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); - + var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); + string wanAddress; - + if (string.IsNullOrEmpty(ServerConfigurationManager.Configuration.WanDdns)) { wanAddress = await GetWanApiUrlFromExternal(cancellationToken).ConfigureAwait(false); @@ -1570,9 +1565,9 @@ namespace Emby.Server.Implementations } return string.Format("http://{0}:{1}", host, - ServerConfigurationManager.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture)); + ServerConfigurationManager.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture)); } - + public Task> GetLocalIpAddresses(CancellationToken cancellationToken) { return GetLocalIpAddressesInternal(true, 0, cancellationToken); diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs index 2925a3efd..cb7343440 100644 --- a/MediaBrowser.Common/IApplicationHost.cs +++ b/MediaBrowser.Common/IApplicationHost.cs @@ -25,11 +25,6 @@ namespace MediaBrowser.Common /// The device identifier. string SystemId { get; } - /// - /// Occurs when [application updated]. - /// - event EventHandler> ApplicationUpdated; - /// /// Gets or sets a value indicating whether this instance has pending kernel reload. /// -- cgit v1.2.3 From f62af07381b633d8e7ddf5787d9048fbbf4e3c85 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sat, 20 Apr 2019 12:18:44 +0200 Subject: Handle exception when loading unsupported assembly Fixes #1256 --- Emby.Server.Implementations/ApplicationHost.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 82042f5ca..0295f1098 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1167,7 +1167,7 @@ namespace Emby.Server.Implementations } catch (Exception ex) { - Logger.LogError(ex, "Error loading plugin {pluginName}", plugin.GetType().FullName); + Logger.LogError(ex, "Error loading plugin {PluginName}", plugin.GetType().FullName); return null; } @@ -1348,8 +1348,19 @@ namespace Emby.Server.Implementations { foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.AllDirectories)) { - Logger.LogInformation("Loading assembly {Path}", file); - yield return Assembly.LoadFrom(file); + Assembly plugAss; + try + { + plugAss = Assembly.LoadFrom(file); + } + catch (TypeLoadException ex) + { + Logger.LogError(ex, "Failed to load assembly {Path}", file); + continue; + } + + Logger.LogInformation("Loaded assembly {Assembly} from {Path}", plugAss.FullName, file); + yield return plugAss; } } -- cgit v1.2.3 From 6973182ade7af9173abaf835608327be30b6b162 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sat, 20 Apr 2019 14:02:00 +0200 Subject: Fix more possible exceptions --- Emby.Server.Implementations/ApplicationHost.cs | 32 ++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 0295f1098..5d5a63a63 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1181,10 +1181,32 @@ namespace Emby.Server.Implementations { Logger.LogInformation("Loading assemblies"); - AllConcreteTypes = GetComposablePartAssemblies() - .SelectMany(x => x.ExportedTypes) - .Where(type => type.IsClass && !type.IsAbstract && !type.IsInterface && !type.IsGenericType) - .ToArray(); + AllConcreteTypes = GetTypes(GetComposablePartAssemblies()).ToArray(); + } + + private IEnumerable GetTypes(IEnumerable assemblies) + { + foreach (var ass in assemblies) + { + Type[] exportedTypes; + try + { + exportedTypes = ass.GetExportedTypes(); + } + catch (TypeLoadException ex) + { + Logger.LogError(ex, "Error getting exported types from {Assembly}", ass.FullName); + continue; + } + + foreach (Type type in exportedTypes) + { + if (type.IsClass && !type.IsAbstract && !type.IsInterface && !type.IsGenericType) + { + yield return type; + } + } + } } private CertificateInfo CertificateInfo { get; set; } @@ -1353,7 +1375,7 @@ namespace Emby.Server.Implementations { plugAss = Assembly.LoadFrom(file); } - catch (TypeLoadException ex) + catch (FileLoadException ex) { Logger.LogError(ex, "Failed to load assembly {Path}", file); continue; -- cgit v1.2.3 From 253e72f66720c2f590c443f8347e2187f4f36db0 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 10 Jun 2019 00:53:16 +0200 Subject: Simplify file serving code --- Emby.Server.Implementations/ApplicationHost.cs | 7 +- Emby.Server.Implementations/ResourceFileManager.cs | 30 +---- Jellyfin.Server/CoreAppHost.cs | 7 +- MediaBrowser.Controller/IResourceFileManager.cs | 11 +- MediaBrowser.WebDashboard/Api/DashboardService.cs | 13 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 148 ++++++++------------- 6 files changed, 67 insertions(+), 149 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 53bc85b28..a4e54af2c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -231,11 +231,6 @@ namespace Emby.Server.Implementations /// The server configuration manager. public IServerConfigurationManager ServerConfigurationManager => (IServerConfigurationManager)ConfigurationManager; - protected virtual IResourceFileManager CreateResourceFileManager() - { - return new ResourceFileManager(HttpResultFactory, LoggerFactory, FileSystemManager); - } - /// /// Gets or sets the user manager. /// @@ -886,7 +881,7 @@ namespace Emby.Server.Implementations SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(LibraryManager, LoggerFactory, ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, ProcessFactory); serviceCollection.AddSingleton(SubtitleEncoder); - serviceCollection.AddSingleton(CreateResourceFileManager()); + serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager)); displayPreferencesRepo.Initialize(); diff --git a/Emby.Server.Implementations/ResourceFileManager.cs b/Emby.Server.Implementations/ResourceFileManager.cs index 890d848f4..6eda2b503 100644 --- a/Emby.Server.Implementations/ResourceFileManager.cs +++ b/Emby.Server.Implementations/ResourceFileManager.cs @@ -1,10 +1,8 @@ using System; using System.IO; -using System.Threading.Tasks; using MediaBrowser.Controller; using MediaBrowser.Controller.Net; using MediaBrowser.Model.IO; -using MediaBrowser.Model.Services; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations @@ -13,34 +11,14 @@ namespace Emby.Server.Implementations { private readonly IFileSystem _fileSystem; private readonly ILogger _logger; - private readonly IHttpResultFactory _resultFactory; - public ResourceFileManager( - IHttpResultFactory resultFactory, - ILoggerFactory loggerFactory, - IFileSystem fileSystem) + public ResourceFileManager(ILogger logger, IFileSystem fileSystem) { - _resultFactory = resultFactory; - _logger = loggerFactory.CreateLogger("ResourceManager"); + _logger = logger; _fileSystem = fileSystem; } - public Stream GetResourceFileStream(string basePath, string virtualPath) - { - return _fileSystem.GetFileStream(GetResourcePath(basePath, virtualPath), FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite, true); - } - - public Task GetStaticFileResult(IRequest request, string basePath, string virtualPath, string contentType, TimeSpan? cacheDuration) - { - return _resultFactory.GetStaticFileResult(request, GetResourcePath(basePath, virtualPath)); - } - - public string ReadAllText(string basePath, string virtualPath) - { - return File.ReadAllText(GetResourcePath(basePath, virtualPath)); - } - - private string GetResourcePath(string basePath, string virtualPath) + public string GetResourcePath(string basePath, string virtualPath) { var fullPath = Path.Combine(basePath, virtualPath.Replace('/', Path.DirectorySeparatorChar)); @@ -50,7 +28,7 @@ namespace Emby.Server.Implementations } catch (Exception ex) { - _logger.LogError(ex, "Error in Path.GetFullPath"); + _logger.LogError(ex, "Error retrieving full path"); } // Don't allow file system access outside of the source folder diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index 8e6ed7a7e..b9b0cc382 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; using System.Reflection; using Emby.Server.Implementations; -using Emby.Server.Implementations.HttpServer; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.IO; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; @@ -15,8 +16,8 @@ namespace Jellyfin.Server ILoggerFactory loggerFactory, StartupOptions options, IFileSystem fileSystem, - MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder, - MediaBrowser.Common.Net.INetworkManager networkManager, + IImageEncoder imageEncoder, + INetworkManager networkManager, IConfiguration configuration) : base( applicationPaths, diff --git a/MediaBrowser.Controller/IResourceFileManager.cs b/MediaBrowser.Controller/IResourceFileManager.cs index f70ea6a17..69a51cec8 100644 --- a/MediaBrowser.Controller/IResourceFileManager.cs +++ b/MediaBrowser.Controller/IResourceFileManager.cs @@ -1,16 +1,7 @@ -using System; -using System.IO; -using System.Threading.Tasks; -using MediaBrowser.Model.Services; - namespace MediaBrowser.Controller { public interface IResourceFileManager { - Task GetStaticFileResult(IRequest request, string basePath, string virtualPath, string contentType, TimeSpan? cacheDuration); - - Stream GetResourceFileStream(string basePath, string virtualPath); - - string ReadAllText(string basePath, string virtualPath); + string GetResourcePath(string basePath, string virtualPath); } } diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 58ab2d27b..d2ffd5efc 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -114,8 +114,6 @@ namespace MediaBrowser.WebDashboard.Api private readonly IServerConfigurationManager _serverConfigurationManager; private readonly IFileSystem _fileSystem; - private readonly ILocalizationManager _localization; - private readonly IJsonSerializer _jsonSerializer; private IResourceFileManager _resourceFileManager; /// @@ -126,16 +124,12 @@ namespace MediaBrowser.WebDashboard.Api IResourceFileManager resourceFileManager, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem, - ILocalizationManager localization, - IJsonSerializer jsonSerializer, ILogger logger, IHttpResultFactory resultFactory) { _appHost = appHost; _serverConfigurationManager = serverConfigurationManager; _fileSystem = fileSystem; - _localization = localization; - _jsonSerializer = jsonSerializer; _logger = logger; _resultFactory = resultFactory; _resourceFileManager = resourceFileManager; @@ -205,6 +199,7 @@ namespace MediaBrowser.WebDashboard.Api { return _resultFactory.GetStaticResult(Request, plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.js"), () => Task.FromResult(stream)); } + if (isTemplate) { return _resultFactory.GetStaticResult(Request, plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => Task.FromResult(stream)); @@ -316,7 +311,7 @@ namespace MediaBrowser.WebDashboard.Api // Bounce them to the startup wizard if it hasn't been completed yet if (!_serverConfigurationManager.Configuration.IsStartupWizardCompleted && Request.RawUrl.IndexOf("wizard", StringComparison.OrdinalIgnoreCase) == -1 && - GetPackageCreator(basePath).IsCoreHtml(path)) + PackageCreator.IsCoreHtml(path)) { // But don't redirect if an html import is being requested. if (path.IndexOf("bower_components", StringComparison.OrdinalIgnoreCase) == -1) @@ -355,7 +350,7 @@ namespace MediaBrowser.WebDashboard.Api return await _resultFactory.GetStaticResult(Request, cacheKey, null, cacheDuration, contentType, () => GetResourceStream(basePath, path, localizationCulture)).ConfigureAwait(false); } - return await _resourceFileManager.GetStaticFileResult(Request, basePath, path, contentType, cacheDuration); + return await _resultFactory.GetStaticFileResult(Request, _resourceFileManager.GetResourcePath(basePath, path)); } private string GetLocalizationCulture() @@ -374,7 +369,7 @@ namespace MediaBrowser.WebDashboard.Api private PackageCreator GetPackageCreator(string basePath) { - return new PackageCreator(basePath, _fileSystem, _logger, _serverConfigurationManager, _resourceFileManager); + return new PackageCreator(basePath, _resourceFileManager); } public async Task Get(GetDashboardPackage request) diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 2d0e0e188..133bf61e8 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -1,139 +1,108 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Model.IO; -using Microsoft.Extensions.Logging; namespace MediaBrowser.WebDashboard.Api { public class PackageCreator { - private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; - private readonly IServerConfigurationManager _config; private readonly string _basePath; - private IResourceFileManager _resourceFileManager; + private readonly IResourceFileManager _resourceFileManager; - public PackageCreator(string basePath, IFileSystem fileSystem, ILogger logger, IServerConfigurationManager config, IResourceFileManager resourceFileManager) + public PackageCreator(string basePath, IResourceFileManager resourceFileManager) { - _fileSystem = fileSystem; - _logger = logger; - _config = config; _basePath = basePath; _resourceFileManager = resourceFileManager; } - public async Task GetResource(string virtualPath, + public async Task GetResource( + string virtualPath, string mode, string localizationCulture, string appVersion) { - var resourceStream = GetRawResourceStream(virtualPath); + var resourcePath = _resourceFileManager.GetResourcePath(_basePath, virtualPath); + Stream resourceStream = File.OpenRead(resourcePath); - if (resourceStream != null) + if (resourceStream != null && IsCoreHtml(virtualPath)) { - if (IsFormat(virtualPath, "html")) - { - if (IsCoreHtml(virtualPath)) - { - resourceStream = await ModifyHtml(virtualPath, resourceStream, mode, appVersion, localizationCulture).ConfigureAwait(false); - } - } + resourceStream = await ModifyHtml(virtualPath, resourceStream, mode, appVersion, localizationCulture).ConfigureAwait(false); } return resourceStream; } - /// - /// Determines whether the specified path is HTML. - /// - /// The path. - /// The format. - /// true if the specified path is HTML; otherwise, false. - private static bool IsFormat(string path, string format) - { - return Path.GetExtension(path).EndsWith(format, StringComparison.OrdinalIgnoreCase); - } - - public bool IsCoreHtml(string path) + public static bool IsCoreHtml(string path) { if (path.IndexOf(".template.html", StringComparison.OrdinalIgnoreCase) != -1) { return false; } - return IsFormat(path, "html"); + return string.Equals(Path.GetExtension(path), ".html", StringComparison.OrdinalIgnoreCase); } /// /// Modifies the HTML by adding common meta tags, css and js. /// /// Task{Stream}. - public async Task ModifyHtml(string path, Stream sourceStream, string mode, string appVersion, string localizationCulture) + public async Task ModifyHtml( + string path, + Stream sourceStream, + string mode, + string appVersion, + string localizationCulture) { var isMainIndexPage = string.Equals(path, "index.html", StringComparison.OrdinalIgnoreCase); - using (sourceStream) + string html; + using (var reader = new StreamReader(sourceStream, Encoding.UTF8)) { - string html; - - using (var memoryStream = new MemoryStream()) - { - await sourceStream.CopyToAsync(memoryStream).ConfigureAwait(false); - - var originalBytes = memoryStream.ToArray(); + html = await reader.ReadToEndAsync().ConfigureAwait(false); + } - html = Encoding.UTF8.GetString(originalBytes, 0, originalBytes.Length); + if (isMainIndexPage && !string.IsNullOrWhiteSpace(localizationCulture)) + { + var lang = localizationCulture.Split('-')[0]; - if (isMainIndexPage) - { - if (!string.IsNullOrWhiteSpace(localizationCulture)) - { - var lang = localizationCulture.Split('-').FirstOrDefault(); + html = html.Replace("", "" + GetMetaTags(mode)); + } - if (isMainIndexPage) - { - html = html.Replace("", "" + GetMetaTags(mode)); - } + // Disable embedded scripts from plugins. We'll run them later once resources have loaded + if (html.IndexOf("", "-->"); + } - // Disable embedded scripts from plugins. We'll run them later once resources have loaded - if (html.IndexOf("", "-->"); - } + if (isMainIndexPage) + { + html = html.Replace("", GetCommonJavascript(mode, appVersion) + ""); + } - if (isMainIndexPage) - { - html = html.Replace("", GetCommonJavascript(mode, appVersion) + ""); - } + var bytes = Encoding.UTF8.GetBytes(html); - var bytes = Encoding.UTF8.GetBytes(html); + return new MemoryStream(bytes); - return new MemoryStream(bytes); - } } /// /// Gets the meta tags. /// /// System.String. - private string GetMetaTags(string mode) + private static string GetMetaTags(string mode) { var sb = new StringBuilder(); - if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase) || - string.Equals(mode, "android", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase) + || string.Equals(mode, "android", StringComparison.OrdinalIgnoreCase)) { sb.Append(""); } @@ -147,7 +116,7 @@ namespace MediaBrowser.WebDashboard.Api /// The mode. /// The version. /// System.String. - private string GetCommonJavascript(string mode, string version) + private static string GetCommonJavascript(string mode, string version) { var builder = new StringBuilder(); @@ -156,7 +125,6 @@ namespace MediaBrowser.WebDashboard.Api { builder.AppendFormat("window.appMode='{0}';", mode); } - else { builder.AppendFormat("window.dashboardVersion='{0}';", version); @@ -164,31 +132,21 @@ namespace MediaBrowser.WebDashboard.Api builder.Append(""); - var versionString = string.IsNullOrWhiteSpace(mode) ? "?v=" + version : string.Empty; - - var files = new List(); - - files.Add("scripts/apploader.js" + versionString); - if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { - files.Insert(0, "cordova.js"); + builder.Append(""); } - var tags = files.Select(s => string.Format("", s)).ToArray(); + builder.Append(""); return builder.ToString(); } - - /// - /// Gets the raw resource stream. - /// - private Stream GetRawResourceStream(string virtualPath) - { - return _resourceFileManager.GetResourceFileStream(_basePath, virtualPath); - } - } } -- cgit v1.2.3 From 6ebac0e5002ee79ac4acc5ac2114384436ea0f9a Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 14 Jun 2019 08:20:52 +0200 Subject: Update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Jean-Samuel Aubry-Guzzi --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 4d5fc585d..4fc2d0d9c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1643,7 +1643,7 @@ namespace Emby.Server.Implementations { Url = apiUrl, LogErrorResponseBody = false, - LogErrors = logPing, + LogErrors = LogPing, LogRequest = logPing, BufferContent = false, -- cgit v1.2.3 From af099a9b53616fdc38392c86236d00413cdc14c5 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 14 Jun 2019 08:21:06 +0200 Subject: Update Emby.Server.Implementations/ApplicationHost.cs Co-Authored-By: Jean-Samuel Aubry-Guzzi --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 4fc2d0d9c..f35b322a2 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1644,7 +1644,7 @@ namespace Emby.Server.Implementations Url = apiUrl, LogErrorResponseBody = false, LogErrors = LogPing, - LogRequest = logPing, + LogRequest = LogPing, BufferContent = false, CancellationToken = cancellationToken -- cgit v1.2.3 From 0a5550b13d3a32ae7158dafb38eca6ed94e17d60 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 8 Mar 2019 20:32:14 +0100 Subject: Remove more unused stuff --- Emby.Server.Implementations/ApplicationHost.cs | 11 ++++++----- .../HttpClientManager/HttpClientManager.cs | 18 ------------------ .../LiveTv/Listings/SchedulesDirect.cs | 10 +--------- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 -- .../LiveTv/TunerHosts/SharedHttpStream.cs | 6 ------ MediaBrowser.Common/Net/HttpRequestOptions.cs | 21 +-------------------- 6 files changed, 8 insertions(+), 60 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 5d5a63a63..02d661d15 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Net; +using System.Net.Http; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; @@ -1560,12 +1561,12 @@ namespace Emby.Server.Implementations LogErrorResponseBody = false, LogErrors = false, LogRequest = false, - TimeoutMs = 10000, BufferContent = false, CancellationToken = cancellationToken }).ConfigureAwait(false)) { - return GetWanApiUrl(response.ReadToEnd().Trim()); + string res = await response.ReadToEndAsync().ConfigureAwait(false); + return GetWanApiUrl(res.Trim()); } } catch (Exception ex) @@ -1717,15 +1718,15 @@ namespace Emby.Server.Implementations LogErrorResponseBody = false, LogErrors = LogPing, LogRequest = LogPing, - TimeoutMs = 5000, BufferContent = false, CancellationToken = cancellationToken - }, "POST").ConfigureAwait(false)) + }, HttpMethod.Post).ConfigureAwait(false)) + { using (var reader = new StreamReader(response.Content)) { - var result = reader.ReadToEnd(); + var result = await reader.ReadToEndAsync().ConfigureAwait(false); var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase); _validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid); diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs index 581d6bafd..b82d55d0e 100644 --- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs @@ -352,11 +352,6 @@ namespace Emby.Server.Implementations.HttpClientManager } } - if (options.ResourcePool != null) - { - await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false); - } - if (options.LogRequest) { _logger.LogDebug("HttpClientManager {0}: {1}", httpMethod.ToString(), options.Url); @@ -397,10 +392,6 @@ namespace Emby.Server.Implementations.HttpClientManager { throw GetCancellationException(options, options.CancellationToken, ex); } - finally - { - options.ResourcePool?.Release(); - } } private HttpResponseInfo GetResponseInfo(HttpResponseMessage httpResponse, Stream content, long? contentLength, IDisposable disposable) @@ -483,11 +474,6 @@ namespace Emby.Server.Implementations.HttpClientManager var httpWebRequest = GetRequestMessage(options, HttpMethod.Get); - if (options.ResourcePool != null) - { - await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false); - } - options.Progress.Report(0); if (options.LogRequest) @@ -528,10 +514,6 @@ namespace Emby.Server.Implementations.HttpClientManager throw GetException(ex, options); } - finally - { - options.ResourcePool?.Release(); - } } private Exception GetException(Exception ex, HttpRequestOptions options) diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 4137760d0..f3f747718 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -96,8 +96,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings Url = ApiUrl + "/schedules", UserAgent = UserAgent, CancellationToken = cancellationToken, - // The data can be large so give it some extra time - TimeoutMs = 60000, LogErrorResponseBody = true, RequestContent = requestString }; @@ -115,9 +113,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings Url = ApiUrl + "/programs", UserAgent = UserAgent, CancellationToken = cancellationToken, - LogErrorResponseBody = true, - // The data can be large so give it some extra time - TimeoutMs = 60000 + LogErrorResponseBody = true }; httpOptions.RequestHeaders["token"] = token; @@ -483,8 +479,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings CancellationToken = cancellationToken, RequestContent = imageIdString, LogErrorResponseBody = true, - // The data can be large so give it some extra time - TimeoutMs = 60000 }; try @@ -871,8 +865,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings UserAgent = UserAgent, CancellationToken = cancellationToken, LogErrorResponseBody = true, - // The data can be large so give it some extra time - TimeoutMs = 60000 }; httpOptions.RequestHeaders["token"] = token; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 24b100edd..761275f8f 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -138,7 +138,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Url = string.Format("{0}/discover.json", GetApiUrl(info)), CancellationToken = cancellationToken, - TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(10).TotalMilliseconds), BufferContent = false }, "GET").ConfigureAwait(false)) @@ -191,7 +190,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Url = string.Format("{0}/tuners.html", GetApiUrl(info)), CancellationToken = cancellationToken, - TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds), BufferContent = false })) { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index d74cf3be2..e8b34da0c 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -47,13 +47,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts CancellationToken = CancellationToken.None, BufferContent = false, - // Increase a little bit - TimeoutMs = 30000, - EnableHttpCompression = false, - - LogResponse = true, - LogResponseHeaders = true }; foreach (var header in mediaSource.RequiredHttpHeaders) diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs index 874383fed..38e0ff0f5 100644 --- a/MediaBrowser.Common/Net/HttpRequestOptions.cs +++ b/MediaBrowser.Common/Net/HttpRequestOptions.cs @@ -28,18 +28,13 @@ namespace MediaBrowser.Common.Net get => GetHeaderValue(HeaderNames.Accept); set => RequestHeaders[HeaderNames.Accept] = value; } + /// /// Gets or sets the cancellation token. /// /// The cancellation token. public CancellationToken CancellationToken { get; set; } - /// - /// Gets or sets the resource pool. - /// - /// The resource pool. - public SemaphoreSlim ResourcePool { get; set; } - /// /// Gets or sets the user agent. /// @@ -86,8 +81,6 @@ namespace MediaBrowser.Common.Net public bool LogRequest { get; set; } public bool LogRequestAsDebug { get; set; } public bool LogErrors { get; set; } - public bool LogResponse { get; set; } - public bool LogResponseHeaders { get; set; } public bool LogErrorResponseBody { get; set; } public bool EnableKeepAlive { get; set; } @@ -95,7 +88,6 @@ namespace MediaBrowser.Common.Net public CacheMode CacheMode { get; set; } public TimeSpan CacheLength { get; set; } - public int TimeoutMs { get; set; } public bool EnableDefaultUserAgent { get; set; } public bool AppendCharsetToMimeType { get; set; } @@ -119,17 +111,6 @@ namespace MediaBrowser.Common.Net LogRequest = true; LogErrors = true; CacheMode = CacheMode.None; - - TimeoutMs = 20000; - } - - public void SetPostData(IDictionary values) - { - var strings = values.Keys.Select(key => string.Format("{0}={1}", key, values[key])); - var postContent = string.Join("&", strings.ToArray()); - - RequestContent = postContent; - RequestContentType = "application/x-www-form-urlencoded"; } } -- cgit v1.2.3 From edfd2d0cd959020cdcd2196320850d28ae10094d Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 3 Apr 2019 14:22:17 +0200 Subject: Fix startup --- Emby.Server.Implementations/ApplicationHost.cs | 11 +++++---- .../Data/SqliteUserRepository.cs | 27 ++++++++++------------ 2 files changed, 18 insertions(+), 20 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 62cc6ec47..3aa2dbf9a 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -754,10 +754,6 @@ namespace Emby.Server.Implementations UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, () => UserManager); serviceCollection.AddSingleton(UserDataManager); - UserRepository = GetUserRepository(); - // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it - serviceCollection.AddSingleton(UserRepository); - var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LoggerFactory, JsonSerializer, ApplicationPaths, FileSystemManager); serviceCollection.AddSingleton(displayPreferencesRepo); @@ -767,6 +763,8 @@ namespace Emby.Server.Implementations AuthenticationRepository = GetAuthenticationRepository(); serviceCollection.AddSingleton(AuthenticationRepository); + UserRepository = GetUserRepository(); + UserManager = new UserManager(LoggerFactory, ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, this, JsonSerializer, FileSystemManager); serviceCollection.AddSingleton(UserManager); @@ -807,7 +805,6 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(TVSeriesManager); DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager); - serviceCollection.AddSingleton(DeviceManager); MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, () => MediaEncoder); @@ -1893,8 +1890,12 @@ namespace Emby.Server.Implementations Logger.LogError(ex, "Error disposing {Type}", part.GetType().Name); } } + + UserRepository.Dispose(); } + UserRepository = null; + _disposed = true; } } diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs index e79b3d601..a0c6d2903 100644 --- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs @@ -56,7 +56,7 @@ namespace Emby.Server.Implementations.Data TryMigrateToLocalUsersTable(connection); } - RemoveEmptyPasswordHashes(); + RemoveEmptyPasswordHashes(connection); } } @@ -75,10 +75,12 @@ namespace Emby.Server.Implementations.Data } } - private void RemoveEmptyPasswordHashes() + private void RemoveEmptyPasswordHashes(ManagedConnection connection) { - foreach (var user in RetrieveAllUsers()) + foreach (var row in connection.Query("select id,guid,data from LocalUsersv2")) { + var user = GetUser(row); + // If the user password is the sha1 hash of the empty string, remove it if (!string.Equals(user.Password, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal) && !string.Equals(user.Password, "$SHA1$DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal)) @@ -89,21 +91,16 @@ namespace Emby.Server.Implementations.Data user.Password = null; var serialized = _jsonSerializer.SerializeToBytes(user); - using (var connection = GetConnection()) + connection.RunInTransaction(db => { - connection.RunInTransaction(db => + using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId")) { - using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId")) - { - statement.TryBind("@InternalId", user.InternalId); - statement.TryBind("@data", serialized); - statement.MoveNext(); - } - - }, TransactionMode); - } + statement.TryBind("@InternalId", user.InternalId); + statement.TryBind("@data", serialized); + statement.MoveNext(); + } + }, TransactionMode); } - } /// -- cgit v1.2.3 From d405a400aaa5f9676cc2ce9159b562f94233dcd5 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 14 Jun 2019 16:32:37 +0200 Subject: Fixes issues with HttpClientManager --- Emby.Dlna/PlayTo/SsdpHttpClient.cs | 22 ++-- Emby.Server.Implementations/ApplicationHost.cs | 13 +- .../HttpClientManager/HttpClientManager.cs | 143 ++++++++++----------- .../LiveTv/EmbyTV/DirectRecorder.cs | 2 +- .../LiveTv/Listings/SchedulesDirect.cs | 20 +-- .../LiveTv/Listings/XmlTvListingsProvider.cs | 4 +- .../LiveTv/TunerHosts/SharedHttpStream.cs | 2 +- Jellyfin.Server/Program.cs | 12 ++ MediaBrowser.Common/Net/HttpRequestOptions.cs | 29 +++-- MediaBrowser.Common/Net/HttpResponseInfo.cs | 12 +- 10 files changed, 119 insertions(+), 140 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Dlna/PlayTo/SsdpHttpClient.cs b/Emby.Dlna/PlayTo/SsdpHttpClient.cs index 1ad99fac5..780b0a889 100644 --- a/Emby.Dlna/PlayTo/SsdpHttpClient.cs +++ b/Emby.Dlna/PlayTo/SsdpHttpClient.cs @@ -34,16 +34,13 @@ namespace Emby.Dlna.PlayTo { var cancellationToken = CancellationToken.None; - using (var response = await PostSoapDataAsync(NormalizeServiceUrl(baseUrl, service.ControlUrl), "\"" + service.ServiceType + "#" + command + "\"", postData, header, logRequest, cancellationToken) + var url = NormalizeServiceUrl(baseUrl, service.ControlUrl); + using (var response = await PostSoapDataAsync(url, '\"' + service.ServiceType + '#' + command + '\"', postData, header, logRequest, cancellationToken) .ConfigureAwait(false)) + using (var stream = response.Content) + using (var reader = new StreamReader(stream, Encoding.UTF8)) { - using (var stream = response.Content) - { - using (var reader = new StreamReader(stream, Encoding.UTF8)) - { - return XDocument.Parse(reader.ReadToEnd(), LoadOptions.PreserveWhitespace); - } - } + return XDocument.Parse(reader.ReadToEnd(), LoadOptions.PreserveWhitespace); } } @@ -121,15 +118,18 @@ namespace Emby.Dlna.PlayTo } } - private Task PostSoapDataAsync(string url, + private Task PostSoapDataAsync( + string url, string soapAction, string postData, string header, bool logRequest, CancellationToken cancellationToken) { - if (!soapAction.StartsWith("\"")) - soapAction = "\"" + soapAction + "\""; + if (soapAction[0] != '\"') + { + soapAction = '\"' + soapAction + '\"'; + } var options = new HttpRequestOptions { diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 02d661d15..c64922a93 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -430,7 +430,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. @@ -690,11 +690,6 @@ namespace Emby.Server.Implementations await HttpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, CancellationToken.None).ConfigureAwait(false); } - protected virtual IHttpClient CreateHttpClient() - { - return new HttpClientManager.HttpClientManager(ApplicationPaths, LoggerFactory, FileSystemManager, () => ApplicationUserAgent); - } - public static IStreamHelper StreamHelper { get; set; } /// @@ -720,7 +715,11 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(FileSystemManager); serviceCollection.AddSingleton(); - HttpClient = CreateHttpClient(); + HttpClient = new HttpClientManager.HttpClientManager( + ApplicationPaths, + LoggerFactory.CreateLogger(), + FileSystemManager, + () => ApplicationUserAgent); serviceCollection.AddSingleton(HttpClient); serviceCollection.AddSingleton(NetworkManager); diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs index b82d55d0e..987657bcb 100644 --- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs @@ -23,11 +23,6 @@ namespace Emby.Server.Implementations.HttpClientManager /// public class HttpClientManager : IHttpClient { - /// - /// When one request to a host times out, we'll ban all other requests for this period of time, to prevent scans from stalling - /// - private const int TimeoutSeconds = 30; - /// /// The _logger /// @@ -46,7 +41,7 @@ namespace Emby.Server.Implementations.HttpClientManager /// public HttpClientManager( IApplicationPaths appPaths, - ILoggerFactory loggerFactory, + ILogger logger, IFileSystem fileSystem, Func defaultUserAgentFn) { @@ -55,18 +50,15 @@ namespace Emby.Server.Implementations.HttpClientManager throw new ArgumentNullException(nameof(appPaths)); } - if (loggerFactory == null) + if (logger == null) { - throw new ArgumentNullException(nameof(loggerFactory)); + throw new ArgumentNullException(nameof(logger)); } - _logger = loggerFactory.CreateLogger(nameof(HttpClientManager)); + _logger = logger; _fileSystem = fileSystem; _appPaths = appPaths; _defaultUserAgentFn = defaultUserAgentFn; - - // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c - ServicePointManager.Expect100Continue = false; } /// @@ -83,13 +75,12 @@ namespace Emby.Server.Implementations.HttpClientManager /// if set to true [enable HTTP compression]. /// HttpClient. /// host - private HttpClient GetHttpClient(string url, bool enableHttpCompression) + private HttpClient GetHttpClient(string url) { - var key = GetHostFromUrl(url) + enableHttpCompression; + var key = GetHostFromUrl(url); if (!_httpClients.TryGetValue(key, out var client)) { - client = new HttpClient() { BaseAddress = new Uri(url) @@ -109,24 +100,27 @@ namespace Emby.Server.Implementations.HttpClientManager if (!string.IsNullOrWhiteSpace(userInfo)) { _logger.LogWarning("Found userInfo in url: {0} ... url: {1}", userInfo, url); - url = url.Replace(userInfo + "@", string.Empty); + url = url.Replace(userInfo + '@', string.Empty); } var request = new HttpRequestMessage(method, url); AddRequestHeaders(request, options); - if (options.EnableHttpCompression) + switch (options.DecompressionMethod) { - if (options.DecompressionMethod.HasValue - && options.DecompressionMethod.Value == CompressionMethod.Gzip) - { + case CompressionMethod.Deflate | CompressionMethod.Gzip: request.Headers.Add(HeaderNames.AcceptEncoding, new[] { "gzip", "deflate" }); - } - else - { + break; + case CompressionMethod.Deflate: request.Headers.Add(HeaderNames.AcceptEncoding, "deflate"); - } + break; + case CompressionMethod.Gzip: + request.Headers.Add(HeaderNames.AcceptEncoding, "gzip"); + break; + case 0: + default: + break; } if (options.EnableKeepAlive) @@ -134,20 +128,8 @@ namespace Emby.Server.Implementations.HttpClientManager request.Headers.Add(HeaderNames.Connection, "Keep-Alive"); } - if (!string.IsNullOrEmpty(options.Host)) - { - request.Headers.Add(HeaderNames.Host, options.Host); - } - - if (!string.IsNullOrEmpty(options.Referer)) - { - request.Headers.Add(HeaderNames.Referer, options.Referer); - } - //request.Headers.Add(HeaderNames.CacheControl, "no-cache"); - //request.Headers.Add(HeaderNames., options.TimeoutMs; - /* if (!string.IsNullOrWhiteSpace(userInfo)) { @@ -188,9 +170,7 @@ namespace Emby.Server.Implementations.HttpClientManager /// The options. /// Task{HttpResponseInfo}. public Task GetResponse(HttpRequestOptions options) - { - return SendAsync(options, HttpMethod.Get); - } + => SendAsync(options, HttpMethod.Get); /// /// Performs a GET request and returns the resulting stream @@ -324,18 +304,29 @@ namespace Emby.Server.Implementations.HttpClientManager options.CancellationToken.ThrowIfCancellationRequested(); - var client = GetHttpClient(options.Url, options.EnableHttpCompression); + var client = GetHttpClient(options.Url); var httpWebRequest = GetRequestMessage(options, httpMethod); - if (options.RequestContentBytes != null || - !string.IsNullOrEmpty(options.RequestContent) || - httpMethod == HttpMethod.Post) + if (options.RequestContentBytes != null + || !string.IsNullOrEmpty(options.RequestContent) + || httpMethod == HttpMethod.Post) { try { - httpWebRequest.Content = new StringContent(Encoding.UTF8.GetString(options.RequestContentBytes) ?? options.RequestContent ?? string.Empty); - + if (options.RequestContentBytes != null) + { + httpWebRequest.Content = new ByteArrayContent(options.RequestContentBytes); + } + else if (options.RequestContent != null) + { + httpWebRequest.Content = new StringContent(options.RequestContent); + } + else + { + httpWebRequest.Content = new ByteArrayContent(Array.Empty()); + } + /* var contentType = options.RequestContentType ?? "application/x-www-form-urlencoded"; if (options.AppendCharsetToMimeType) @@ -343,8 +334,11 @@ namespace Emby.Server.Implementations.HttpClientManager contentType = contentType.TrimEnd(';') + "; charset=\"utf-8\""; } - httpWebRequest.Headers.Add(HeaderNames.ContentType, contentType); - await client.SendAsync(httpWebRequest).ConfigureAwait(false); + httpWebRequest.Headers.Add(HeaderNames.ContentType, contentType);*/ + using (var response = await client.SendAsync(httpWebRequest).ConfigureAwait(false)) + { + return await HandleResponseAsync(response, options).ConfigureAwait(false); + } } catch (Exception ex) { @@ -374,18 +368,7 @@ namespace Emby.Server.Implementations.HttpClientManager using (var response = await client.SendAsync(httpWebRequest).ConfigureAwait(false)) { - await EnsureSuccessStatusCode(response, options).ConfigureAwait(false); - - options.CancellationToken.ThrowIfCancellationRequested(); - - using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) - { - var memoryStream = new MemoryStream(); - await stream.CopyToAsync(memoryStream).ConfigureAwait(false); - memoryStream.Position = 0; - - return GetResponseInfo(response, memoryStream, memoryStream.Length, null); - } + return await HandleResponseAsync(response, options).ConfigureAwait(false); } } catch (OperationCanceledException ex) @@ -394,9 +377,25 @@ namespace Emby.Server.Implementations.HttpClientManager } } - private HttpResponseInfo GetResponseInfo(HttpResponseMessage httpResponse, Stream content, long? contentLength, IDisposable disposable) + private async Task HandleResponseAsync(HttpResponseMessage response, HttpRequestOptions options) + { + await EnsureSuccessStatusCode(response, options).ConfigureAwait(false); + + options.CancellationToken.ThrowIfCancellationRequested(); + + using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) + { + var memoryStream = new MemoryStream(); + await stream.CopyToAsync(memoryStream, 81920, options.CancellationToken).ConfigureAwait(false); + memoryStream.Position = 0; + + return GetResponseInfo(response, memoryStream, memoryStream.Length); + } + } + + private HttpResponseInfo GetResponseInfo(HttpResponseMessage httpResponse, Stream content, long? contentLength) { - var responseInfo = new HttpResponseInfo(disposable) + var responseInfo = new HttpResponseInfo() { Content = content, StatusCode = httpResponse.StatusCode, @@ -433,16 +432,14 @@ namespace Emby.Server.Implementations.HttpClientManager private static void SetHeaders(HttpContentHeaders headers, HttpResponseInfo responseInfo) { - foreach (var key in headers) + foreach (var header in headers) { - responseInfo.Headers[key.Key] = string.Join(", ", key.Value); + responseInfo.Headers[header.Key] = string.Join(", ", header.Value); } } public Task Post(HttpRequestOptions options) - { - return SendAsync(options, HttpMethod.Post); - } + => SendAsync(options, HttpMethod.Post); /// /// Downloads the contents of a given url into a temporary location @@ -451,10 +448,8 @@ namespace Emby.Server.Implementations.HttpClientManager /// Task{System.String}. public async Task GetTempFile(HttpRequestOptions options) { - using (var response = await GetTempFileResponse(options).ConfigureAwait(false)) - { - return response.TempFilePath; - } + var response = await GetTempFileResponse(options).ConfigureAwait(false); + return response.TempFilePath; } public async Task GetTempFileResponse(HttpRequestOptions options) @@ -481,13 +476,13 @@ namespace Emby.Server.Implementations.HttpClientManager _logger.LogDebug("HttpClientManager.GetTempFileResponse url: {0}", options.Url); } - var client = GetHttpClient(options.Url, options.EnableHttpCompression); + var client = GetHttpClient(options.Url); try { options.CancellationToken.ThrowIfCancellationRequested(); - using (var response = (await client.SendAsync(httpWebRequest).ConfigureAwait(false))) + using (var response = (await client.SendAsync(httpWebRequest, options.CancellationToken).ConfigureAwait(false))) { await EnsureSuccessStatusCode(response, options).ConfigureAwait(false); @@ -530,7 +525,7 @@ namespace Emby.Server.Implementations.HttpClientManager { if (options.LogErrors) { - _logger.LogError(webException, "Error {status} getting response from {url}", webException.Status, options.Url); + _logger.LogError(webException, "Error {Status} getting response from {Url}", webException.Status, options.Url); } var exception = new HttpException(webException.Message, webException); @@ -565,7 +560,7 @@ namespace Emby.Server.Implementations.HttpClientManager if (options.LogErrors) { - _logger.LogError(ex, "Error getting response from {url}", options.Url); + _logger.LogError(ex, "Error getting response from {Url}", options.Url); } return ex; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs index dd636e6cd..8dee7046e 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs @@ -71,7 +71,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV UserAgent = "Emby/3.0", // Shouldn't matter but may cause issues - EnableHttpCompression = false + DecompressionMethod = CompressionMethod.None }; using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET").ConfigureAwait(false)) diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index f3f747718..f5dffc22a 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -627,15 +627,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings ListingsProviderInfo providerInfo) { // Schedules direct requires that the client support compression and will return a 400 response without it - options.EnableHttpCompression = true; - - // On windows 7 under .net core, this header is not getting added -#if NETSTANDARD2_0 - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - { - options.RequestHeaders[HeaderNames.AcceptEncoding] = "deflate"; - } -#endif + options.DecompressionMethod = CompressionMethod.Deflate; try { @@ -665,15 +657,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings ListingsProviderInfo providerInfo) { // Schedules direct requires that the client support compression and will return a 400 response without it - options.EnableHttpCompression = true; - - // On windows 7 under .net core, this header is not getting added -#if NETSTANDARD2_0 - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - { - options.RequestHeaders[HeaderNames.AcceptEncoding] = "deflate"; - } -#endif + options.DecompressionMethod = CompressionMethod.Deflate; try { diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index 69b10e6da..d39c91783 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -73,11 +73,9 @@ namespace Emby.Server.Implementations.LiveTv.Listings CancellationToken = cancellationToken, Url = path, Progress = new SimpleProgress(), - DecompressionMethod = CompressionMethod.Gzip, - // It's going to come back gzipped regardless of this value // So we need to make sure the decompression method is set to gzip - EnableHttpCompression = true, + DecompressionMethod = CompressionMethod.Gzip, UserAgent = "Emby/3.0" diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index e8b34da0c..60c914898 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -47,7 +47,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts CancellationToken = CancellationToken.None, BufferContent = false, - EnableHttpCompression = false, + DecompressionMethod = CompressionMethod.None, }; foreach (var header in mediaSource.RequiredHttpHeaders) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index d4b10c8c8..95ce08f26 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -118,8 +118,20 @@ namespace Jellyfin.Server SQLitePCL.Batteries_V2.Init(); + // Increase the max http request limit + // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others. + ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); + + // Disable the "Expect: 100-Continue" header by default + // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c + ServicePointManager.Expect100Continue = false; + +// CA5359: Do Not Disable Certificate Validation +#pragma warning disable CA5359 + // Allow all https requests ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; }); +#pragma warning restore CA5359 var fileSystem = new ManagedFileSystem(_loggerFactory, appPaths); diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs index 38e0ff0f5..432e389d3 100644 --- a/MediaBrowser.Common/Net/HttpRequestOptions.cs +++ b/MediaBrowser.Common/Net/HttpRequestOptions.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading; using Microsoft.Net.Http.Headers; @@ -17,7 +16,7 @@ namespace MediaBrowser.Common.Net /// The URL. public string Url { get; set; } - public CompressionMethod? DecompressionMethod { get; set; } + public CompressionMethod DecompressionMethod { get; set; } /// /// Gets or sets the accept header. @@ -49,13 +48,21 @@ namespace MediaBrowser.Common.Net /// Gets or sets the referrer. /// /// The referrer. - public string Referer { get; set; } + public string Referer + { + get => GetHeaderValue(HeaderNames.Referer); + set => RequestHeaders[HeaderNames.Referer] = value; + } /// /// Gets or sets the host. /// /// The host. - public string Host { get; set; } + public string Host + { + get => GetHeaderValue(HeaderNames.Host); + set => RequestHeaders[HeaderNames.Host] = value; + } /// /// Gets or sets the progress. @@ -63,12 +70,6 @@ namespace MediaBrowser.Common.Net /// The progress. public IProgress Progress { get; set; } - /// - /// Gets or sets a value indicating whether [enable HTTP compression]. - /// - /// true if [enable HTTP compression]; otherwise, false. - public bool EnableHttpCompression { get; set; } - public Dictionary RequestHeaders { get; private set; } public string RequestContentType { get; set; } @@ -104,13 +105,12 @@ namespace MediaBrowser.Common.Net /// public HttpRequestOptions() { - EnableHttpCompression = true; - RequestHeaders = new Dictionary(StringComparer.OrdinalIgnoreCase); LogRequest = true; LogErrors = true; CacheMode = CacheMode.None; + DecompressionMethod = CompressionMethod.Deflate; } } @@ -122,7 +122,8 @@ namespace MediaBrowser.Common.Net public enum CompressionMethod { - Deflate, - Gzip + None = 0b00000001, + Deflate = 0b00000010, + Gzip = 0b00000100 } } diff --git a/MediaBrowser.Common/Net/HttpResponseInfo.cs b/MediaBrowser.Common/Net/HttpResponseInfo.cs index 186674167..aa496adac 100644 --- a/MediaBrowser.Common/Net/HttpResponseInfo.cs +++ b/MediaBrowser.Common/Net/HttpResponseInfo.cs @@ -52,13 +52,6 @@ namespace MediaBrowser.Common.Net /// The headers. public Dictionary Headers { get; set; } - private readonly IDisposable _disposable; - - public HttpResponseInfo(IDisposable disposable) - { - _disposable = disposable; - Headers = new Dictionary(StringComparer.OrdinalIgnoreCase); - } public HttpResponseInfo() { Headers = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -66,10 +59,7 @@ namespace MediaBrowser.Common.Net public void Dispose() { - if (_disposable != null) - { - _disposable.Dispose(); - } + // Only IDisposable for backwards compatibility } } } -- cgit v1.2.3 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.Dlna/Main/DlnaEntryPoint.cs | 3 +- Emby.Dlna/PlayTo/PlayToManager.cs | 4 +- Emby.Server.Implementations/ApplicationHost.cs | 53 +++-- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 9 +- .../TunerHosts/HdHomerun/HdHomerunManager.cs | 16 +- .../TunerHosts/HdHomerun/HdHomerunUdpStream.cs | 17 +- Emby.Server.Implementations/Net/SocketFactory.cs | 14 +- Emby.Server.Implementations/Net/UdpSocket.cs | 30 +-- .../Networking/NetworkManager.cs | 232 +++++---------------- Emby.Server.Implementations/Udp/UdpServer.cs | 15 +- Jellyfin.Server/Program.cs | 2 +- MediaBrowser.Common/Net/INetworkManager.cs | 14 +- MediaBrowser.Controller/IServerApplicationHost.cs | 6 +- MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs | 4 +- MediaBrowser.Model/Net/ISocket.cs | 5 +- MediaBrowser.Model/Net/ISocketFactory.cs | 11 +- MediaBrowser.Model/Net/IpAddressInfo.cs | 38 ---- MediaBrowser.Model/Net/IpEndPointInfo.cs | 29 --- MediaBrowser.Model/Net/SocketReceiveResult.cs | 6 +- RSSDP/DeviceAvailableEventArgs.cs | 53 +++-- RSSDP/ISsdpCommunicationsServer.cs | 8 +- RSSDP/RequestReceivedEventArgs.cs | 12 +- RSSDP/ResponseReceivedEventArgs.cs | 12 +- RSSDP/SsdpCommunicationsServer.cs | 52 ++--- RSSDP/SsdpDevice.cs | 3 - RSSDP/SsdpDeviceLocator.cs | 17 +- RSSDP/SsdpDevicePublisher.cs | 32 ++- RSSDP/SsdpRootDevice.cs | 10 +- 28 files changed, 262 insertions(+), 445 deletions(-) delete mode 100644 MediaBrowser.Model/Net/IpAddressInfo.cs delete mode 100644 MediaBrowser.Model/Net/IpEndPointInfo.cs (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 5fbe70ded..206a873e1 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -1,4 +1,5 @@ using System; +using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using Emby.Dlna.PlayTo; @@ -247,7 +248,7 @@ namespace Emby.Dlna.Main foreach (var address in addresses) { - if (address.AddressFamily == IpAddressFamily.InterNetworkV6) + if (address.AddressFamily == AddressFamily.InterNetworkV6) { // Not support IPv6 right now continue; diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index 28e70d046..c0a441871 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Net; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Extensions; @@ -14,7 +15,6 @@ using MediaBrowser.Controller.Session; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Events; using MediaBrowser.Model.Globalization; -using MediaBrowser.Model.Net; using MediaBrowser.Model.Session; using Microsoft.Extensions.Logging; @@ -172,7 +172,7 @@ namespace Emby.Dlna.PlayTo _sessionManager.UpdateDeviceName(sessionInfo.Id, deviceName); string serverAddress; - if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Any)) + if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IPAddress.Any) || info.LocalIpAddress.Equals(IPAddress.IPv6Any)) { serverAddress = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false); } diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 120aade39..c6ba2326a 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; } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 761275f8f..ed524cae3 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; @@ -11,7 +12,6 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; @@ -20,7 +20,6 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Net; using MediaBrowser.Model.Serialization; -using MediaBrowser.Model.System; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun @@ -259,7 +258,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun using (var manager = new HdHomerunManager(_socketFactory, Logger)) { // Legacy HdHomeruns are IPv4 only - var ipInfo = _networkManager.ParseIpAddress(uri.Host); + var ipInfo = IPAddress.Parse(uri.Host); for (int i = 0; i < model.TunerCount; ++i) { @@ -675,13 +674,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun // Need a way to set the Receive timeout on the socket otherwise this might never timeout? try { - await udpClient.SendToAsync(discBytes, 0, discBytes.Length, new IpEndPointInfo(new IpAddressInfo("255.255.255.255", IpAddressFamily.InterNetwork), 65001), cancellationToken); + await udpClient.SendToAsync(discBytes, 0, discBytes.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 65001), cancellationToken); var receiveBuffer = new byte[8192]; while (!cancellationToken.IsCancellationRequested) { var response = await udpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, cancellationToken).ConfigureAwait(false); - var deviceIp = response.RemoteEndPoint.IpAddress.Address; + var deviceIp = response.RemoteEndPoint.Address.ToString(); // check to make sure we have enough bytes received to be a valid message and make sure the 2nd byte is the discover reply byte if (response.ReceivedBytes > 13 && response.Buffer[1] == 3) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs index 2205c0ecc..6e79441da 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs @@ -89,7 +89,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun private uint? _lockkey = null; private int _activeTuner = -1; private readonly ISocketFactory _socketFactory; - private IpAddressInfo _remoteIp; + private IPAddress _remoteIp; private ILogger _logger; private ISocket _currentTcpSocket; @@ -114,7 +114,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun } } - public async Task CheckTunerAvailability(IpAddressInfo remoteIp, int tuner, CancellationToken cancellationToken) + public async Task CheckTunerAvailability(IPAddress remoteIp, int tuner, CancellationToken cancellationToken) { using (var socket = _socketFactory.CreateTcpSocket(remoteIp, HdHomeRunPort)) { @@ -122,9 +122,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun } } - private static async Task CheckTunerAvailability(ISocket socket, IpAddressInfo remoteIp, int tuner, CancellationToken cancellationToken) + private static async Task CheckTunerAvailability(ISocket socket, IPAddress remoteIp, int tuner, CancellationToken cancellationToken) { - var ipEndPoint = new IpEndPointInfo(remoteIp, HdHomeRunPort); + var ipEndPoint = new IPEndPoint(remoteIp, HdHomeRunPort); var lockkeyMsg = CreateGetMessage(tuner, "lockkey"); await socket.SendToAsync(lockkeyMsg, 0, lockkeyMsg.Length, ipEndPoint, cancellationToken); @@ -137,7 +137,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun return string.Equals(returnVal, "none", StringComparison.OrdinalIgnoreCase); } - public async Task StartStreaming(IpAddressInfo remoteIp, IPAddress localIp, int localPort, IHdHomerunChannelCommands commands, int numTuners, CancellationToken cancellationToken) + public async Task StartStreaming(IPAddress remoteIp, IPAddress localIp, int localPort, IHdHomerunChannelCommands commands, int numTuners, CancellationToken cancellationToken) { _remoteIp = remoteIp; @@ -154,7 +154,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun var lockKeyValue = _lockkey.Value; - var ipEndPoint = new IpEndPointInfo(_remoteIp, HdHomeRunPort); + var ipEndPoint = new IPEndPoint(_remoteIp, HdHomeRunPort); for (int i = 0; i < numTuners; ++i) { @@ -217,7 +217,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun foreach (Tuple command in commandList) { var channelMsg = CreateSetMessage(_activeTuner, command.Item1, command.Item2, _lockkey); - await tcpClient.SendToAsync(channelMsg, 0, channelMsg.Length, new IpEndPointInfo(_remoteIp, HdHomeRunPort), cancellationToken).ConfigureAwait(false); + await tcpClient.SendToAsync(channelMsg, 0, channelMsg.Length, new IPEndPoint(_remoteIp, HdHomeRunPort), cancellationToken).ConfigureAwait(false); var response = await tcpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, cancellationToken).ConfigureAwait(false); // parse response to make sure it worked if (!ParseReturnMessage(response.Buffer, response.ReceivedBytes, out string returnVal)) @@ -242,7 +242,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { _logger.LogInformation("HdHomerunManager.ReleaseLockkey {0}", lockKeyValue); - var ipEndPoint = new IpEndPointInfo(_remoteIp, HdHomeRunPort); + var ipEndPoint = new IPEndPoint(_remoteIp, HdHomeRunPort); var releaseTarget = CreateSetMessage(_activeTuner, "target", "none", lockKeyValue); await tcpClient.SendToAsync(releaseTarget, 0, releaseTarget.Length, ipEndPoint, CancellationToken.None).ConfigureAwait(false); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index 7f426ea31..ec708cf20 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -25,7 +25,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun private readonly int _numTuners; private readonly INetworkManager _networkManager; - public HdHomerunUdpStream(MediaSourceInfo mediaSource, TunerHostInfo tunerHostInfo, string originalStreamId, IHdHomerunChannelCommands channelCommands, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, MediaBrowser.Model.Net.ISocketFactory socketFactory, INetworkManager networkManager) + public HdHomerunUdpStream( + MediaSourceInfo mediaSource, + TunerHostInfo tunerHostInfo, + string originalStreamId, + IHdHomerunChannelCommands channelCommands, + int numTuners, + IFileSystem fileSystem, + IHttpClient httpClient, + ILogger logger, + IServerApplicationPaths appPaths, + IServerApplicationHost appHost, + MediaBrowser.Model.Net.ISocketFactory socketFactory, + INetworkManager networkManager) : base(mediaSource, tunerHostInfo, fileSystem, logger, appPaths) { _appHost = appHost; @@ -58,7 +70,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun Logger.LogInformation("Opening HDHR UDP Live stream from {host}", uri.Host); var remoteAddress = IPAddress.Parse(uri.Host); - var embyRemoteAddress = _networkManager.ParseIpAddress(uri.Host); IPAddress localAddress = null; using (var tcpSocket = CreateSocket(remoteAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { @@ -81,7 +92,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun try { // send url to start streaming - await hdHomerunManager.StartStreaming(embyRemoteAddress, localAddress, localPort, _channelCommands, _numTuners, openCancellationToken).ConfigureAwait(false); + await hdHomerunManager.StartStreaming(remoteAddress, localAddress, localPort, _channelCommands, _numTuners, openCancellationToken).ConfigureAwait(false); } catch (Exception ex) { diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index 492f48abe..42ffa4e22 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -16,14 +16,14 @@ namespace Emby.Server.Implementations.Net // but that wasn't really the point so kept to YAGNI principal for now, even if the // interfaces are a bit ugly, specific and make assumptions. - public ISocket CreateTcpSocket(IpAddressInfo remoteAddress, int remotePort) + public ISocket CreateTcpSocket(IPAddress remoteAddress, int remotePort) { if (remotePort < 0) { throw new ArgumentException("remotePort cannot be less than zero.", nameof(remotePort)); } - var addressFamily = remoteAddress.AddressFamily == IpAddressFamily.InterNetwork + var addressFamily = remoteAddress.AddressFamily == AddressFamily.InterNetwork ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6; @@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Net try { - return new UdpSocket(retVal, new IpEndPointInfo(remoteAddress, remotePort)); + return new UdpSocket(retVal, new IPEndPoint(remoteAddress, remotePort)); } catch { @@ -102,7 +102,7 @@ namespace Emby.Server.Implementations.Net /// Creates a new UDP acceptSocket that is a member of the SSDP multicast local admin group and binds it to the specified local port. /// /// An implementation of the interface used by RSSDP components to perform acceptSocket operations. - public ISocket CreateSsdpUdpSocket(IpAddressInfo localIpAddress, int localPort) + public ISocket CreateSsdpUdpSocket(IPAddress localIpAddress, int localPort) { if (localPort < 0) { @@ -115,10 +115,8 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); - var localIp = NetworkManager.ToIPAddress(localIpAddress); - - retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIp)); - return new UdpSocket(retVal, localPort, localIp); + retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIpAddress)); + return new UdpSocket(retVal, localPort, localIpAddress); } catch { diff --git a/Emby.Server.Implementations/Net/UdpSocket.cs b/Emby.Server.Implementations/Net/UdpSocket.cs index 6c55085c8..2908ee9af 100644 --- a/Emby.Server.Implementations/Net/UdpSocket.cs +++ b/Emby.Server.Implementations/Net/UdpSocket.cs @@ -19,7 +19,7 @@ namespace Emby.Server.Implementations.Net public Socket Socket => _socket; - public IpAddressInfo LocalIPAddress { get; } + public IPAddress LocalIPAddress { get; } private readonly SocketAsyncEventArgs _receiveSocketAsyncEventArgs = new SocketAsyncEventArgs() { @@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Net _socket = socket; _localPort = localPort; - LocalIPAddress = NetworkManager.ToIpAddressInfo(ip); + LocalIPAddress = ip; _socket.Bind(new IPEndPoint(ip, _localPort)); @@ -71,7 +71,7 @@ namespace Emby.Server.Implementations.Net { Buffer = e.Buffer, ReceivedBytes = e.BytesTransferred, - RemoteEndPoint = ToIpEndPointInfo(e.RemoteEndPoint as IPEndPoint), + RemoteEndPoint = e.RemoteEndPoint as IPEndPoint, LocalIPAddress = LocalIPAddress }); } @@ -100,12 +100,12 @@ namespace Emby.Server.Implementations.Net } } - public UdpSocket(Socket socket, IpEndPointInfo endPoint) + public UdpSocket(Socket socket, IPEndPoint endPoint) { if (socket == null) throw new ArgumentNullException(nameof(socket)); _socket = socket; - _socket.Connect(NetworkManager.ToIPEndPoint(endPoint)); + _socket.Connect(endPoint); InitReceiveSocketAsyncEventArgs(); } @@ -140,7 +140,7 @@ namespace Emby.Server.Implementations.Net return new SocketReceiveResult { ReceivedBytes = receivedBytes, - RemoteEndPoint = ToIpEndPointInfo((IPEndPoint)remoteEndPoint), + RemoteEndPoint = (IPEndPoint)remoteEndPoint, Buffer = buffer, LocalIPAddress = LocalIPAddress }; @@ -191,7 +191,7 @@ namespace Emby.Server.Implementations.Net return ReceiveAsync(buffer, 0, buffer.Length, cancellationToken); } - public Task SendToAsync(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, CancellationToken cancellationToken) + public Task SendToAsync(byte[] buffer, int offset, int size, IPEndPoint endPoint, CancellationToken cancellationToken) { ThrowIfDisposed(); @@ -227,13 +227,11 @@ namespace Emby.Server.Implementations.Net return taskCompletion.Task; } - public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, AsyncCallback callback, object state) + public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, IPEndPoint endPoint, AsyncCallback callback, object state) { ThrowIfDisposed(); - var ipEndPoint = NetworkManager.ToIPEndPoint(endPoint); - - return _socket.BeginSendTo(buffer, offset, size, SocketFlags.None, ipEndPoint, callback, state); + return _socket.BeginSendTo(buffer, offset, size, SocketFlags.None, endPoint, callback, state); } public int EndSendTo(IAsyncResult result) @@ -268,15 +266,5 @@ namespace Emby.Server.Implementations.Net _disposed = true; } - - private static IpEndPointInfo ToIpEndPointInfo(IPEndPoint endpoint) - { - if (endpoint == null) - { - return null; - } - - return NetworkManager.ToIpEndPointInfo(endpoint); - } } } diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index c102f9eb5..3cacacf07 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -9,55 +9,38 @@ using System.Threading.Tasks; using MediaBrowser.Common.Net; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; -using MediaBrowser.Model.System; using Microsoft.Extensions.Logging; -using OperatingSystem = MediaBrowser.Common.System.OperatingSystem; namespace Emby.Server.Implementations.Networking { public class NetworkManager : INetworkManager { - protected ILogger Logger { get; private set; } + private readonly ILogger _logger; - public event EventHandler NetworkChanged; - public Func LocalSubnetsFn { get; set; } + private IPAddress[] _localIpAddresses; + private readonly object _localIpAddressSyncLock = new object(); - public NetworkManager(ILoggerFactory loggerFactory) + public NetworkManager(ILogger logger) { - Logger = loggerFactory.CreateLogger(nameof(NetworkManager)); - - // In FreeBSD these events cause a crash - if (OperatingSystem.Id != OperatingSystemId.BSD) - { - try - { - NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged; - } - catch (Exception ex) - { - Logger.LogError(ex, "Error binding to NetworkAddressChanged event"); - } + _logger = logger; - try - { - NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged; - } - catch (Exception ex) - { - Logger.LogError(ex, "Error binding to NetworkChange_NetworkAvailabilityChanged event"); - } - } + NetworkChange.NetworkAddressChanged += OnNetworkAddressChanged; + NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged; } - private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) + public Func LocalSubnetsFn { get; set; } + + public event EventHandler NetworkChanged; + + private void OnNetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) { - Logger.LogDebug("NetworkAvailabilityChanged"); + _logger.LogDebug("NetworkAvailabilityChanged"); OnNetworkChanged(); } - private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e) + private void OnNetworkAddressChanged(object sender, EventArgs e) { - Logger.LogDebug("NetworkAddressChanged"); + _logger.LogDebug("NetworkAddressChanged"); OnNetworkChanged(); } @@ -68,39 +51,35 @@ namespace Emby.Server.Implementations.Networking _localIpAddresses = null; _macAddresses = null; } + if (NetworkChanged != null) { NetworkChanged(this, EventArgs.Empty); } } - private IpAddressInfo[] _localIpAddresses; - private readonly object _localIpAddressSyncLock = new object(); - - public IpAddressInfo[] GetLocalIpAddresses(bool ignoreVirtualInterface = true) + public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true) { lock (_localIpAddressSyncLock) { if (_localIpAddresses == null) { - var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).Result.Select(ToIpAddressInfo).ToArray(); + var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).ToArray(); _localIpAddresses = addresses; - - return addresses; } + return _localIpAddresses; } } - private async Task> GetLocalIpAddressesInternal(bool ignoreVirtualInterface) + private List GetLocalIpAddressesInternal(bool ignoreVirtualInterface) { - var list = GetIPsDefault(ignoreVirtualInterface) - .ToList(); + var list = GetIPsDefault(ignoreVirtualInterface).ToList(); if (list.Count == 0) { - list.AddRange(await GetLocalIpAddressesFallback().ConfigureAwait(false)); + list = GetLocalIpAddressesFallback().GetAwaiter().GetResult().ToList(); } var listClone = list.ToList(); @@ -351,13 +330,13 @@ namespace Emby.Server.Implementations.Networking try { var host = uri.DnsSafeHost; - Logger.LogDebug("Resolving host {0}", host); + _logger.LogDebug("Resolving host {0}", host); address = GetIpAddresses(host).Result.FirstOrDefault(); if (address != null) { - Logger.LogDebug("{0} resolved to {1}", host, address); + _logger.LogDebug("{0} resolved to {1}", host, address); return IsInLocalNetworkInternal(address.ToString(), false); } @@ -368,7 +347,7 @@ namespace Emby.Server.Implementations.Networking } catch (Exception ex) { - Logger.LogError(ex, "Error resolving hostname"); + _logger.LogError(ex, "Error resolving hostname"); } } } @@ -381,56 +360,41 @@ namespace Emby.Server.Implementations.Networking return Dns.GetHostAddressesAsync(hostName); } - private List GetIPsDefault(bool ignoreVirtualInterface) + private IEnumerable GetIPsDefault(bool ignoreVirtualInterface) { - NetworkInterface[] interfaces; + IEnumerable interfaces; try { - var validStatuses = new[] { OperationalStatus.Up, OperationalStatus.Unknown }; - interfaces = NetworkInterface.GetAllNetworkInterfaces() - .Where(i => validStatuses.Contains(i.OperationalStatus)) - .ToArray(); + .Where(x => x.OperationalStatus == OperationalStatus.Up + || x.OperationalStatus == OperationalStatus.Unknown); } - catch (Exception ex) + catch (NetworkInformationException ex) { - Logger.LogError(ex, "Error in GetAllNetworkInterfaces"); - return new List(); + _logger.LogError(ex, "Error in GetAllNetworkInterfaces"); + return Enumerable.Empty(); } return interfaces.SelectMany(network => { + var ipProperties = network.GetIPProperties(); - try - { - // suppress logging because it might be causing nas device wake up - //logger.LogDebug("Querying interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus); - - var ipProperties = network.GetIPProperties(); - - // Try to exclude virtual adapters - // http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms - var addr = ipProperties.GatewayAddresses.FirstOrDefault(); - if (addr == null || ignoreVirtualInterface && string.Equals(addr.Address.ToString(), "0.0.0.0", StringComparison.OrdinalIgnoreCase)) - { - return new List(); - } - - return ipProperties.UnicastAddresses - .Select(i => i.Address) - .Where(i => i.AddressFamily == AddressFamily.InterNetwork || i.AddressFamily == AddressFamily.InterNetworkV6) - .ToList(); - } - catch (Exception ex) + // Try to exclude virtual adapters + // http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms + var addr = ipProperties.GatewayAddresses.FirstOrDefault(); + if (addr == null + || (ignoreVirtualInterface + && (addr.Address.Equals(IPAddress.Any) || addr.Address.Equals(IPAddress.IPv6Any)))) { - Logger.LogError(ex, "Error querying network interface"); - return new List(); + return Enumerable.Empty(); } + return ipProperties.UnicastAddresses + .Select(i => i.Address) + .Where(i => i.AddressFamily == AddressFamily.InterNetwork || i.AddressFamily == AddressFamily.InterNetworkV6); }).GroupBy(i => i.ToString()) - .Select(x => x.First()) - .ToList(); + .Select(x => x.First()); } private static async Task> GetLocalIpAddressesFallback() @@ -612,32 +576,10 @@ namespace Emby.Server.Implementations.Networking return hosts[0]; } - public IpAddressInfo ParseIpAddress(string ipAddress) - { - if (TryParseIpAddress(ipAddress, out var info)) - { - return info; - } - - throw new ArgumentException("Invalid ip address: " + ipAddress); - } - - public bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo) + public bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask) { - if (IPAddress.TryParse(ipAddress, out var address)) - { - ipAddressInfo = ToIpAddressInfo(address); - return true; - } - - ipAddressInfo = null; - return false; - } - - public bool IsInSameSubnet(IpAddressInfo address1, IpAddressInfo address2, IpAddressInfo subnetMask) - { - IPAddress network1 = GetNetworkAddress(ToIPAddress(address1), ToIPAddress(subnetMask)); - IPAddress network2 = GetNetworkAddress(ToIPAddress(address2), ToIPAddress(subnetMask)); + IPAddress network1 = GetNetworkAddress(address1, subnetMask); + IPAddress network2 = GetNetworkAddress(address2, subnetMask); return network1.Equals(network2); } @@ -656,13 +598,13 @@ namespace Emby.Server.Implementations.Networking { broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i])); } + return new IPAddress(broadcastAddress); } - public IpAddressInfo GetLocalIpSubnetMask(IpAddressInfo address) + public IPAddress GetLocalIpSubnetMask(IPAddress address) { NetworkInterface[] interfaces; - IPAddress ipaddress = ToIPAddress(address); try { @@ -674,7 +616,7 @@ namespace Emby.Server.Implementations.Networking } catch (Exception ex) { - Logger.LogError(ex, "Error in GetAllNetworkInterfaces"); + _logger.LogError(ex, "Error in GetAllNetworkInterfaces"); return null; } @@ -684,83 +626,15 @@ namespace Emby.Server.Implementations.Networking { foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) { - if (ip.Address.Equals(ipaddress) && ip.IPv4Mask != null) + if (ip.Address.Equals(address) && ip.IPv4Mask != null) { - return ToIpAddressInfo(ip.IPv4Mask); + return ip.IPv4Mask; } } } } - return null; - } - - public static IpEndPointInfo ToIpEndPointInfo(IPEndPoint endpoint) - { - if (endpoint == null) - { - return null; - } - - return new IpEndPointInfo(ToIpAddressInfo(endpoint.Address), endpoint.Port); - } - - public static IPEndPoint ToIPEndPoint(IpEndPointInfo endpoint) - { - if (endpoint == null) - { - return null; - } - - return new IPEndPoint(ToIPAddress(endpoint.IpAddress), endpoint.Port); - } - public static IPAddress ToIPAddress(IpAddressInfo address) - { - if (address.Equals(IpAddressInfo.Any)) - { - return IPAddress.Any; - } - if (address.Equals(IpAddressInfo.IPv6Any)) - { - return IPAddress.IPv6Any; - } - if (address.Equals(IpAddressInfo.Loopback)) - { - return IPAddress.Loopback; - } - if (address.Equals(IpAddressInfo.IPv6Loopback)) - { - return IPAddress.IPv6Loopback; - } - - return IPAddress.Parse(address.Address); - } - - public static IpAddressInfo ToIpAddressInfo(IPAddress address) - { - if (address.Equals(IPAddress.Any)) - { - return IpAddressInfo.Any; - } - if (address.Equals(IPAddress.IPv6Any)) - { - return IpAddressInfo.IPv6Any; - } - if (address.Equals(IPAddress.Loopback)) - { - return IpAddressInfo.Loopback; - } - if (address.Equals(IPAddress.IPv6Loopback)) - { - return IpAddressInfo.IPv6Loopback; - } - return new IpAddressInfo(address.ToString(), address.AddressFamily == AddressFamily.InterNetworkV6 ? IpAddressFamily.InterNetworkV6 : IpAddressFamily.InterNetwork); - } - - public async Task GetHostAddressesAsync(string host) - { - var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); - return addresses.Select(ToIpAddressInfo).ToArray(); + return null; } /// diff --git a/Emby.Server.Implementations/Udp/UdpServer.cs b/Emby.Server.Implementations/Udp/UdpServer.cs index e7cda2993..185a282ac 100644 --- a/Emby.Server.Implementations/Udp/UdpServer.cs +++ b/Emby.Server.Implementations/Udp/UdpServer.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -25,7 +26,7 @@ namespace Emby.Server.Implementations.Udp private bool _isDisposed; - private readonly List>> _responders = new List>>(); + private readonly List>> _responders = new List>>(); private readonly IServerApplicationHost _appHost; private readonly IJsonSerializer _json; @@ -43,9 +44,9 @@ namespace Emby.Server.Implementations.Udp AddMessageResponder("who is JellyfinServer?", true, RespondToV2Message); } - private void AddMessageResponder(string message, bool isSubstring, Func responder) + private void AddMessageResponder(string message, bool isSubstring, Func responder) { - _responders.Add(new Tuple>(message, isSubstring, responder)); + _responders.Add(new Tuple>(message, isSubstring, responder)); } /// @@ -83,7 +84,7 @@ namespace Emby.Server.Implementations.Udp } } - private Tuple>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding) + private Tuple>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding) { var text = encoding.GetString(buffer, 0, bytesReceived); var responder = _responders.FirstOrDefault(i => @@ -99,10 +100,10 @@ namespace Emby.Server.Implementations.Udp { return null; } - return new Tuple>>(text, responder); + return new Tuple>>(text, responder); } - private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding, CancellationToken cancellationToken) + private async Task RespondToV2Message(string messageText, IPEndPoint endpoint, Encoding encoding, CancellationToken cancellationToken) { var parts = messageText.Split('|'); @@ -254,7 +255,7 @@ namespace Emby.Server.Implementations.Udp } } - public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint, CancellationToken cancellationToken) + public async Task SendAsync(byte[] bytes, IPEndPoint remoteEndPoint, CancellationToken cancellationToken) { if (_isDisposed) { diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 94308a98e..08c0983be 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -143,7 +143,7 @@ namespace Jellyfin.Server options, new ManagedFileSystem(_loggerFactory.CreateLogger(), appPaths), new NullImageEncoder(), - new NetworkManager(_loggerFactory), + new NetworkManager(_loggerFactory.CreateLogger()), appConfig)) { await appHost.InitAsync(new ServiceCollection()).ConfigureAwait(false); diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 34c6f5866..61f2bc2f9 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Net; using System.Threading.Tasks; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; @@ -53,17 +54,12 @@ namespace MediaBrowser.Common.Net /// true if [is in local network] [the specified endpoint]; otherwise, false. bool IsInLocalNetwork(string endpoint); - IpAddressInfo[] GetLocalIpAddresses(bool ignoreVirtualInterface); - - IpAddressInfo ParseIpAddress(string ipAddress); - - bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo); - - Task GetHostAddressesAsync(string host); + IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface); bool IsAddressInSubnets(string addressString, string[] subnets); - bool IsInSameSubnet(IpAddressInfo address1, IpAddressInfo address2, IpAddressInfo subnetMask); - IpAddressInfo GetLocalIpSubnetMask(IpAddressInfo address); + bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask); + + IPAddress GetLocalIpSubnetMask(IPAddress address); } } diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 81b9ff0a5..3f8cc0b83 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; +using System.Net; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common; -using MediaBrowser.Model.Net; using MediaBrowser.Model.System; namespace MediaBrowser.Controller @@ -59,7 +59,7 @@ namespace MediaBrowser.Controller /// Gets the local ip address. /// /// The local ip address. - Task> GetLocalIpAddresses(CancellationToken cancellationToken); + Task> GetLocalIpAddresses(CancellationToken cancellationToken); /// /// Gets the local API URL. @@ -77,7 +77,7 @@ namespace MediaBrowser.Controller /// /// Gets the local API URL. /// - string GetLocalApiUrl(IpAddressInfo address); + string GetLocalApiUrl(IPAddress address); void LaunchUrl(string url); diff --git a/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs b/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs index 4edbb503b..c443a8ad1 100644 --- a/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs +++ b/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using MediaBrowser.Model.Net; +using System.Net; namespace MediaBrowser.Model.Dlna { @@ -8,7 +8,7 @@ namespace MediaBrowser.Model.Dlna { public Uri Location { get; set; } public Dictionary Headers { get; set; } - public IpAddressInfo LocalIpAddress { get; set; } + public IPAddress LocalIpAddress { get; set; } public int LocalPort { get; set; } } } diff --git a/MediaBrowser.Model/Net/ISocket.cs b/MediaBrowser.Model/Net/ISocket.cs index 992ccb49b..f80de5524 100644 --- a/MediaBrowser.Model/Net/ISocket.cs +++ b/MediaBrowser.Model/Net/ISocket.cs @@ -1,4 +1,5 @@ using System; +using System.Net; using System.Threading; using System.Threading.Tasks; @@ -9,7 +10,7 @@ namespace MediaBrowser.Model.Net /// public interface ISocket : IDisposable { - IpAddressInfo LocalIPAddress { get; } + IPAddress LocalIPAddress { get; } Task ReceiveAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken); @@ -21,6 +22,6 @@ namespace MediaBrowser.Model.Net /// /// Sends a UDP message to a particular end point (uni or multicast). /// - Task SendToAsync(byte[] buffer, int offset, int bytes, IpEndPointInfo endPoint, CancellationToken cancellationToken); + Task SendToAsync(byte[] buffer, int offset, int bytes, IPEndPoint endPoint, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index 69fe134bc..e58f4cc14 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Net; namespace MediaBrowser.Model.Net { @@ -8,7 +9,7 @@ namespace MediaBrowser.Model.Net public interface ISocketFactory { /// - /// Createa a new unicast socket using the specified local port number. + /// Creates a new unicast socket using the specified local port number. /// /// The local port to bind to. /// A implementation. @@ -16,15 +17,15 @@ namespace MediaBrowser.Model.Net ISocket CreateUdpBroadcastSocket(int localPort); - ISocket CreateTcpSocket(IpAddressInfo remoteAddress, int remotePort); + ISocket CreateTcpSocket(IPAddress remoteAddress, int remotePort); /// - /// Createa a new unicast socket using the specified local port number. + /// Creates a new unicast socket using the specified local port number. /// - ISocket CreateSsdpUdpSocket(IpAddressInfo localIp, int localPort); + ISocket CreateSsdpUdpSocket(IPAddress localIp, int localPort); /// - /// Createa a new multicast socket using the specified multicast IP address, multicast time to live and local port. + /// Creates a new multicast socket using the specified multicast IP address, multicast time to live and local port. /// /// The multicast IP address to bind to. /// The multicast time to live value. Actually a maximum number of network hops for UDP packets. diff --git a/MediaBrowser.Model/Net/IpAddressInfo.cs b/MediaBrowser.Model/Net/IpAddressInfo.cs deleted file mode 100644 index 87fa55bca..000000000 --- a/MediaBrowser.Model/Net/IpAddressInfo.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; - -namespace MediaBrowser.Model.Net -{ - public class IpAddressInfo - { - public static IpAddressInfo Any = new IpAddressInfo("0.0.0.0", IpAddressFamily.InterNetwork); - public static IpAddressInfo IPv6Any = new IpAddressInfo("00000000000000000000", IpAddressFamily.InterNetworkV6); - public static IpAddressInfo Loopback = new IpAddressInfo("127.0.0.1", IpAddressFamily.InterNetwork); - public static IpAddressInfo IPv6Loopback = new IpAddressInfo("::1", IpAddressFamily.InterNetworkV6); - - public string Address { get; set; } - public IpAddressInfo SubnetMask { get; set; } - public IpAddressFamily AddressFamily { get; set; } - - public IpAddressInfo(string address, IpAddressFamily addressFamily) - { - Address = address; - AddressFamily = addressFamily; - } - - public bool Equals(IpAddressInfo address) - { - return string.Equals(address.Address, Address, StringComparison.OrdinalIgnoreCase); - } - - public override string ToString() - { - return Address; - } - } - - public enum IpAddressFamily - { - InterNetwork, - InterNetworkV6 - } -} diff --git a/MediaBrowser.Model/Net/IpEndPointInfo.cs b/MediaBrowser.Model/Net/IpEndPointInfo.cs deleted file mode 100644 index f8c125144..000000000 --- a/MediaBrowser.Model/Net/IpEndPointInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Globalization; - -namespace MediaBrowser.Model.Net -{ - public class IpEndPointInfo - { - public IpAddressInfo IpAddress { get; set; } - - public int Port { get; set; } - - public IpEndPointInfo() - { - - } - - public IpEndPointInfo(IpAddressInfo address, int port) - { - IpAddress = address; - Port = port; - } - - public override string ToString() - { - var ipAddresString = IpAddress == null ? string.Empty : IpAddress.ToString(); - - return ipAddresString + ":" + Port.ToString(CultureInfo.InvariantCulture); - } - } -} diff --git a/MediaBrowser.Model/Net/SocketReceiveResult.cs b/MediaBrowser.Model/Net/SocketReceiveResult.cs index 8c394f7c7..cd7a2e55f 100644 --- a/MediaBrowser.Model/Net/SocketReceiveResult.cs +++ b/MediaBrowser.Model/Net/SocketReceiveResult.cs @@ -1,3 +1,5 @@ +using System.Net; + namespace MediaBrowser.Model.Net { /// @@ -18,7 +20,7 @@ namespace MediaBrowser.Model.Net /// /// The the data was received from. /// - public IpEndPointInfo RemoteEndPoint { get; set; } - public IpAddressInfo LocalIPAddress { get; set; } + public IPEndPoint RemoteEndPoint { get; set; } + public IPAddress LocalIPAddress { get; set; } } } diff --git a/RSSDP/DeviceAvailableEventArgs.cs b/RSSDP/DeviceAvailableEventArgs.cs index 9106e27e5..21ac7c631 100644 --- a/RSSDP/DeviceAvailableEventArgs.cs +++ b/RSSDP/DeviceAvailableEventArgs.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using MediaBrowser.Model.Net; +using System.Net; namespace Rssdp { @@ -11,12 +8,12 @@ namespace Rssdp /// public sealed class DeviceAvailableEventArgs : EventArgs { - public IpAddressInfo LocalIpAddress { get; set; } + public IPAddress LocalIpAddress { get; set; } #region Fields private readonly DiscoveredSsdpDevice _DiscoveredDevice; - private readonly bool _IsNewlyDiscovered; + private readonly bool _IsNewlyDiscovered; #endregion @@ -29,34 +26,34 @@ namespace Rssdp /// A boolean value indicating whether or not this device came from the cache. See for more detail. /// Thrown if the parameter is null. public DeviceAvailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool isNewlyDiscovered) - { - if (discoveredDevice == null) throw new ArgumentNullException(nameof(discoveredDevice)); + { + if (discoveredDevice == null) throw new ArgumentNullException(nameof(discoveredDevice)); - _DiscoveredDevice = discoveredDevice; - _IsNewlyDiscovered = isNewlyDiscovered; - } + _DiscoveredDevice = discoveredDevice; + _IsNewlyDiscovered = isNewlyDiscovered; + } - #endregion + #endregion - #region Public Properties + #region Public Properties - /// - /// Returns true if the device was discovered due to an alive notification, or a search and was not already in the cache. Returns false if the item came from the cache but matched the current search request. - /// - public bool IsNewlyDiscovered - { - get { return _IsNewlyDiscovered; } - } + /// + /// Returns true if the device was discovered due to an alive notification, or a search and was not already in the cache. Returns false if the item came from the cache but matched the current search request. + /// + public bool IsNewlyDiscovered + { + get { return _IsNewlyDiscovered; } + } /// /// A reference to a instance containing the discovered details and allowing access to the full device description. /// public DiscoveredSsdpDevice DiscoveredDevice - { - get { return _DiscoveredDevice; } - } - - #endregion - - } -} \ No newline at end of file + { + get { return _DiscoveredDevice; } + } + + #endregion + + } +} diff --git a/RSSDP/ISsdpCommunicationsServer.cs b/RSSDP/ISsdpCommunicationsServer.cs index c99d684a1..8cf65df11 100644 --- a/RSSDP/ISsdpCommunicationsServer.cs +++ b/RSSDP/ISsdpCommunicationsServer.cs @@ -1,7 +1,7 @@ using System; +using System.Net; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Net; namespace Rssdp.Infrastructure { @@ -40,13 +40,13 @@ namespace Rssdp.Infrastructure /// /// Sends a message to a particular address (uni or multicast) and port. /// - Task SendMessage(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken); + Task SendMessage(byte[] messageData, IPEndPoint destination, IPAddress fromLocalIpAddress, CancellationToken cancellationToken); /// /// Sends a message to the SSDP multicast address and port. /// - Task SendMulticastMessage(string message, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken); - Task SendMulticastMessage(string message, int sendCount, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken); + Task SendMulticastMessage(string message, IPAddress fromLocalIpAddress, CancellationToken cancellationToken); + Task SendMulticastMessage(string message, int sendCount, IPAddress fromLocalIpAddress, CancellationToken cancellationToken); #endregion diff --git a/RSSDP/RequestReceivedEventArgs.cs b/RSSDP/RequestReceivedEventArgs.cs index fd3cd9e3a..b753950f0 100644 --- a/RSSDP/RequestReceivedEventArgs.cs +++ b/RSSDP/RequestReceivedEventArgs.cs @@ -1,10 +1,6 @@ using System; -using System.Collections.Generic; using System.Net; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using MediaBrowser.Model.Net; namespace Rssdp.Infrastructure { @@ -16,18 +12,18 @@ namespace Rssdp.Infrastructure #region Fields private readonly HttpRequestMessage _Message; - private readonly IpEndPointInfo _ReceivedFrom; + private readonly IPEndPoint _ReceivedFrom; #endregion - public IpAddressInfo LocalIpAddress { get; private set; } + public IPAddress LocalIpAddress { get; private set; } #region Constructors /// /// Full constructor. /// - public RequestReceivedEventArgs(HttpRequestMessage message, IpEndPointInfo receivedFrom, IpAddressInfo localIpAddress) + public RequestReceivedEventArgs(HttpRequestMessage message, IPEndPoint receivedFrom, IPAddress localIpAddress) { _Message = message; _ReceivedFrom = receivedFrom; @@ -49,7 +45,7 @@ namespace Rssdp.Infrastructure /// /// The the request came from. /// - public IpEndPointInfo ReceivedFrom + public IPEndPoint ReceivedFrom { get { return _ReceivedFrom; } } diff --git a/RSSDP/ResponseReceivedEventArgs.cs b/RSSDP/ResponseReceivedEventArgs.cs index 5ed9664ed..f9f9c3040 100644 --- a/RSSDP/ResponseReceivedEventArgs.cs +++ b/RSSDP/ResponseReceivedEventArgs.cs @@ -1,10 +1,6 @@ using System; -using System.Collections.Generic; using System.Net; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using MediaBrowser.Model.Net; namespace Rssdp.Infrastructure { @@ -14,12 +10,12 @@ namespace Rssdp.Infrastructure public sealed class ResponseReceivedEventArgs : EventArgs { - public IpAddressInfo LocalIpAddress { get; set; } + public IPAddress LocalIpAddress { get; set; } #region Fields private readonly HttpResponseMessage _Message; - private readonly IpEndPointInfo _ReceivedFrom; + private readonly IPEndPoint _ReceivedFrom; #endregion @@ -28,7 +24,7 @@ namespace Rssdp.Infrastructure /// /// Full constructor. /// - public ResponseReceivedEventArgs(HttpResponseMessage message, IpEndPointInfo receivedFrom) + public ResponseReceivedEventArgs(HttpResponseMessage message, IPEndPoint receivedFrom) { _Message = message; _ReceivedFrom = receivedFrom; @@ -49,7 +45,7 @@ namespace Rssdp.Infrastructure /// /// The the response came from. /// - public IpEndPointInfo ReceivedFrom + public IPEndPoint ReceivedFrom { get { return _ReceivedFrom; } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 5d2afc37a..0aa985a26 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Net.Http; using System.Net.Sockets; using System.Text; @@ -163,7 +164,7 @@ namespace Rssdp.Infrastructure /// /// Sends a message to a particular address (uni or multicast) and port. /// - public async Task SendMessage(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken) + public async Task SendMessage(byte[] messageData, IPEndPoint destination, IPAddress fromLocalIpAddress, CancellationToken cancellationToken) { if (messageData == null) throw new ArgumentNullException(nameof(messageData)); @@ -186,7 +187,7 @@ namespace Rssdp.Infrastructure } } - private async Task SendFromSocket(ISocket socket, byte[] messageData, IpEndPointInfo destination, CancellationToken cancellationToken) + private async Task SendFromSocket(ISocket socket, byte[] messageData, IPEndPoint destination, CancellationToken cancellationToken) { try { @@ -206,7 +207,7 @@ namespace Rssdp.Infrastructure } } - private List GetSendSockets(IpAddressInfo fromLocalIpAddress, IpEndPointInfo destination) + private List GetSendSockets(IPAddress fromLocalIpAddress, IPEndPoint destination) { EnsureSendSocketCreated(); @@ -215,24 +216,24 @@ namespace Rssdp.Infrastructure var sockets = _sendSockets.Where(i => i.LocalIPAddress.AddressFamily == fromLocalIpAddress.AddressFamily); // Send from the Any socket and the socket with the matching address - if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetwork) + if (fromLocalIpAddress.AddressFamily == AddressFamily.InterNetwork) { - sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || fromLocalIpAddress.Equals(i.LocalIPAddress)); + sockets = sockets.Where(i => i.LocalIPAddress.Equals(IPAddress.Any) || fromLocalIpAddress.Equals(i.LocalIPAddress)); // If sending to the loopback address, filter the socket list as well - if (destination.IpAddress.Equals(IpAddressInfo.Loopback)) + if (destination.Address.Equals(IPAddress.Loopback)) { - sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || i.LocalIPAddress.Equals(IpAddressInfo.Loopback)); + sockets = sockets.Where(i => i.LocalIPAddress.Equals(IPAddress.Any) || i.LocalIPAddress.Equals(IPAddress.Loopback)); } } - else if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetworkV6) + else if (fromLocalIpAddress.AddressFamily == AddressFamily.InterNetworkV6) { - sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || fromLocalIpAddress.Equals(i.LocalIPAddress)); + sockets = sockets.Where(i => i.LocalIPAddress.Equals(IPAddress.IPv6Any) || fromLocalIpAddress.Equals(i.LocalIPAddress)); // If sending to the loopback address, filter the socket list as well - if (destination.IpAddress.Equals(IpAddressInfo.IPv6Loopback)) + if (destination.Address.Equals(IPAddress.IPv6Loopback)) { - sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || i.LocalIPAddress.Equals(IpAddressInfo.IPv6Loopback)); + sockets = sockets.Where(i => i.LocalIPAddress.Equals(IPAddress.IPv6Any) || i.LocalIPAddress.Equals(IPAddress.IPv6Loopback)); } } @@ -240,7 +241,7 @@ namespace Rssdp.Infrastructure } } - public Task SendMulticastMessage(string message, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken) + public Task SendMulticastMessage(string message, IPAddress fromLocalIpAddress, CancellationToken cancellationToken) { return SendMulticastMessage(message, SsdpConstants.UdpResendCount, fromLocalIpAddress, cancellationToken); } @@ -248,7 +249,7 @@ namespace Rssdp.Infrastructure /// /// Sends a message to the SSDP multicast address and port. /// - public async Task SendMulticastMessage(string message, int sendCount, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken) + public async Task SendMulticastMessage(string message, int sendCount, IPAddress fromLocalIpAddress, CancellationToken cancellationToken) { if (message == null) throw new ArgumentNullException(nameof(message)); @@ -263,12 +264,13 @@ namespace Rssdp.Infrastructure // SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP. for (var i = 0; i < sendCount; i++) { - await SendMessageIfSocketNotDisposed(messageData, new IpEndPointInfo - { - IpAddress = new IpAddressInfo(SsdpConstants.MulticastLocalAdminAddress, IpAddressFamily.InterNetwork), - Port = SsdpConstants.MulticastPort - - }, fromLocalIpAddress, cancellationToken).ConfigureAwait(false); + await SendMessageIfSocketNotDisposed( + messageData, + new IPEndPoint( + IPAddress.Parse(SsdpConstants.MulticastLocalAdminAddress), + SsdpConstants.MulticastPort), + fromLocalIpAddress, + cancellationToken).ConfigureAwait(false); await Task.Delay(100, cancellationToken).ConfigureAwait(false); } @@ -336,7 +338,7 @@ namespace Rssdp.Infrastructure #region Private Methods - private Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken) + private Task SendMessageIfSocketNotDisposed(byte[] messageData, IPEndPoint destination, IPAddress fromLocalIpAddress, CancellationToken cancellationToken) { var sockets = _sendSockets; if (sockets != null) @@ -364,13 +366,13 @@ namespace Rssdp.Infrastructure { var sockets = new List(); - sockets.Add(_SocketFactory.CreateSsdpUdpSocket(IpAddressInfo.Any, _LocalPort)); + sockets.Add(_SocketFactory.CreateSsdpUdpSocket(IPAddress.Any, _LocalPort)); if (_enableMultiSocketBinding) { foreach (var address in _networkManager.GetLocalIpAddresses(_config.Configuration.IgnoreVirtualInterfaces)) { - if (address.AddressFamily == IpAddressFamily.InterNetworkV6) + if (address.AddressFamily == AddressFamily.InterNetworkV6) { // Not support IPv6 right now continue; @@ -439,7 +441,7 @@ namespace Rssdp.Infrastructure } } - private void ProcessMessage(string data, IpEndPointInfo endPoint, IpAddressInfo receivedOnLocalIpAddress) + private void ProcessMessage(string data, IPEndPoint endPoint, IPAddress receivedOnLocalIpAddress) { // Responses start with the HTTP version, prefixed with HTTP/ while // requests start with a method which can vary and might be one we haven't @@ -481,7 +483,7 @@ namespace Rssdp.Infrastructure } } - private void OnRequestReceived(HttpRequestMessage data, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnLocalIpAddress) + private void OnRequestReceived(HttpRequestMessage data, IPEndPoint remoteEndPoint, IPAddress receivedOnLocalIpAddress) { //SSDP specification says only * is currently used but other uri's might //be implemented in the future and should be ignored unless understood. @@ -496,7 +498,7 @@ namespace Rssdp.Infrastructure handlers(this, new RequestReceivedEventArgs(data, remoteEndPoint, receivedOnLocalIpAddress)); } - private void OnResponseReceived(HttpResponseMessage data, IpEndPointInfo endPoint, IpAddressInfo localIpAddress) + private void OnResponseReceived(HttpResponseMessage data, IPEndPoint endPoint, IPAddress localIpAddress) { var handlers = this.ResponseReceived; if (handlers != null) diff --git a/RSSDP/SsdpDevice.cs b/RSSDP/SsdpDevice.cs index b4c4a88fd..09f729e83 100644 --- a/RSSDP/SsdpDevice.cs +++ b/RSSDP/SsdpDevice.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Text; -using System.Threading.Tasks; -using System.Xml; using Rssdp.Infrastructure; namespace Rssdp diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index e17e14c1a..59a2710d5 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -1,13 +1,10 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; using System.Linq; +using System.Net; using System.Net.Http; -using System.Text; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Net; namespace Rssdp.Infrastructure { @@ -213,7 +210,7 @@ namespace Rssdp.Infrastructure /// Raises the event. /// /// - protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice, IpAddressInfo localIpAddress) + protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress localIpAddress) { if (this.IsDisposed) return; @@ -295,7 +292,7 @@ namespace Rssdp.Infrastructure #region Discovery/Device Add - private void AddOrUpdateDiscoveredDevice(DiscoveredSsdpDevice device, IpAddressInfo localIpAddress) + private void AddOrUpdateDiscoveredDevice(DiscoveredSsdpDevice device, IPAddress localIpAddress) { bool isNewDevice = false; lock (_Devices) @@ -316,7 +313,7 @@ namespace Rssdp.Infrastructure DeviceFound(device, isNewDevice, localIpAddress); } - private void DeviceFound(DiscoveredSsdpDevice device, bool isNewDevice, IpAddressInfo localIpAddress) + private void DeviceFound(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress localIpAddress) { if (!NotificationTypeMatchesFilter(device)) return; @@ -357,7 +354,7 @@ namespace Rssdp.Infrastructure return _CommunicationsServer.SendMulticastMessage(message, null, cancellationToken); } - private void ProcessSearchResponseMessage(HttpResponseMessage message, IpAddressInfo localIpAddress) + private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress localIpAddress) { if (!message.IsSuccessStatusCode) return; @@ -378,7 +375,7 @@ namespace Rssdp.Infrastructure } } - private void ProcessNotificationMessage(HttpRequestMessage message, IpAddressInfo localIpAddress) + private void ProcessNotificationMessage(HttpRequestMessage message, IPAddress localIpAddress) { if (String.Compare(message.Method.Method, "Notify", StringComparison.OrdinalIgnoreCase) != 0) return; @@ -389,7 +386,7 @@ namespace Rssdp.Infrastructure ProcessByeByeNotification(message); } - private void ProcessAliveNotification(HttpRequestMessage message, IpAddressInfo localIpAddress) + private void ProcessAliveNotification(HttpRequestMessage message, IPAddress localIpAddress) { var location = GetFirstHeaderUriValue("Location", message); if (location != null) diff --git a/RSSDP/SsdpDevicePublisher.cs b/RSSDP/SsdpDevicePublisher.cs index 921f33c21..7f3e56394 100644 --- a/RSSDP/SsdpDevicePublisher.cs +++ b/RSSDP/SsdpDevicePublisher.cs @@ -2,13 +2,10 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using System.Net.Http; -using System.Text; +using System.Net; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Net; using MediaBrowser.Common.Net; -using Rssdp; namespace Rssdp.Infrastructure { @@ -199,7 +196,12 @@ namespace Rssdp.Infrastructure } } - private void ProcessSearchRequest(string mx, string searchTarget, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnlocalIpAddress, CancellationToken cancellationToken) + private void ProcessSearchRequest( + string mx, + string searchTarget, + IPEndPoint remoteEndPoint, + IPAddress receivedOnlocalIpAddress, + CancellationToken cancellationToken) { if (String.IsNullOrEmpty(searchTarget)) { @@ -258,7 +260,7 @@ namespace Rssdp.Infrastructure foreach (var device in deviceList) { if (!_sendOnlyMatchedHost || - _networkManager.IsInSameSubnet(device.ToRootDevice().Address, remoteEndPoint.IpAddress, device.ToRootDevice().SubnetMask)) + _networkManager.IsInSameSubnet(device.ToRootDevice().Address, remoteEndPoint.Address, device.ToRootDevice().SubnetMask)) { SendDeviceSearchResponses(device, remoteEndPoint, receivedOnlocalIpAddress, cancellationToken); } @@ -276,7 +278,11 @@ namespace Rssdp.Infrastructure return _Devices.Union(_Devices.SelectManyRecursive((d) => d.Devices)); } - private void SendDeviceSearchResponses(SsdpDevice device, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress, CancellationToken cancellationToken) + private void SendDeviceSearchResponses( + SsdpDevice device, + IPEndPoint endPoint, + IPAddress receivedOnlocalIpAddress, + CancellationToken cancellationToken) { bool isRootDevice = (device as SsdpRootDevice) != null; if (isRootDevice) @@ -296,7 +302,13 @@ namespace Rssdp.Infrastructure return String.Format("{0}::{1}", udn, fullDeviceType); } - private async void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress, CancellationToken cancellationToken) + private async void SendSearchResponse( + string searchTarget, + SsdpDevice device, + string uniqueServiceName, + IPEndPoint endPoint, + IPAddress receivedOnlocalIpAddress, + CancellationToken cancellationToken) { var rootDevice = device.ToRootDevice(); @@ -333,7 +345,7 @@ namespace Rssdp.Infrastructure //WriteTrace(String.Format("Sent search response to " + endPoint.ToString()), device); } - private bool IsDuplicateSearchRequest(string searchTarget, IpEndPointInfo endPoint) + private bool IsDuplicateSearchRequest(string searchTarget, IPEndPoint endPoint) { var isDuplicateRequest = false; @@ -556,7 +568,7 @@ namespace Rssdp.Infrastructure private class SearchRequest { - public IpEndPointInfo EndPoint { get; set; } + public IPEndPoint EndPoint { get; set; } public DateTime Received { get; set; } public string SearchTarget { get; set; } diff --git a/RSSDP/SsdpRootDevice.cs b/RSSDP/SsdpRootDevice.cs index d918b9040..0f2de7b15 100644 --- a/RSSDP/SsdpRootDevice.cs +++ b/RSSDP/SsdpRootDevice.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; -using System.Text; -using System.Xml; -using Rssdp.Infrastructure; -using MediaBrowser.Model.Net; +using System.Net; namespace Rssdp { @@ -56,12 +52,12 @@ namespace Rssdp /// /// Gets or sets the Address used to check if the received message from same interface with this device/tree. Required. /// - public IpAddressInfo Address { get; set; } + public IPAddress Address { get; set; } /// /// Gets or sets the SubnetMask used to check if the received message from same interface with this device/tree. Required. /// - public IpAddressInfo SubnetMask { get; set; } + public IPAddress SubnetMask { get; set; } /// /// The base URL to use for all relative url's provided in other propertise (and those of child devices). Optional. -- 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 c6ba2326a..ef2f59d30 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