diff options
Diffstat (limited to 'Emby.Dlna')
| -rw-r--r-- | Emby.Dlna/ConnectionManager/ConnectionManagerService.cs | 6 | ||||
| -rw-r--r-- | Emby.Dlna/ContentDirectory/ContentDirectoryService.cs | 4 | ||||
| -rw-r--r-- | Emby.Dlna/ContentDirectory/ControlHandler.cs | 2 | ||||
| -rw-r--r-- | Emby.Dlna/Didl/DidlBuilder.cs | 4 | ||||
| -rw-r--r-- | Emby.Dlna/DlnaManager.cs | 48 | ||||
| -rw-r--r-- | Emby.Dlna/Emby.Dlna.csproj | 1 | ||||
| -rw-r--r-- | Emby.Dlna/Eventing/DlnaEventManager.cs | 30 | ||||
| -rw-r--r-- | Emby.Dlna/Images/logo240.jpg | bin | 11520 -> 11483 bytes | |||
| -rw-r--r-- | Emby.Dlna/Images/people48.png | bin | 286 -> 278 bytes | |||
| -rw-r--r-- | Emby.Dlna/Main/DlnaEntryPoint.cs | 15 | ||||
| -rw-r--r-- | Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarService.cs | 6 | ||||
| -rw-r--r-- | Emby.Dlna/PlayTo/Device.cs | 41 | ||||
| -rw-r--r-- | Emby.Dlna/PlayTo/PlayToController.cs | 87 | ||||
| -rw-r--r-- | Emby.Dlna/PlayTo/PlayToManager.cs | 29 | ||||
| -rw-r--r-- | Emby.Dlna/PlayTo/SsdpHttpClient.cs | 116 | ||||
| -rw-r--r-- | Emby.Dlna/Service/BaseService.cs | 10 |
16 files changed, 174 insertions, 225 deletions
diff --git a/Emby.Dlna/ConnectionManager/ConnectionManagerService.cs b/Emby.Dlna/ConnectionManager/ConnectionManagerService.cs index 12338e2b4b..f5a7eca720 100644 --- a/Emby.Dlna/ConnectionManager/ConnectionManagerService.cs +++ b/Emby.Dlna/ConnectionManager/ConnectionManagerService.cs @@ -1,8 +1,8 @@ #pragma warning disable CS1591 +using System.Net.Http; using System.Threading.Tasks; using Emby.Dlna.Service; -using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dlna; using Microsoft.Extensions.Logging; @@ -18,8 +18,8 @@ namespace Emby.Dlna.ConnectionManager IDlnaManager dlna, IServerConfigurationManager config, ILogger<ConnectionManagerService> logger, - IHttpClient httpClient) - : base(logger, httpClient) + IHttpClientFactory httpClientFactory) + : base(logger, httpClientFactory) { _dlna = dlna; _config = config; diff --git a/Emby.Dlna/ContentDirectory/ContentDirectoryService.cs b/Emby.Dlna/ContentDirectory/ContentDirectoryService.cs index 72732823ac..5760f260cf 100644 --- a/Emby.Dlna/ContentDirectory/ContentDirectoryService.cs +++ b/Emby.Dlna/ContentDirectory/ContentDirectoryService.cs @@ -2,11 +2,11 @@ using System; using System.Linq; +using System.Net.Http; using System.Threading.Tasks; using Emby.Dlna.Service; using Jellyfin.Data.Entities; using Jellyfin.Data.Enums; -using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; @@ -41,7 +41,7 @@ namespace Emby.Dlna.ContentDirectory IServerConfigurationManager config, IUserManager userManager, ILogger<ContentDirectoryService> logger, - IHttpClient httpClient, + IHttpClientFactory httpClient, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index be1ed7872e..4b108b89ea 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -1363,7 +1363,7 @@ namespace Emby.Dlna.ContentDirectory }; } - Logger.LogError("Error parsing item Id: {id}. Returning user root folder.", id); + Logger.LogError("Error parsing item Id: {Id}. Returning user root folder.", id); return new ServerItem(_libraryManager.GetUserRootFolder()); } diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index bd09a80511..5b8a89d8f3 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -948,7 +948,7 @@ namespace Emby.Dlna.Didl } catch (XmlException ex) { - _logger.LogError(ex, "Error adding xml value: {value}", name); + _logger.LogError(ex, "Error adding xml value: {Value}", name); } } @@ -960,7 +960,7 @@ namespace Emby.Dlna.Didl } catch (XmlException ex) { - _logger.LogError(ex, "Error adding xml value: {value}", value); + _logger.LogError(ex, "Error adding xml value: {Value}", value); } } diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index d5629684c3..1807ac6a13 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -126,32 +126,23 @@ namespace Emby.Dlna var builder = new StringBuilder(); builder.AppendLine("No matching device profile found. The default will need to be used."); - builder.AppendFormat(CultureInfo.InvariantCulture, "DeviceDescription:{0}", profile.DeviceDescription ?? string.Empty).AppendLine(); - builder.AppendFormat(CultureInfo.InvariantCulture, "FriendlyName:{0}", profile.FriendlyName ?? string.Empty).AppendLine(); - builder.AppendFormat(CultureInfo.InvariantCulture, "Manufacturer:{0}", profile.Manufacturer ?? string.Empty).AppendLine(); - builder.AppendFormat(CultureInfo.InvariantCulture, "ManufacturerUrl:{0}", profile.ManufacturerUrl ?? string.Empty).AppendLine(); - builder.AppendFormat(CultureInfo.InvariantCulture, "ModelDescription:{0}", profile.ModelDescription ?? string.Empty).AppendLine(); - builder.AppendFormat(CultureInfo.InvariantCulture, "ModelName:{0}", profile.ModelName ?? string.Empty).AppendLine(); - builder.AppendFormat(CultureInfo.InvariantCulture, "ModelNumber:{0}", profile.ModelNumber ?? string.Empty).AppendLine(); - builder.AppendFormat(CultureInfo.InvariantCulture, "ModelUrl:{0}", profile.ModelUrl ?? string.Empty).AppendLine(); - builder.AppendFormat(CultureInfo.InvariantCulture, "SerialNumber:{0}", profile.SerialNumber ?? string.Empty).AppendLine(); + builder.Append("FriendlyName:").AppendLine(profile.FriendlyName); + builder.Append("Manufacturer:").AppendLine(profile.Manufacturer); + builder.Append("ManufacturerUrl:").AppendLine(profile.ManufacturerUrl); + builder.Append("ModelDescription:").AppendLine(profile.ModelDescription); + builder.Append("ModelName:").AppendLine(profile.ModelName); + builder.Append("ModelNumber:").AppendLine(profile.ModelNumber); + builder.Append("ModelUrl:").AppendLine(profile.ModelUrl); + builder.Append("SerialNumber:").AppendLine(profile.SerialNumber); _logger.LogInformation(builder.ToString()); } private bool IsMatch(DeviceIdentification deviceInfo, DeviceIdentification profileInfo) { - if (!string.IsNullOrEmpty(profileInfo.DeviceDescription)) - { - if (deviceInfo.DeviceDescription == null || !IsRegexMatch(deviceInfo.DeviceDescription, profileInfo.DeviceDescription)) - { - return false; - } - } - if (!string.IsNullOrEmpty(profileInfo.FriendlyName)) { - if (deviceInfo.FriendlyName == null || !IsRegexMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName)) + if (deviceInfo.FriendlyName == null || !IsRegexOrSubstringMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName)) { return false; } @@ -159,7 +150,7 @@ namespace Emby.Dlna if (!string.IsNullOrEmpty(profileInfo.Manufacturer)) { - if (deviceInfo.Manufacturer == null || !IsRegexMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer)) + if (deviceInfo.Manufacturer == null || !IsRegexOrSubstringMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer)) { return false; } @@ -167,7 +158,7 @@ namespace Emby.Dlna if (!string.IsNullOrEmpty(profileInfo.ManufacturerUrl)) { - if (deviceInfo.ManufacturerUrl == null || !IsRegexMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl)) + if (deviceInfo.ManufacturerUrl == null || !IsRegexOrSubstringMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl)) { return false; } @@ -175,7 +166,7 @@ namespace Emby.Dlna if (!string.IsNullOrEmpty(profileInfo.ModelDescription)) { - if (deviceInfo.ModelDescription == null || !IsRegexMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription)) + if (deviceInfo.ModelDescription == null || !IsRegexOrSubstringMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription)) { return false; } @@ -183,7 +174,7 @@ namespace Emby.Dlna if (!string.IsNullOrEmpty(profileInfo.ModelName)) { - if (deviceInfo.ModelName == null || !IsRegexMatch(deviceInfo.ModelName, profileInfo.ModelName)) + if (deviceInfo.ModelName == null || !IsRegexOrSubstringMatch(deviceInfo.ModelName, profileInfo.ModelName)) { return false; } @@ -191,7 +182,7 @@ namespace Emby.Dlna if (!string.IsNullOrEmpty(profileInfo.ModelNumber)) { - if (deviceInfo.ModelNumber == null || !IsRegexMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber)) + if (deviceInfo.ModelNumber == null || !IsRegexOrSubstringMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber)) { return false; } @@ -199,7 +190,7 @@ namespace Emby.Dlna if (!string.IsNullOrEmpty(profileInfo.ModelUrl)) { - if (deviceInfo.ModelUrl == null || !IsRegexMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl)) + if (deviceInfo.ModelUrl == null || !IsRegexOrSubstringMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl)) { return false; } @@ -207,7 +198,7 @@ namespace Emby.Dlna if (!string.IsNullOrEmpty(profileInfo.SerialNumber)) { - if (deviceInfo.SerialNumber == null || !IsRegexMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber)) + if (deviceInfo.SerialNumber == null || !IsRegexOrSubstringMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber)) { return false; } @@ -216,11 +207,11 @@ namespace Emby.Dlna return true; } - private bool IsRegexMatch(string input, string pattern) + private bool IsRegexOrSubstringMatch(string input, string pattern) { try { - return Regex.IsMatch(input, pattern); + return input.Contains(pattern, StringComparison.OrdinalIgnoreCase) || Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); } catch (ArgumentException ex) { @@ -511,8 +502,7 @@ namespace Emby.Dlna public string GetServerDescriptionXml(IHeaderDictionary headers, string serverUuId, string serverAddress) { - var profile = GetProfile(headers) ?? - GetDefaultProfile(); + var profile = GetDefaultProfile(); var serverId = _appHost.SystemId; diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj index 8538f580ca..6ed49944c0 100644 --- a/Emby.Dlna/Emby.Dlna.csproj +++ b/Emby.Dlna/Emby.Dlna.csproj @@ -80,6 +80,7 @@ <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" /> <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" /> + <PackageReference Include="Microsoft.Extensions.Http" Version="3.1.6" /> </ItemGroup> </Project> diff --git a/Emby.Dlna/Eventing/DlnaEventManager.cs b/Emby.Dlna/Eventing/DlnaEventManager.cs index b66e966dff..7d8da86ef9 100644 --- a/Emby.Dlna/Eventing/DlnaEventManager.cs +++ b/Emby.Dlna/Eventing/DlnaEventManager.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net.Http; +using System.Net.Mime; using System.Text; using System.Threading.Tasks; using MediaBrowser.Common.Extensions; @@ -20,13 +21,13 @@ namespace Emby.Dlna.Eventing new ConcurrentDictionary<string, EventSubscription>(StringComparer.OrdinalIgnoreCase); private readonly ILogger _logger; - private readonly IHttpClient _httpClient; + private readonly IHttpClientFactory _httpClientFactory; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - public DlnaEventManager(ILogger logger, IHttpClient httpClient) + public DlnaEventManager(ILogger logger, IHttpClientFactory httpClientFactory) { - _httpClient = httpClient; + _httpClientFactory = httpClientFactory; _logger = logger; } @@ -167,24 +168,17 @@ namespace Emby.Dlna.Eventing builder.Append("</e:propertyset>"); - var options = new HttpRequestOptions - { - RequestContent = builder.ToString(), - RequestContentType = "text/xml", - Url = subscription.CallbackUrl, - BufferContent = false - }; - - options.RequestHeaders.Add("NT", subscription.NotificationType); - options.RequestHeaders.Add("NTS", "upnp:propchange"); - options.RequestHeaders.Add("SID", subscription.Id); - options.RequestHeaders.Add("SEQ", subscription.TriggerCount.ToString(_usCulture)); + using var options = new HttpRequestMessage(new HttpMethod("NOTIFY"), subscription.CallbackUrl); + options.Content = new StringContent(builder.ToString(), Encoding.UTF8, MediaTypeNames.Text.Xml); + options.Headers.TryAddWithoutValidation("NT", subscription.NotificationType); + options.Headers.TryAddWithoutValidation("NTS", "upnp:propchange"); + options.Headers.TryAddWithoutValidation("SID", subscription.Id); + options.Headers.TryAddWithoutValidation("SEQ", subscription.TriggerCount.ToString(_usCulture)); try { - using (await _httpClient.SendAsync(options, new HttpMethod("NOTIFY")).ConfigureAwait(false)) - { - } + using var response = await _httpClientFactory.CreateClient(NamedClient.Default) + .SendAsync(options, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); } catch (OperationCanceledException) { diff --git a/Emby.Dlna/Images/logo240.jpg b/Emby.Dlna/Images/logo240.jpg Binary files differindex da1cb5e071..78a27f1b54 100644 --- a/Emby.Dlna/Images/logo240.jpg +++ b/Emby.Dlna/Images/logo240.jpg diff --git a/Emby.Dlna/Images/people48.png b/Emby.Dlna/Images/people48.png Binary files differindex 7fb25e6b39..dae5f6057f 100644 --- a/Emby.Dlna/Images/people48.png +++ b/Emby.Dlna/Images/people48.png diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 0ad82022dd..40c2cc0e0a 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -2,6 +2,7 @@ using System; using System.Globalization; +using System.Net.Http; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; @@ -36,7 +37,7 @@ namespace Emby.Dlna.Main private readonly ILogger<DlnaEntryPoint> _logger; private readonly IServerApplicationHost _appHost; private readonly ISessionManager _sessionManager; - private readonly IHttpClient _httpClient; + private readonly IHttpClientFactory _httpClientFactory; private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; private readonly IDlnaManager _dlnaManager; @@ -61,7 +62,7 @@ namespace Emby.Dlna.Main ILoggerFactory loggerFactory, IServerApplicationHost appHost, ISessionManager sessionManager, - IHttpClient httpClient, + IHttpClientFactory httpClientFactory, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, @@ -79,7 +80,7 @@ namespace Emby.Dlna.Main _config = config; _appHost = appHost; _sessionManager = sessionManager; - _httpClient = httpClient; + _httpClientFactory = httpClientFactory; _libraryManager = libraryManager; _userManager = userManager; _dlnaManager = dlnaManager; @@ -101,7 +102,7 @@ namespace Emby.Dlna.Main config, userManager, loggerFactory.CreateLogger<ContentDirectory.ContentDirectoryService>(), - httpClient, + httpClientFactory, localizationManager, mediaSourceManager, userViewManager, @@ -112,11 +113,11 @@ namespace Emby.Dlna.Main dlnaManager, config, loggerFactory.CreateLogger<ConnectionManager.ConnectionManagerService>(), - httpClient); + httpClientFactory); MediaReceiverRegistrar = new MediaReceiverRegistrar.MediaReceiverRegistrarService( loggerFactory.CreateLogger<MediaReceiverRegistrar.MediaReceiverRegistrarService>(), - httpClient, + httpClientFactory, config); Current = this; } @@ -364,7 +365,7 @@ namespace Emby.Dlna.Main _appHost, _imageProcessor, _deviceDiscovery, - _httpClient, + _httpClientFactory, _config, _userDataManager, _localization, diff --git a/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarService.cs b/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarService.cs index 28de2fef52..e6d845e1e4 100644 --- a/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarService.cs +++ b/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarService.cs @@ -1,8 +1,8 @@ #pragma warning disable CS1591 +using System.Net.Http; using System.Threading.Tasks; using Emby.Dlna.Service; -using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using Microsoft.Extensions.Logging; @@ -14,9 +14,9 @@ namespace Emby.Dlna.MediaReceiverRegistrar public MediaReceiverRegistrarService( ILogger<MediaReceiverRegistrarService> logger, - IHttpClient httpClient, + IHttpClientFactory httpClientFactory, IServerConfigurationManager config) - : base(logger, httpClient) + : base(logger, httpClientFactory) { _config = config; } diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 5462e7abc5..c97acdb026 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Net.Http; using System.Security; using System.Threading; using System.Threading.Tasks; @@ -21,7 +22,7 @@ namespace Emby.Dlna.PlayTo { private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - private readonly IHttpClient _httpClient; + private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; @@ -34,10 +35,10 @@ namespace Emby.Dlna.PlayTo private int _connectFailureCount; private bool _disposed; - public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger) + public Device(DeviceInfo deviceProperties, IHttpClientFactory httpClientFactory, ILogger logger) { Properties = deviceProperties; - _httpClient = httpClient; + _httpClientFactory = httpClientFactory; _logger = logger; } @@ -236,7 +237,7 @@ namespace Emby.Dlna.PlayTo _logger.LogDebug("Setting mute"); var value = mute ? 1 : 0; - await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value)) + await new SsdpHttpClient(_httpClientFactory).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value)) .ConfigureAwait(false); IsMuted = mute; @@ -271,7 +272,7 @@ namespace Emby.Dlna.PlayTo // Remote control will perform better Volume = value; - await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value)) + await new SsdpHttpClient(_httpClientFactory).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value)) .ConfigureAwait(false); } @@ -292,7 +293,7 @@ namespace Emby.Dlna.PlayTo throw new InvalidOperationException("Unable to find service"); } - await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format(CultureInfo.InvariantCulture, "{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME")) + await new SsdpHttpClient(_httpClientFactory).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format(CultureInfo.InvariantCulture, "{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME")) .ConfigureAwait(false); RestartTimer(true); @@ -326,7 +327,7 @@ namespace Emby.Dlna.PlayTo } var post = avCommands.BuildPost(command, service.ServiceType, url, dictionary); - await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header: header) + await new SsdpHttpClient(_httpClientFactory).SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header: header) .ConfigureAwait(false); await Task.Delay(50).ConfigureAwait(false); @@ -368,7 +369,7 @@ namespace Emby.Dlna.PlayTo throw new InvalidOperationException("Unable to find service"); } - return new SsdpHttpClient(_httpClient).SendCommandAsync( + return new SsdpHttpClient(_httpClientFactory).SendCommandAsync( Properties.BaseUrl, service, command.Name, @@ -397,7 +398,7 @@ namespace Emby.Dlna.PlayTo var service = GetAvTransportService(); - await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) + await new SsdpHttpClient(_httpClientFactory).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) .ConfigureAwait(false); RestartTimer(true); @@ -415,7 +416,7 @@ namespace Emby.Dlna.PlayTo var service = GetAvTransportService(); - await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) + await new SsdpHttpClient(_httpClientFactory).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) .ConfigureAwait(false); TransportState = TransportState.Paused; @@ -542,7 +543,7 @@ namespace Emby.Dlna.PlayTo return; } - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + var result = await new SsdpHttpClient(_httpClientFactory).SendCommandAsync( Properties.BaseUrl, service, command.Name, @@ -592,7 +593,7 @@ namespace Emby.Dlna.PlayTo return; } - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + var result = await new SsdpHttpClient(_httpClientFactory).SendCommandAsync( Properties.BaseUrl, service, command.Name, @@ -625,7 +626,7 @@ namespace Emby.Dlna.PlayTo return null; } - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + var result = await new SsdpHttpClient(_httpClientFactory).SendCommandAsync( Properties.BaseUrl, service, command.Name, @@ -667,7 +668,7 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + var result = await new SsdpHttpClient(_httpClientFactory).SendCommandAsync( Properties.BaseUrl, service, command.Name, @@ -734,7 +735,7 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + var result = await new SsdpHttpClient(_httpClientFactory).SendCommandAsync( Properties.BaseUrl, service, command.Name, @@ -912,7 +913,7 @@ namespace Emby.Dlna.PlayTo string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); - var httpClient = new SsdpHttpClient(_httpClient); + var httpClient = new SsdpHttpClient(_httpClientFactory); var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); @@ -940,7 +941,7 @@ namespace Emby.Dlna.PlayTo string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); - var httpClient = new SsdpHttpClient(_httpClient); + var httpClient = new SsdpHttpClient(_httpClientFactory); _logger.LogDebug("Dlna Device.GetRenderingProtocolAsync"); var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); @@ -969,9 +970,9 @@ namespace Emby.Dlna.PlayTo return baseUrl + url; } - public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, ILogger logger, CancellationToken cancellationToken) + public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClientFactory httpClientFactory, ILogger logger, CancellationToken cancellationToken) { - var ssdpHttpClient = new SsdpHttpClient(httpClient); + var ssdpHttpClient = new SsdpHttpClient(httpClientFactory); var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false); @@ -1079,7 +1080,7 @@ namespace Emby.Dlna.PlayTo } } - return new Device(deviceProperties, httpClient, logger); + return new Device(deviceProperties, httpClientFactory, logger); } private static DeviceIcon CreateIcon(XElement element) diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 328759c5bc..460ac2d8d1 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -669,62 +669,57 @@ namespace Emby.Dlna.PlayTo private Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken) { - if (Enum.TryParse(command.Name, true, out GeneralCommandType commandType)) - { - switch (commandType) - { - case GeneralCommandType.VolumeDown: - return _device.VolumeDown(cancellationToken); - case GeneralCommandType.VolumeUp: - return _device.VolumeUp(cancellationToken); - case GeneralCommandType.Mute: - return _device.Mute(cancellationToken); - case GeneralCommandType.Unmute: - return _device.Unmute(cancellationToken); - case GeneralCommandType.ToggleMute: - return _device.ToggleMute(cancellationToken); - case GeneralCommandType.SetAudioStreamIndex: - if (command.Arguments.TryGetValue("Index", out string index)) + switch (command.Name) + { + case GeneralCommandType.VolumeDown: + return _device.VolumeDown(cancellationToken); + case GeneralCommandType.VolumeUp: + return _device.VolumeUp(cancellationToken); + case GeneralCommandType.Mute: + return _device.Mute(cancellationToken); + case GeneralCommandType.Unmute: + return _device.Unmute(cancellationToken); + case GeneralCommandType.ToggleMute: + return _device.ToggleMute(cancellationToken); + case GeneralCommandType.SetAudioStreamIndex: + if (command.Arguments.TryGetValue("Index", out string index)) + { + if (int.TryParse(index, NumberStyles.Integer, _usCulture, out var val)) { - if (int.TryParse(index, NumberStyles.Integer, _usCulture, out var val)) - { - return SetAudioStreamIndex(val); - } - - throw new ArgumentException("Unsupported SetAudioStreamIndex value supplied."); + return SetAudioStreamIndex(val); } - throw new ArgumentException("SetAudioStreamIndex argument cannot be null"); - case GeneralCommandType.SetSubtitleStreamIndex: - if (command.Arguments.TryGetValue("Index", out index)) - { - if (int.TryParse(index, NumberStyles.Integer, _usCulture, out var val)) - { - return SetSubtitleStreamIndex(val); - } + throw new ArgumentException("Unsupported SetAudioStreamIndex value supplied."); + } - throw new ArgumentException("Unsupported SetSubtitleStreamIndex value supplied."); + throw new ArgumentException("SetAudioStreamIndex argument cannot be null"); + case GeneralCommandType.SetSubtitleStreamIndex: + if (command.Arguments.TryGetValue("Index", out index)) + { + if (int.TryParse(index, NumberStyles.Integer, _usCulture, out var val)) + { + return SetSubtitleStreamIndex(val); } - throw new ArgumentException("SetSubtitleStreamIndex argument cannot be null"); - case GeneralCommandType.SetVolume: - if (command.Arguments.TryGetValue("Volume", out string vol)) - { - if (int.TryParse(vol, NumberStyles.Integer, _usCulture, out var volume)) - { - return _device.SetVolume(volume, cancellationToken); - } + throw new ArgumentException("Unsupported SetSubtitleStreamIndex value supplied."); + } - throw new ArgumentException("Unsupported volume value supplied."); + throw new ArgumentException("SetSubtitleStreamIndex argument cannot be null"); + case GeneralCommandType.SetVolume: + if (command.Arguments.TryGetValue("Volume", out string vol)) + { + if (int.TryParse(vol, NumberStyles.Integer, _usCulture, out var volume)) + { + return _device.SetVolume(volume, cancellationToken); } - throw new ArgumentException("Volume argument cannot be null"); - default: - return Task.CompletedTask; - } - } + throw new ArgumentException("Unsupported volume value supplied."); + } - return Task.CompletedTask; + throw new ArgumentException("Volume argument cannot be null"); + default: + return Task.CompletedTask; + } } private async Task SetAudioStreamIndex(int? newIndex) diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index ff801f2630..21877f121f 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -4,6 +4,7 @@ using System; using System.Globalization; using System.Linq; using System.Net; +using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Jellyfin.Data.Events; @@ -33,7 +34,7 @@ namespace Emby.Dlna.PlayTo private readonly IDlnaManager _dlnaManager; private readonly IServerApplicationHost _appHost; private readonly IImageProcessor _imageProcessor; - private readonly IHttpClient _httpClient; + private readonly IHttpClientFactory _httpClientFactory; private readonly IServerConfigurationManager _config; private readonly IUserDataManager _userDataManager; private readonly ILocalizationManager _localization; @@ -46,7 +47,7 @@ namespace Emby.Dlna.PlayTo private SemaphoreSlim _sessionLock = new SemaphoreSlim(1, 1); private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); - public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder) + public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClientFactory httpClientFactory, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder) { _logger = logger; _sessionManager = sessionManager; @@ -56,7 +57,7 @@ namespace Emby.Dlna.PlayTo _appHost = appHost; _imageProcessor = imageProcessor; _deviceDiscovery = deviceDiscovery; - _httpClient = httpClient; + _httpClientFactory = httpClientFactory; _config = config; _userDataManager = userDataManager; _localization = localization; @@ -129,25 +130,21 @@ namespace Emby.Dlna.PlayTo } } - private string GetUuid(string usn) + private static string GetUuid(string usn) { - var found = false; - var index = usn.IndexOf("uuid:", StringComparison.OrdinalIgnoreCase); - if (index != -1) - { - usn = usn.Substring(index); - found = true; - } + const string UuidStr = "uuid:"; + const string UuidColonStr = "::"; - index = usn.IndexOf("::", StringComparison.OrdinalIgnoreCase); + var index = usn.IndexOf(UuidStr, StringComparison.OrdinalIgnoreCase); if (index != -1) { - usn = usn.Substring(0, index); + return usn.Substring(index + UuidStr.Length); } - if (found) + index = usn.IndexOf(UuidColonStr, StringComparison.OrdinalIgnoreCase); + if (index != -1) { - return usn; + usn = usn.Substring(0, index + UuidColonStr.Length); } return usn.GetMD5().ToString("N", CultureInfo.InvariantCulture); @@ -174,7 +171,7 @@ namespace Emby.Dlna.PlayTo if (controller == null) { - var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _logger, cancellationToken).ConfigureAwait(false); + var device = await Device.CreateuPnpDeviceAsync(uri, _httpClientFactory, _logger, cancellationToken).ConfigureAwait(false); string deviceName = device.Properties.Name; diff --git a/Emby.Dlna/PlayTo/SsdpHttpClient.cs b/Emby.Dlna/PlayTo/SsdpHttpClient.cs index ab262bebfc..c8c36fc972 100644 --- a/Emby.Dlna/PlayTo/SsdpHttpClient.cs +++ b/Emby.Dlna/PlayTo/SsdpHttpClient.cs @@ -4,6 +4,8 @@ using System; using System.Globalization; using System.IO; using System.Net.Http; +using System.Net.Http.Headers; +using System.Net.Mime; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -20,11 +22,11 @@ namespace Emby.Dlna.PlayTo private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IHttpClient _httpClient; + private readonly IHttpClientFactory _httpClientFactory; - public SsdpHttpClient(IHttpClient httpClient) + public SsdpHttpClient(IHttpClientFactory httpClientFactory) { - _httpClient = httpClient; + _httpClientFactory = httpClientFactory; } public async Task<XDocument> SendCommandAsync( @@ -36,20 +38,18 @@ namespace Emby.Dlna.PlayTo CancellationToken cancellationToken = default) { var url = NormalizeServiceUrl(baseUrl, service.ControlUrl); - using (var response = await PostSoapDataAsync( - url, - $"\"{service.ServiceType}#{command}\"", - postData, - header, - cancellationToken) - .ConfigureAwait(false)) - using (var stream = response.Content) - using (var reader = new StreamReader(stream, Encoding.UTF8)) - { - return XDocument.Parse( - await reader.ReadToEndAsync().ConfigureAwait(false), - LoadOptions.PreserveWhitespace); - } + using var response = await PostSoapDataAsync( + url, + $"\"{service.ServiceType}#{command}\"", + postData, + header, + cancellationToken) + .ConfigureAwait(false); + await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + using var reader = new StreamReader(stream, Encoding.UTF8); + return XDocument.Parse( + await reader.ReadToEndAsync().ConfigureAwait(false), + LoadOptions.PreserveWhitespace); } private static string NormalizeServiceUrl(string baseUrl, string serviceUrl) @@ -76,49 +76,32 @@ namespace Emby.Dlna.PlayTo int eventport, int timeOut = 3600) { - var options = new HttpRequestOptions - { - Url = url, - UserAgent = USERAGENT, - LogErrorResponseBody = true, - BufferContent = false, - }; - - options.RequestHeaders["HOST"] = ip + ":" + port.ToString(_usCulture); - options.RequestHeaders["CALLBACK"] = "<" + localIp + ":" + eventport.ToString(_usCulture) + ">"; - options.RequestHeaders["NT"] = "upnp:event"; - options.RequestHeaders["TIMEOUT"] = "Second-" + timeOut.ToString(_usCulture); - - using (await _httpClient.SendAsync(options, new HttpMethod("SUBSCRIBE")).ConfigureAwait(false)) - { - } + using var options = new HttpRequestMessage(new HttpMethod("SUBSCRIBE"), url); + options.Headers.UserAgent.ParseAdd(USERAGENT); + options.Headers.TryAddWithoutValidation("HOST", ip + ":" + port.ToString(_usCulture)); + options.Headers.TryAddWithoutValidation("CALLBACK", "<" + localIp + ":" + eventport.ToString(_usCulture) + ">"); + options.Headers.TryAddWithoutValidation("NT", "upnp:event"); + options.Headers.TryAddWithoutValidation("TIMEOUT", "Second-" + timeOut.ToString(_usCulture)); + + using var response = await _httpClientFactory.CreateClient(NamedClient.Default) + .SendAsync(options, HttpCompletionOption.ResponseHeadersRead) + .ConfigureAwait(false); } public async Task<XDocument> GetDataAsync(string url, CancellationToken cancellationToken) { - var options = new HttpRequestOptions - { - Url = url, - UserAgent = USERAGENT, - LogErrorResponseBody = true, - BufferContent = false, - - CancellationToken = cancellationToken - }; - - options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName; - - using (var response = await _httpClient.SendAsync(options, HttpMethod.Get).ConfigureAwait(false)) - using (var stream = response.Content) - using (var reader = new StreamReader(stream, Encoding.UTF8)) - { - return XDocument.Parse( - await reader.ReadToEndAsync().ConfigureAwait(false), - LoadOptions.PreserveWhitespace); - } + using var options = new HttpRequestMessage(HttpMethod.Get, url); + options.Headers.UserAgent.ParseAdd(USERAGENT); + options.Headers.TryAddWithoutValidation("FriendlyName.DLNA.ORG", FriendlyName); + using var response = await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(options, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + using var reader = new StreamReader(stream, Encoding.UTF8); + return XDocument.Parse( + await reader.ReadToEndAsync().ConfigureAwait(false), + LoadOptions.PreserveWhitespace); } - private Task<HttpResponseInfo> PostSoapDataAsync( + private async Task<HttpResponseMessage> PostSoapDataAsync( string url, string soapAction, string postData, @@ -130,29 +113,20 @@ namespace Emby.Dlna.PlayTo soapAction = $"\"{soapAction}\""; } - var options = new HttpRequestOptions - { - Url = url, - UserAgent = USERAGENT, - LogErrorResponseBody = true, - BufferContent = false, - - CancellationToken = cancellationToken - }; - - options.RequestHeaders["SOAPAction"] = soapAction; - options.RequestHeaders["Pragma"] = "no-cache"; - options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName; + using var options = new HttpRequestMessage(HttpMethod.Post, url); + options.Headers.UserAgent.ParseAdd(USERAGENT); + options.Headers.TryAddWithoutValidation("SOAPACTION", soapAction); + options.Headers.TryAddWithoutValidation("Pragma", "no-cache"); + options.Headers.TryAddWithoutValidation("FriendlyName.DLNA.ORG", FriendlyName); if (!string.IsNullOrEmpty(header)) { - options.RequestHeaders["contentFeatures.dlna.org"] = header; + options.Headers.TryAddWithoutValidation("contentFeatures.dlna.org", header); } - options.RequestContentType = "text/xml"; - options.RequestContent = postData; + options.Content = new StringContent(postData, Encoding.UTF8, MediaTypeNames.Text.Xml); - return _httpClient.Post(options); + return await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(options, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); } } } diff --git a/Emby.Dlna/Service/BaseService.cs b/Emby.Dlna/Service/BaseService.cs index 40d069e7cd..a97c4d63a6 100644 --- a/Emby.Dlna/Service/BaseService.cs +++ b/Emby.Dlna/Service/BaseService.cs @@ -1,25 +1,21 @@ #pragma warning disable CS1591 +using System.Net.Http; using Emby.Dlna.Eventing; -using MediaBrowser.Common.Net; using Microsoft.Extensions.Logging; namespace Emby.Dlna.Service { public class BaseService : IDlnaEventManager { - protected BaseService(ILogger<BaseService> logger, IHttpClient httpClient) + protected BaseService(ILogger<BaseService> logger, IHttpClientFactory httpClientFactory) { Logger = logger; - HttpClient = httpClient; - - EventManager = new DlnaEventManager(logger, HttpClient); + EventManager = new DlnaEventManager(logger, httpClientFactory); } protected IDlnaEventManager EventManager { get; } - protected IHttpClient HttpClient { get; } - protected ILogger Logger { get; } public EventSubscriptionResponse CancelEventSubscription(string subscriptionId) |
