diff options
| -rw-r--r-- | .github/workflows/codeql-analysis.yml | 6 | ||||
| -rw-r--r-- | Directory.Packages.props | 4 | ||||
| -rw-r--r-- | Emby.Dlna/Extensions/DlnaServiceCollectionExtensions.cs | 69 | ||||
| -rw-r--r-- | Emby.Dlna/Main/DlnaEntryPoint.cs | 135 | ||||
| -rw-r--r-- | Emby.Server.Implementations/ApplicationHost.cs | 8 | ||||
| -rw-r--r-- | Emby.Server.Implementations/Localization/Core/sk.json | 2 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/DlnaServerController.cs | 16 | ||||
| -rw-r--r-- | Jellyfin.Api/Helpers/StreamingHelpers.cs | 20 | ||||
| -rw-r--r-- | Jellyfin.Server/Startup.cs | 20 | ||||
| -rw-r--r-- | MediaBrowser.Common/MediaBrowser.Common.csproj | 4 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Manager/ProviderManager.cs | 6 |
11 files changed, 120 insertions, 170 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 4c9d68d11..a6062940c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -27,11 +27,11 @@ jobs: dotnet-version: '7.0.x' - name: Initialize CodeQL - uses: github/codeql-action/init@fdcae64e1484d349b3366718cdfef3d404390e85 # v2.22.1 + uses: github/codeql-action/init@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2 with: languages: ${{ matrix.language }} queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@fdcae64e1484d349b3366718cdfef3d404390e85 # v2.22.1 + uses: github/codeql-action/autobuild@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fdcae64e1484d349b3366718cdfef3d404390e85 # v2.22.1 + uses: github/codeql-action/analyze@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2 diff --git a/Directory.Packages.props b/Directory.Packages.props index 33736482c..e26005f8e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -86,8 +86,8 @@ <PackageVersion Include="TMDbLib" Version="2.0.0" /> <PackageVersion Include="UTF.Unknown" Version="2.5.1" /> <PackageVersion Include="Xunit.Priority" Version="1.1.6" /> - <PackageVersion Include="xunit.runner.visualstudio" Version="2.5.1" /> + <PackageVersion Include="xunit.runner.visualstudio" Version="2.5.3" /> <PackageVersion Include="Xunit.SkippableFact" Version="1.4.13" /> - <PackageVersion Include="xunit" Version="2.5.1" /> + <PackageVersion Include="xunit" Version="2.5.2" /> </ItemGroup> </Project> diff --git a/Emby.Dlna/Extensions/DlnaServiceCollectionExtensions.cs b/Emby.Dlna/Extensions/DlnaServiceCollectionExtensions.cs new file mode 100644 index 000000000..87ec14d95 --- /dev/null +++ b/Emby.Dlna/Extensions/DlnaServiceCollectionExtensions.cs @@ -0,0 +1,69 @@ +using System; +using System.Globalization; +using System.Net; +using System.Net.Http; +using System.Text; +using Emby.Dlna.ConnectionManager; +using Emby.Dlna.ContentDirectory; +using Emby.Dlna.MediaReceiverRegistrar; +using Emby.Dlna.Ssdp; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Dlna; +using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Net; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Rssdp.Infrastructure; + +namespace Emby.Dlna.Extensions; + +/// <summary> +/// Extension methods for adding DLNA services. +/// </summary> +public static class DlnaServiceCollectionExtensions +{ + /// <summary> + /// Adds DLNA services to the provided <see cref="IServiceCollection"/>. + /// </summary> + /// <param name="services">The <see cref="IServiceCollection"/>.</param> + /// <param name="applicationHost">The <see cref="IServerApplicationHost"/>.</param> + public static void AddDlnaServices( + this IServiceCollection services, + IServerApplicationHost applicationHost) + { + services.AddHttpClient(NamedClient.Dlna, c => + { + c.DefaultRequestHeaders.UserAgent.ParseAdd( + string.Format( + CultureInfo.InvariantCulture, + "{0}/{1} UPnP/1.0 {2}/{3}", + Environment.OSVersion.Platform, + Environment.OSVersion, + applicationHost.Name, + applicationHost.ApplicationVersionString)); + + c.DefaultRequestHeaders.Add("CPFN.UPNP.ORG", applicationHost.FriendlyName); // Required for UPnP DeviceArchitecture v2.0 + c.DefaultRequestHeaders.Add("FriendlyName.DLNA.ORG", applicationHost.FriendlyName); // REVIEW: where does this come from? + }) + .ConfigurePrimaryHttpMessageHandler(_ => new SocketsHttpHandler + { + AutomaticDecompression = DecompressionMethods.All, + RequestHeaderEncodingSelector = (_, _) => Encoding.UTF8 + }); + + services.AddSingleton<IDlnaManager, DlnaManager>(); + services.AddSingleton<IDeviceDiscovery, DeviceDiscovery>(); + services.AddSingleton<IContentDirectory, ContentDirectoryService>(); + services.AddSingleton<IConnectionManager, ConnectionManagerService>(); + services.AddSingleton<IMediaReceiverRegistrar, MediaReceiverRegistrarService>(); + + services.AddSingleton<ISsdpCommunicationsServer>(provider => new SsdpCommunicationsServer( + provider.GetRequiredService<ISocketFactory>(), + provider.GetRequiredService<INetworkManager>(), + provider.GetRequiredService<ILogger<SsdpCommunicationsServer>>()) + { + IsShared = true + }); + } +} diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 83b0ef316..aa7012487 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -23,10 +23,8 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; -using MediaBrowser.Controller.TV; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Globalization; -using MediaBrowser.Model.Net; using Microsoft.Extensions.Logging; using Rssdp; using Rssdp.Infrastructure; @@ -49,14 +47,13 @@ namespace Emby.Dlna.Main private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaEncoder _mediaEncoder; private readonly IDeviceDiscovery _deviceDiscovery; - private readonly ISocketFactory _socketFactory; + private readonly ISsdpCommunicationsServer _communicationsServer; private readonly INetworkManager _networkManager; - private readonly object _syncLock = new object(); + private readonly object _syncLock = new(); private readonly bool _disabled; private PlayToManager _manager; private SsdpDevicePublisher _publisher; - private ISsdpCommunicationsServer _communicationsServer; private bool _disposed; @@ -75,10 +72,8 @@ namespace Emby.Dlna.Main IMediaSourceManager mediaSourceManager, IDeviceDiscovery deviceDiscovery, IMediaEncoder mediaEncoder, - ISocketFactory socketFactory, - INetworkManager networkManager, - IUserViewManager userViewManager, - ITVSeriesManager tvSeriesManager) + ISsdpCommunicationsServer communicationsServer, + INetworkManager networkManager) { _config = config; _appHost = appHost; @@ -93,37 +88,10 @@ namespace Emby.Dlna.Main _mediaSourceManager = mediaSourceManager; _deviceDiscovery = deviceDiscovery; _mediaEncoder = mediaEncoder; - _socketFactory = socketFactory; + _communicationsServer = communicationsServer; _networkManager = networkManager; _logger = loggerFactory.CreateLogger<DlnaEntryPoint>(); - ContentDirectory = new ContentDirectory.ContentDirectoryService( - dlnaManager, - userDataManager, - imageProcessor, - libraryManager, - config, - userManager, - loggerFactory.CreateLogger<ContentDirectory.ContentDirectoryService>(), - httpClientFactory, - localizationManager, - mediaSourceManager, - userViewManager, - mediaEncoder, - tvSeriesManager); - - ConnectionManager = new ConnectionManager.ConnectionManagerService( - dlnaManager, - config, - loggerFactory.CreateLogger<ConnectionManager.ConnectionManagerService>(), - httpClientFactory); - - MediaReceiverRegistrar = new MediaReceiverRegistrar.MediaReceiverRegistrarService( - loggerFactory.CreateLogger<MediaReceiverRegistrar.MediaReceiverRegistrarService>(), - httpClientFactory, - config); - Current = this; - var netConfig = config.GetConfiguration<NetworkConfiguration>(NetworkConfigurationStore.StoreKey); _disabled = appHost.ListenWithHttps && netConfig.RequireHttps; @@ -133,19 +101,6 @@ namespace Emby.Dlna.Main } } - public static DlnaEntryPoint Current { get; private set; } - - /// <summary> - /// Gets a value indicating whether the dlna server is enabled. - /// </summary> - public static bool Enabled { get; private set; } - - public IContentDirectory ContentDirectory { get; private set; } - - public IConnectionManager ConnectionManager { get; private set; } - - public IMediaReceiverRegistrar MediaReceiverRegistrar { get; private set; } - public async Task RunAsync() { await ((DlnaManager)_dlnaManager).InitProfilesAsync().ConfigureAwait(false); @@ -172,9 +127,7 @@ namespace Emby.Dlna.Main private void ReloadComponents() { var options = _config.GetDlnaConfiguration(); - Enabled = options.EnableServer; - - StartSsdpHandler(); + StartDeviceDiscovery(); if (options.EnableServer) { @@ -195,37 +148,11 @@ namespace Emby.Dlna.Main } } - private void StartSsdpHandler() + private void StartDeviceDiscovery() { try { - if (_communicationsServer is null) - { - _communicationsServer = new SsdpCommunicationsServer( - _socketFactory, - _networkManager, - _logger) - { - IsShared = true - }; - - StartDeviceDiscovery(_communicationsServer); - } - } - catch (Exception ex) - { - _logger.LogError(ex, "Error starting SSDP handlers"); - } - } - - private void StartDeviceDiscovery(ISsdpCommunicationsServer communicationsServer) - { - try - { - if (communicationsServer is not null) - { - ((DeviceDiscovery)_deviceDiscovery).Start(communicationsServer); - } + ((DeviceDiscovery)_deviceDiscovery).Start(_communicationsServer); } catch (Exception ex) { @@ -233,19 +160,6 @@ namespace Emby.Dlna.Main } } - private void DisposeDeviceDiscovery() - { - try - { - _logger.LogInformation("Disposing DeviceDiscovery"); - ((DeviceDiscovery)_deviceDiscovery).Dispose(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error stopping device discovery"); - } - } - public void StartDevicePublisher(Configuration.DlnaOptions options) { if (_publisher is not null) @@ -318,7 +232,7 @@ namespace Emby.Dlna.Main // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc. }; - SetProperies(device, fullService); + SetProperties(device, fullService); _publisher.AddDevice(device); var embeddedDevices = new[] @@ -339,13 +253,13 @@ namespace Emby.Dlna.Main // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc. }; - SetProperies(embeddedDevice, subDevice); + SetProperties(embeddedDevice, subDevice); device.AddDevice(embeddedDevice); } } } - private string CreateUuid(string text) + private static string CreateUuid(string text) { if (!Guid.TryParse(text, out var guid)) { @@ -355,15 +269,14 @@ namespace Emby.Dlna.Main return guid.ToString("D", CultureInfo.InvariantCulture); } - private void SetProperies(SsdpDevice device, string fullDeviceType) + private static void SetProperties(SsdpDevice device, string fullDeviceType) { - var service = fullDeviceType.Replace("urn:", string.Empty, StringComparison.OrdinalIgnoreCase).Replace(":1", string.Empty, StringComparison.OrdinalIgnoreCase); - - var serviceParts = service.Split(':'); + var serviceParts = fullDeviceType + .Replace("urn:", string.Empty, StringComparison.OrdinalIgnoreCase) + .Replace(":1", string.Empty, StringComparison.OrdinalIgnoreCase) + .Split(':'); - var deviceTypeNamespace = serviceParts[0].Replace('.', '-'); - - device.DeviceTypeNamespace = deviceTypeNamespace; + device.DeviceTypeNamespace = serviceParts[0].Replace('.', '-'); device.DeviceClass = serviceParts[1]; device.DeviceType = serviceParts[2]; } @@ -444,20 +357,6 @@ namespace Emby.Dlna.Main DisposeDevicePublisher(); DisposePlayToManager(); - DisposeDeviceDiscovery(); - - if (_communicationsServer is not null) - { - _logger.LogInformation("Disposing SsdpCommunicationsServer"); - _communicationsServer.Dispose(); - _communicationsServer = null; - } - - ContentDirectory = null; - ConnectionManager = null; - MediaReceiverRegistrar = null; - Current = null; - _disposed = true; } } diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index c247178ee..c9bf7f085 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -13,9 +13,7 @@ using System.Net; using System.Reflection; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; -using Emby.Dlna; using Emby.Dlna.Main; -using Emby.Dlna.Ssdp; using Emby.Naming.Common; using Emby.Photos; using Emby.Server.Implementations.Channels; @@ -58,7 +56,6 @@ using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.ClientEvent; using MediaBrowser.Controller.Collections; using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; @@ -82,7 +79,6 @@ using MediaBrowser.LocalMetadata.Savers; using MediaBrowser.MediaEncoding.BdInfo; using MediaBrowser.MediaEncoding.Subtitles; using MediaBrowser.Model.Cryptography; -using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.IO; using MediaBrowser.Model.MediaInfo; @@ -563,8 +559,6 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton<ISessionManager, SessionManager>(); - serviceCollection.AddSingleton<IDlnaManager, DlnaManager>(); - serviceCollection.AddSingleton<ICollectionManager, CollectionManager>(); serviceCollection.AddSingleton<IPlaylistManager, PlaylistManager>(); @@ -576,8 +570,6 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton<IUserViewManager, UserViewManager>(); - serviceCollection.AddSingleton<IDeviceDiscovery, DeviceDiscovery>(); - serviceCollection.AddSingleton<IChapterManager, ChapterManager>(); serviceCollection.AddSingleton<IEncodingManager, MediaEncoder.EncodingManager>(); diff --git a/Emby.Server.Implementations/Localization/Core/sk.json b/Emby.Server.Implementations/Localization/Core/sk.json index 858cc40dd..c231d76fe 100644 --- a/Emby.Server.Implementations/Localization/Core/sk.json +++ b/Emby.Server.Implementations/Localization/Core/sk.json @@ -124,5 +124,5 @@ "TaskKeyframeExtractorDescription": "Extrahuje kľúčové snímky z video súborov na vytvorenie presnejších HLS playlistov. Táto úloha môže trvať dlhšiu dobu.", "TaskKeyframeExtractor": "Extraktor kľúčových snímkov", "External": "Externé", - "HearingImpaired": "Sluchovo Postihnutý" + "HearingImpaired": "Sluchovo postihnutí" } diff --git a/Jellyfin.Api/Controllers/DlnaServerController.cs b/Jellyfin.Api/Controllers/DlnaServerController.cs index 95b296fae..42576934b 100644 --- a/Jellyfin.Api/Controllers/DlnaServerController.cs +++ b/Jellyfin.Api/Controllers/DlnaServerController.cs @@ -5,7 +5,6 @@ using System.IO; using System.Net.Mime; using System.Threading.Tasks; using Emby.Dlna; -using Emby.Dlna.Main; using Jellyfin.Api.Attributes; using Jellyfin.Api.Constants; using MediaBrowser.Controller.Dlna; @@ -33,12 +32,19 @@ public class DlnaServerController : BaseJellyfinApiController /// Initializes a new instance of the <see cref="DlnaServerController"/> class. /// </summary> /// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param> - public DlnaServerController(IDlnaManager dlnaManager) + /// <param name="contentDirectory">Instance of the <see cref="IContentDirectory"/> interface.</param> + /// <param name="connectionManager">Instance of the <see cref="IConnectionManager"/> interface.</param> + /// <param name="mediaReceiverRegistrar">Instance of the <see cref="IMediaReceiverRegistrar"/> interface.</param> + public DlnaServerController( + IDlnaManager dlnaManager, + IContentDirectory contentDirectory, + IConnectionManager connectionManager, + IMediaReceiverRegistrar mediaReceiverRegistrar) { _dlnaManager = dlnaManager; - _contentDirectory = DlnaEntryPoint.Current.ContentDirectory; - _connectionManager = DlnaEntryPoint.Current.ConnectionManager; - _mediaReceiverRegistrar = DlnaEntryPoint.Current.MediaReceiverRegistrar; + _contentDirectory = contentDirectory; + _connectionManager = connectionManager; + _mediaReceiverRegistrar = mediaReceiverRegistrar; } /// <summary> diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs index a653c5795..11f6bcf6b 100644 --- a/Jellyfin.Api/Helpers/StreamingHelpers.cs +++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs @@ -421,13 +421,12 @@ public static class StreamingHelpers /// <param name="state">The state.</param> /// <param name="mediaSource">The mediaSource.</param> /// <returns>System.String.</returns> - private static string? GetOutputFileExtension(StreamState state, MediaSourceInfo? mediaSource) + private static string GetOutputFileExtension(StreamState state, MediaSourceInfo? mediaSource) { - var ext = Path.GetExtension(state.RequestedUrl.AsSpan()); - - if (ext.IsEmpty) + var ext = Path.GetExtension(state.RequestedUrl); + if (!string.IsNullOrEmpty(ext)) { - return null; + return ext; } // Try to infer based on the desired video codec @@ -463,10 +462,9 @@ public static class StreamingHelpers return ".asf"; } } - - // Try to infer based on the desired audio codec - if (!state.IsVideoRequest) + else { + // Try to infer based on the desired audio codec var audioCodec = state.Request.AudioCodec; if (string.Equals("aac", audioCodec, StringComparison.OrdinalIgnoreCase)) @@ -497,7 +495,7 @@ public static class StreamingHelpers return '.' + (idx == -1 ? mediaSource.Container : mediaSource.Container[..idx]).Trim(); } - return null; + throw new InvalidOperationException("Failed to find an appropriate file extension"); } /// <summary> @@ -509,12 +507,12 @@ public static class StreamingHelpers /// <param name="deviceId">The device id.</param> /// <param name="playSessionId">The play session id.</param> /// <returns>The complete file path, including the folder, for the transcoding file.</returns> - private static string GetOutputFilePath(StreamState state, string? outputFileExtension, IServerConfigurationManager serverConfigurationManager, string? deviceId, string? playSessionId) + private static string GetOutputFilePath(StreamState state, string outputFileExtension, IServerConfigurationManager serverConfigurationManager, string? deviceId, string? playSessionId) { var data = $"{state.MediaPath}-{state.UserAgent}-{deviceId!}-{playSessionId!}"; var filename = data.GetMD5().ToString("N", CultureInfo.InvariantCulture); - var ext = outputFileExtension?.ToLowerInvariant(); + var ext = outputFileExtension.ToLowerInvariant(); var folder = serverConfigurationManager.GetTranscodePath(); return Path.Combine(folder, filename + ext); diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index b759b6bca..2acddb243 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -1,10 +1,10 @@ using System; -using System.Globalization; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Net.Mime; using System.Text; +using Emby.Dlna.Extensions; using Jellyfin.Api.Middleware; using Jellyfin.MediaEncoding.Hls.Extensions; using Jellyfin.Networking.Configuration; @@ -27,7 +27,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Hosting; -using Microsoft.VisualBasic; using Prometheus; namespace Jellyfin.Server @@ -120,26 +119,11 @@ namespace Jellyfin.Server }) .ConfigurePrimaryHttpMessageHandler(defaultHttpClientHandlerDelegate); - services.AddHttpClient(NamedClient.Dlna, c => - { - c.DefaultRequestHeaders.UserAgent.ParseAdd( - string.Format( - CultureInfo.InvariantCulture, - "{0}/{1} UPnP/1.0 {2}/{3}", - Environment.OSVersion.Platform, - Environment.OSVersion, - _serverApplicationHost.Name, - _serverApplicationHost.ApplicationVersionString)); - - c.DefaultRequestHeaders.Add("CPFN.UPNP.ORG", _serverApplicationHost.FriendlyName); // Required for UPnP DeviceArchitecture v2.0 - c.DefaultRequestHeaders.Add("FriendlyName.DLNA.ORG", _serverApplicationHost.FriendlyName); // REVIEW: where does this come from? - }) - .ConfigurePrimaryHttpMessageHandler(defaultHttpClientHandlerDelegate); - services.AddHealthChecks() .AddCheck<DbContextFactoryHealthCheck<JellyfinDbContext>>(nameof(JellyfinDbContext)); services.AddHlsPlaylistGenerator(); + services.AddDlnaServices(_serverApplicationHost); } /// <summary> diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 3f1a098e4..7015d991f 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -38,10 +38,6 @@ <SymbolPackageFormat>snupkg</SymbolPackageFormat> </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> - <CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors> - </PropertyGroup> - <PropertyGroup Condition=" '$(Stability)'=='Unstable'"> <!-- Include all symbols in the main nupkg until Azure Artifact Feed starts supporting ingesting NuGet symbol packages. --> <AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder> diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index f3211ba45..d0bb34d52 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -943,6 +943,12 @@ namespace MediaBrowser.Providers.Manager /// <inheritdoc/> public void QueueRefresh(Guid itemId, MetadataRefreshOptions options, RefreshPriority priority) { + ArgumentNullException.ThrowIfNull(itemId); + if (itemId.Equals(default)) + { + throw new ArgumentException("Guid can't be empty", nameof(itemId)); + } + if (_disposed) { return; |
