From 26af5ea45a8ea02b7a3f20b0ebc31ef19f850dea Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Tue, 25 Feb 2020 16:51:36 +0100 Subject: Do not set a static content root if the jellyfin-web directory does not exist or is empty --- Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs | 2 +- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs index c3cdcc222..be2d198ef 100644 --- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs +++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs @@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.AppBase /// /// Gets the path to the web UI resources folder. /// - /// The web UI resources path. + /// The web UI resources path, or null if the server is not hosting any web content. public string WebPath { get; } /// diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8ea188724..a5b88f64f 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -240,7 +240,7 @@ namespace Emby.Server.Implementations public int HttpsPort { get; private set; } /// - /// Gets the content root for the webhost. + /// Gets the content root for the webhost. If the webhost is not serving static web content, this will be null. /// public string ContentRoot { get; private set; } -- cgit v1.2.3 From 1b5999a1bc11ee386131e4bbce561896c0e1bced Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Tue, 25 Feb 2020 17:01:57 +0100 Subject: Open the Swagger API page on server start if not hosting the static web content --- Emby.Server.Implementations/ApplicationHost.cs | 3 +++ Emby.Server.Implementations/Browser/BrowserLauncher.cs | 10 ++++++++++ Emby.Server.Implementations/EntryPoints/StartupWizard.cs | 6 +++++- MediaBrowser.Controller/IServerApplicationHost.cs | 5 +++++ 4 files changed, 23 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index a5b88f64f..789b8724c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -244,6 +244,9 @@ namespace Emby.Server.Implementations /// public string ContentRoot { get; private set; } + /// + public bool IsHostingContent => ContentRoot != null; + /// /// Gets the server configuration manager. /// diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs index f5da0d018..b17c2b270 100644 --- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs +++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs @@ -29,6 +29,16 @@ namespace Emby.Server.Implementations.Browser OpenDashboardPage("index.html", appHost); } + /// + /// Opens the swagger API page. + /// + /// The app host. + public static void OpenSwaggerPage(IServerApplicationHost appHost) + { + var url = appHost.GetLocalApiUrl("localhost") + "/swagger/index.html"; + OpenUrl(appHost, url); + } + /// /// Opens the URL. /// diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 5f2d629fe..6b7e2805b 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -36,7 +36,11 @@ namespace Emby.Server.Implementations.EntryPoints return Task.CompletedTask; } - if (!_config.Configuration.IsStartupWizardCompleted) + if (!_appHost.IsHostingContent) + { + BrowserLauncher.OpenSwaggerPage(_appHost); + } + else if (!_config.Configuration.IsStartupWizardCompleted) { BrowserLauncher.OpenWebApp(_appHost); } diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 25f0905eb..134ed110b 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -16,6 +16,11 @@ namespace MediaBrowser.Controller { event EventHandler HasUpdateAvailableChanged; + /// + /// Gets a value indicating whether the server is hosting the static web content from jellyfin-web. + /// + bool IsHostingContent { get; } + /// /// Gets the system info. /// -- cgit v1.2.3 From f3be93a4de86177d87a3be919b7aaa6e394b819d Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Tue, 25 Feb 2020 17:02:51 +0100 Subject: Use the swagger API page as the default redirect path if not hosting the jellyfin-web content --- Emby.Server.Implementations/ConfigurationOptions.cs | 8 +++++++- Jellyfin.Server/Program.cs | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index 2ea7ff6e9..b733bd2d5 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -3,9 +3,15 @@ using static MediaBrowser.Controller.Extensions.ConfigurationExtensions; namespace Emby.Server.Implementations { + /// + /// Static class containing the default configuration options for the web server. + /// public static class ConfigurationOptions { - public static Dictionary Configuration => new Dictionary + /// + /// Gets the default configuration options. + /// + public static Dictionary DefaultConfiguration => new Dictionary { { "HttpListenerHost:DefaultRedirectPath", "web/index.html" }, { "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" }, diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 2ce7379fb..8c133576c 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -468,9 +468,16 @@ namespace Jellyfin.Server await resource.CopyToAsync(dst).ConfigureAwait(false); } + // Use the swagger API page as the default redirect path if not hosting the jellyfin-web content + var inMemoryDefaultConfig = ConfigurationOptions.DefaultConfiguration; + if (string.IsNullOrEmpty(appPaths.WebPath)) + { + inMemoryDefaultConfig["HttpListenerHost:DefaultRedirectPath"] = "swagger/index.html"; + } + return new ConfigurationBuilder() .SetBasePath(appPaths.ConfigurationDirectoryPath) - .AddInMemoryCollection(ConfigurationOptions.Configuration) + .AddInMemoryCollection(inMemoryDefaultConfig) .AddJsonFile("logging.json", false, true) .AddEnvironmentVariables("JELLYFIN_") .Build(); -- cgit v1.2.3 From 192ec57b608a2cd1f8b337fb416b84abccd7a2a0 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Tue, 25 Feb 2020 17:22:21 +0100 Subject: Remove log message executed before logger is initialized --- Emby.Server.Implementations/ConfigurationOptions.cs | 2 +- Jellyfin.Server/Program.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index b733bd2d5..456484813 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -9,7 +9,7 @@ namespace Emby.Server.Implementations public static class ConfigurationOptions { /// - /// Gets the default configuration options. + /// Gets a new copy of the default configuration options. /// public static Dictionary DefaultConfiguration => new Dictionary { diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 8c133576c..c4e3cd726 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -392,7 +392,6 @@ namespace Jellyfin.Server // ELSE IF $JELLYFIN_WEB_DIR // ELSE /jellyfin-web var webDir = options.WebDir; - if (string.IsNullOrEmpty(webDir)) { webDir = Environment.GetEnvironmentVariable("JELLYFIN_WEB_DIR"); @@ -407,7 +406,6 @@ namespace Jellyfin.Server // Reset webDir if the directory does not exist, or is empty if (!Directory.Exists(webDir) || !Directory.GetFiles(webDir).Any()) { - _logger.LogInformation("Server will not host static content because the web content directory does not exist or is empty: {ContentRoot}", webDir); webDir = null; } -- cgit v1.2.3 From 3043b7323b1a12e888ba8c4eb71f904724f43e3a Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 28 Feb 2020 17:57:38 +0100 Subject: Use constants for settings keys --- Emby.Server.Implementations/ConfigurationOptions.cs | 6 ++++-- Emby.Server.Implementations/HttpServer/HttpListenerHost.cs | 8 +++++++- Jellyfin.Server/Program.cs | 3 ++- MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs | 7 ++++++- 4 files changed, 19 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index 456484813..cc0d314ed 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using Emby.Server.Implementations.HttpServer; +using MediaBrowser.Providers.Music; using static MediaBrowser.Controller.Extensions.ConfigurationExtensions; namespace Emby.Server.Implementations @@ -13,8 +15,8 @@ namespace Emby.Server.Implementations /// public static Dictionary DefaultConfiguration => new Dictionary { - { "HttpListenerHost:DefaultRedirectPath", "web/index.html" }, - { "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" }, + { HttpListenerHost.DefaultRedirectKey, "web/index.html" }, + { MusicBrainzAlbumProvider.BaseUrlKey, "https://www.musicbrainz.org" }, { FfmpegProbeSizeKey, "1G" }, { FfmpegAnalyzeDurationKey, "200M" } }; diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 85602a67f..7f16c6834 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -30,6 +30,12 @@ namespace Emby.Server.Implementations.HttpServer { public class HttpListenerHost : IHttpServer, IDisposable { + /// + /// The settings key for a setting that specifies the default redirect path + /// to use for requests where the URL base prefix is invalid or missing. + /// + public const string DefaultRedirectKey = "HttpListenerHost:DefaultRedirectPath"; + private readonly ILogger _logger; private readonly IServerConfigurationManager _config; private readonly INetworkManager _networkManager; @@ -58,7 +64,7 @@ namespace Emby.Server.Implementations.HttpServer _appHost = applicationHost; _logger = logger; _config = config; - _defaultRedirectPath = configuration["HttpListenerHost:DefaultRedirectPath"]; + _defaultRedirectPath = configuration[DefaultRedirectKey]; _baseUrlPrefix = _config.Configuration.BaseUrl; _networkManager = networkManager; _jsonSerializer = jsonSerializer; diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 4048a0d03..7e03b0c9c 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using CommandLine; using Emby.Drawing; using Emby.Server.Implementations; +using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.IO; using Emby.Server.Implementations.Networking; using Jellyfin.Drawing.Skia; @@ -470,7 +471,7 @@ namespace Jellyfin.Server var inMemoryDefaultConfig = ConfigurationOptions.DefaultConfiguration; if (string.IsNullOrEmpty(appPaths.WebPath)) { - inMemoryDefaultConfig["HttpListenerHost:DefaultRedirectPath"] = "swagger/index.html"; + inMemoryDefaultConfig[HttpListenerHost.DefaultRedirectKey] = "swagger/index.html"; } return new ConfigurationBuilder() diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs index 8e71b625e..ed7688e5a 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs @@ -22,6 +22,11 @@ namespace MediaBrowser.Providers.Music { public class MusicBrainzAlbumProvider : IRemoteMetadataProvider, IHasOrder { + /// + /// The settings key for a setting that specifies the base URL to use for sending requests to MusicBrainz. + /// + public const string BaseUrlKey = "MusicBrainz:BaseUrl"; + /// /// The Jellyfin user-agent is unrestricted but source IP must not exceed /// one request per second, therefore we rate limit to avoid throttling. @@ -57,7 +62,7 @@ namespace MediaBrowser.Providers.Music _appHost = appHost; _logger = logger; - _musicBrainzBaseUrl = configuration["MusicBrainz:BaseUrl"]; + _musicBrainzBaseUrl = configuration[BaseUrlKey]; // Use a stopwatch to ensure we don't exceed the MusicBrainz rate limit _stopWatchMusicBrainz.Start(); -- cgit v1.2.3 From 3f4b9e9a81278c6f5c817036a7ae52b6f70557e4 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 28 Feb 2020 20:40:45 +0100 Subject: Add new 'nowebcontent' configuration flag --- .../ConfigurationOptions.cs | 1 + .../HttpServer/HttpListenerHost.cs | 2 +- .../Extensions/ConfigurationExtensions.cs | 31 ++++++++++++++++++++++ .../Music/MusicBrainzAlbumProvider.cs | 2 +- 4 files changed, 34 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index cc0d314ed..08a493cb7 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -15,6 +15,7 @@ namespace Emby.Server.Implementations /// public static Dictionary DefaultConfiguration => new Dictionary { + { NoWebContentKey, bool.FalseString }, { HttpListenerHost.DefaultRedirectKey, "web/index.html" }, { MusicBrainzAlbumProvider.BaseUrlKey, "https://www.musicbrainz.org" }, { FfmpegProbeSizeKey, "1G" }, diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 7f16c6834..546a59517 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -31,7 +31,7 @@ namespace Emby.Server.Implementations.HttpServer public class HttpListenerHost : IHttpServer, IDisposable { /// - /// The settings key for a setting that specifies the default redirect path + /// The key for a setting that specifies the default redirect path /// to use for requests where the URL base prefix is invalid or missing. /// public const string DefaultRedirectKey = "HttpListenerHost:DefaultRedirectPath"; diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs index 76c9b4b26..9dbc1a243 100644 --- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs @@ -1,3 +1,4 @@ +using System; using Microsoft.Extensions.Configuration; namespace MediaBrowser.Controller.Extensions @@ -7,6 +8,11 @@ namespace MediaBrowser.Controller.Extensions /// public static class ConfigurationExtensions { + /// + /// The key for a setting that indicates whether the application should host static web content. + /// + public const string NoWebContentKey = "nowebcontent"; + /// /// The key for the FFmpeg probe size option. /// @@ -17,6 +23,16 @@ namespace MediaBrowser.Controller.Extensions /// public const string FfmpegAnalyzeDurationKey = "FFmpeg:analyzeduration"; + /// + /// Retrieves a config value indicating whether the application should not host + /// static web content from the . + /// + /// The configuration to retrieve the value from. + /// The parsed config value. + /// The config value is not a valid bool string. See . + public static bool IsNoWebContent(this IConfiguration configuration) + => configuration.ParseBoolean(NoWebContentKey); + /// /// Retrieves the FFmpeg probe size from the . /// @@ -32,5 +48,20 @@ namespace MediaBrowser.Controller.Extensions /// The FFmpeg analyse duration option. public static string GetFFmpegAnalyzeDuration(this IConfiguration configuration) => configuration[FfmpegAnalyzeDurationKey]; + + /// + /// Convert the specified configuration string value its equivalent. + /// + /// The configuration to retrieve and parse the setting from. + /// The key to use to retrieve the string value from the configuration. + /// The parsed boolean value. + /// The config value is not a valid bool string. See . + public static bool ParseBoolean(this IConfiguration configuration, string key) + { + string configValue = configuration[key]; + return bool.TryParse(configValue, out bool result) ? + result : + throw new FormatException($"Invalid value for configuration option '{key}' (expected a boolean): {configValue}"); + } } } diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs index ed7688e5a..d217c6ad2 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs @@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzAlbumProvider : IRemoteMetadataProvider, IHasOrder { /// - /// The settings key for a setting that specifies the base URL to use for sending requests to MusicBrainz. + /// The key for a setting that specifies the base URL to use for sending requests to MusicBrainz. /// public const string BaseUrlKey = "MusicBrainz:BaseUrl"; -- cgit v1.2.3 From 29bad073ebeb10813c6468b6159ce3bd06398134 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 28 Feb 2020 20:49:04 +0100 Subject: Use config setting to decide if web content should be hosted Also fail server startup if web content is expected but missing --- Emby.Server.Implementations/ApplicationHost.cs | 5 +---- .../EntryPoints/StartupWizard.cs | 4 +++- Jellyfin.Server/Program.cs | 25 ++++++++++++---------- MediaBrowser.Controller/IServerApplicationHost.cs | 5 ----- 4 files changed, 18 insertions(+), 21 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 789b8724c..8ea188724 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -240,13 +240,10 @@ namespace Emby.Server.Implementations public int HttpsPort { get; private set; } /// - /// Gets the content root for the webhost. If the webhost is not serving static web content, this will be null. + /// Gets the content root for the webhost. /// public string ContentRoot { get; private set; } - /// - public bool IsHostingContent => ContentRoot != null; - /// /// Gets the server configuration manager. /// diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 6b7e2805b..7c2b3cd5f 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -2,7 +2,9 @@ using System.Threading.Tasks; using Emby.Server.Implementations.Browser; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Extensions; using MediaBrowser.Controller.Plugins; +using Microsoft.Extensions.Configuration; namespace Emby.Server.Implementations.EntryPoints { @@ -36,7 +38,7 @@ namespace Emby.Server.Implementations.EntryPoints return Task.CompletedTask; } - if (!_appHost.IsHostingContent) + if (_appHost.Resolve().IsNoWebContent()) { BrowserLauncher.OpenSwaggerPage(_appHost); } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 7e03b0c9c..843eb9ea9 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -19,7 +19,7 @@ using Emby.Server.Implementations.Networking; using Jellyfin.Drawing.Skia; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Drawing; -using MediaBrowser.Model.Globalization; +using MediaBrowser.Controller.Extensions; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -177,7 +177,7 @@ namespace Jellyfin.Server ServiceCollection serviceCollection = new ServiceCollection(); await appHost.InitAsync(serviceCollection).ConfigureAwait(false); - var host = CreateWebHostBuilder(appHost, serviceCollection).Build(); + var host = CreateWebHostBuilder(appHost, serviceCollection, appConfig).Build(); // A bit hacky to re-use service provider since ASP.NET doesn't allow a custom service collection. appHost.ServiceProvider = host.Services; @@ -221,7 +221,7 @@ namespace Jellyfin.Server } } - private static IWebHostBuilder CreateWebHostBuilder(ApplicationHost appHost, IServiceCollection serviceCollection) + private static IWebHostBuilder CreateWebHostBuilder(ApplicationHost appHost, IServiceCollection serviceCollection, IConfiguration appConfig) { var webhostBuilder = new WebHostBuilder() .UseKestrel(options => @@ -268,9 +268,18 @@ namespace Jellyfin.Server }) .UseStartup(); - // Set the root directory for static content, if one exists - if (appHost.IsHostingContent) + if (!appConfig.IsNoWebContent()) { + // Fail startup if the web content does not exist + if (!Directory.Exists(appHost.ContentRoot) || !Directory.GetFiles(appHost.ContentRoot).Any()) + { + throw new InvalidOperationException( + "The server is expected to host web content, but the provided content directory is either " + + $"invalid or empty: {appHost.ContentRoot}. If you do not want to host web content with the " + + $"server, you may set the '{MediaBrowser.Controller.Extensions.ConfigurationExtensions.NoWebContentKey}' flag."); + } + + // Configure the web host to host the static web content webhostBuilder.UseContentRoot(appHost.ContentRoot); } @@ -404,12 +413,6 @@ namespace Jellyfin.Server } } - // Reset webDir if the directory does not exist, or is empty - if (!Directory.Exists(webDir) || !Directory.GetFiles(webDir).Any()) - { - webDir = null; - } - // logDir // IF --logdir // ELSE IF $JELLYFIN_LOG_DIR diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 134ed110b..25f0905eb 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -16,11 +16,6 @@ namespace MediaBrowser.Controller { event EventHandler HasUpdateAvailableChanged; - /// - /// Gets a value indicating whether the server is hosting the static web content from jellyfin-web. - /// - bool IsHostingContent { get; } - /// /// Gets the system info. /// -- cgit v1.2.3 From 547f248a620c2de61d72703590f9c5c4720ba6e2 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 15 Mar 2020 12:59:34 +0100 Subject: Update XML documentation for WebPath --- Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs index be2d198ef..8bcd08745 100644 --- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs +++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs @@ -1,11 +1,13 @@ using System; using System.IO; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Extensions; +using Microsoft.Extensions.Configuration; namespace Emby.Server.Implementations.AppBase { /// - /// Provides a base class to hold common application paths used by both the Ui and Server. + /// Provides a base class to hold common application paths used by both the UI and Server. /// This can be subclassed to add application-specific paths. /// public abstract class BaseApplicationPaths : IApplicationPaths @@ -40,7 +42,10 @@ namespace Emby.Server.Implementations.AppBase /// /// Gets the path to the web UI resources folder. /// - /// The web UI resources path, or null if the server is not hosting any web content. + /// The web UI resources path. + /// + /// This value is not relevant if is true. + /// public string WebPath { get; } /// -- cgit v1.2.3 From 4102e3afd0a9df29faea598769db2212a00d64ce Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 15 Mar 2020 13:00:14 +0100 Subject: Rename IsNoWebContent to NoWebContent --- Emby.Server.Implementations/EntryPoints/StartupWizard.cs | 2 +- Jellyfin.Server/Program.cs | 3 ++- MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 7c2b3cd5f..bc6b8c956 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -38,7 +38,7 @@ namespace Emby.Server.Implementations.EntryPoints return Task.CompletedTask; } - if (_appHost.Resolve().IsNoWebContent()) + if (_appHost.Resolve().NoWebContent()) { BrowserLauncher.OpenSwaggerPage(_appHost); } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 9450fee70..6412db751 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -287,7 +287,8 @@ namespace Jellyfin.Server }) .UseStartup(); - if (!startupConfig.IsNoWebContent()) + // Set up static content hosting unless it has been disabled via config + if (!startupConfig.NoWebContent()) { // Fail startup if the web content does not exist if (!Directory.Exists(appHost.ContentRoot) || !Directory.GetFiles(appHost.ContentRoot).Any()) diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs index 1a9ac09ee..e802eeed2 100644 --- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs @@ -30,7 +30,7 @@ namespace MediaBrowser.Controller.Extensions /// The configuration to retrieve the value from. /// The parsed config value. /// The config value is not a valid bool string. See . - public static bool IsNoWebContent(this IConfiguration configuration) + public static bool NoWebContent(this IConfiguration configuration) => configuration.GetValue(NoWebContentKey); /// -- cgit v1.2.3 From a9c1ff91193d8f645225ee9f7001370fe304ae8d Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 15 Mar 2020 13:00:34 +0100 Subject: Remove unnecessary method in BrowserLauncher --- Emby.Server.Implementations/Browser/BrowserLauncher.cs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs index b17c2b270..752650ae1 100644 --- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs +++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs @@ -8,25 +8,14 @@ namespace Emby.Server.Implementations.Browser /// public static class BrowserLauncher { - /// - /// Opens the dashboard page. - /// - /// The page. - /// The app host. - private static void OpenDashboardPage(string page, IServerApplicationHost appHost) - { - var url = appHost.GetLocalApiUrl("localhost") + "/web/" + page; - - OpenUrl(appHost, url); - } - /// /// Opens the web client. /// /// The app host. public static void OpenWebApp(IServerApplicationHost appHost) { - OpenDashboardPage("index.html", appHost); + var url = appHost.GetLocalApiUrl("localhost") + "/web/index.html"; + OpenUrl(appHost, url); } /// -- cgit v1.2.3 From a67e32f8ecd46dfe2193ab3c81160bc830cd9349 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 15 Mar 2020 13:14:57 +0100 Subject: Clean up and document BrowserLauncher correctly --- .../Browser/BrowserLauncher.cs | 28 ++++++++++------------ MediaBrowser.Controller/IServerApplicationHost.cs | 5 ++++ 2 files changed, 18 insertions(+), 15 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs index 752650ae1..96096e142 100644 --- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs +++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs @@ -1,21 +1,21 @@ using System; using MediaBrowser.Controller; +using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Browser { /// - /// Class BrowserLauncher. + /// Assists in opening application URLs in an external browser. /// public static class BrowserLauncher { /// - /// Opens the web client. + /// Opens the home page of the web client. /// /// The app host. public static void OpenWebApp(IServerApplicationHost appHost) { - var url = appHost.GetLocalApiUrl("localhost") + "/web/index.html"; - OpenUrl(appHost, url); + TryOpenUrl(appHost, "/web/index.html"); } /// @@ -24,27 +24,25 @@ namespace Emby.Server.Implementations.Browser /// The app host. public static void OpenSwaggerPage(IServerApplicationHost appHost) { - var url = appHost.GetLocalApiUrl("localhost") + "/swagger/index.html"; - OpenUrl(appHost, url); + TryOpenUrl(appHost, "/swagger/index.html"); } /// - /// Opens the URL. + /// Opens the specified URL in an external browser window. Any exceptions will be logged, but ignored. /// - /// The application host instance. + /// The application host. /// The URL. - private static void OpenUrl(IServerApplicationHost appHost, string url) + private static void TryOpenUrl(IServerApplicationHost appHost, string url) { try { - appHost.LaunchUrl(url); + string baseUrl = appHost.GetLocalApiUrl("localhost"); + appHost.LaunchUrl(baseUrl + url); } - catch (NotSupportedException) - { - - } - catch (Exception) + catch (Exception ex) { + var logger = appHost.Resolve(); + logger?.LogError(ex, "Failed to open browser window with URL {URL}", url); } } } diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 25f0905eb..608ffc61c 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -82,6 +82,11 @@ namespace MediaBrowser.Controller /// The local API URL. string GetLocalApiUrl(IPAddress address); + /// + /// Open a URL in an external browser window. + /// + /// The URL to open. + /// is false. void LaunchUrl(string url); void EnableLoopback(string appName); -- cgit v1.2.3 From 6fbdf0d6a20d8bf230cbf2ba002612b49fa45b76 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 15 Mar 2020 15:23:50 +0100 Subject: Construct ApplicationHost with DI framework instead of manually --- Emby.Server.Implementations/ApplicationHost.cs | 32 +++++++++------------- .../HttpServer/HttpListenerHost.cs | 5 +++- Jellyfin.Server/Program.cs | 3 +- 3 files changed, 19 insertions(+), 21 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 3d79cae1e..7262268a9 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -613,7 +613,7 @@ namespace Emby.Server.Implementations DiscoverTypes(); - await RegisterResources(serviceCollection, startupConfig).ConfigureAwait(false); + await RegisterServices(serviceCollection, startupConfig).ConfigureAwait(false); ContentRoot = ServerConfigurationManager.Configuration.DashboardSourcePath; if (string.IsNullOrEmpty(ContentRoot)) @@ -650,9 +650,9 @@ namespace Emby.Server.Implementations } /// - /// Registers resources that classes will depend on + /// Registers services/resources with the service collection that will be available via DI. /// - protected async Task RegisterResources(IServiceCollection serviceCollection, IConfiguration startupConfig) + protected async Task RegisterServices(IServiceCollection serviceCollection, IConfiguration startupConfig) { serviceCollection.AddMemoryCache(); @@ -770,20 +770,8 @@ namespace Emby.Server.Implementations CertificateInfo = GetCertificateInfo(true); Certificate = GetCertificate(CertificateInfo); - HttpServer = new HttpListenerHost( - this, - LoggerFactory.CreateLogger(), - ServerConfigurationManager, - startupConfig, - NetworkManager, - JsonSerializer, - XmlSerializer, - CreateHttpListener()) - { - GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading") - }; - - serviceCollection.AddSingleton(HttpServer); + serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); ImageProcessor = new ImageProcessor(LoggerFactory.CreateLogger(), ServerConfigurationManager.ApplicationPaths, FileSystemManager, ImageEncoder, () => LibraryManager, () => MediaEncoder); serviceCollection.AddSingleton(ImageProcessor); @@ -891,6 +879,14 @@ namespace Emby.Server.Implementations ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; } + /// + /// Create services registered with the service container that need to be initialized at application startup. + /// + public void InitializeServices() + { + HttpServer = Resolve(); + } + public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths) { // Distinct these to prevent users from reporting problems that aren't actually problems @@ -1196,8 +1192,6 @@ namespace Emby.Server.Implementations }); } - protected IHttpListener CreateHttpListener() => new WebSocketSharpListener(LoggerFactory.CreateLogger()); - private CertificateInfo GetCertificateInfo(bool generateCertificate) { // Custom cert diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 546a59517..7633eec4e 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -18,6 +18,7 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Events; +using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Services; using Microsoft.AspNetCore.Http; @@ -59,7 +60,8 @@ namespace Emby.Server.Implementations.HttpServer INetworkManager networkManager, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer, - IHttpListener socketListener) + IHttpListener socketListener, + ILocalizationManager localizationManager) { _appHost = applicationHost; _logger = logger; @@ -76,6 +78,7 @@ namespace Emby.Server.Implementations.HttpServer Instance = this; ResponseFilters = Array.Empty>(); + GlobalResponse = localizationManager.GetLocalizedString("StartupEmbyServerIsLoading"); } public event EventHandler> WebSocketConnected; diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index c839867f1..cb886b8ce 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -191,8 +191,9 @@ namespace Jellyfin.Server var webHost = CreateWebHostBuilder(appHost, serviceCollection, startupConfig, appPaths).Build(); - // A bit hacky to re-use service provider since ASP.NET doesn't allow a custom service collection. + // Re-use the web host service provider in the app host since ASP.NET doesn't allow a custom service collection. appHost.ServiceProvider = webHost.Services; + appHost.InitializeServices(); appHost.FindParts(); Migrations.MigrationRunner.Run(appHost, _loggerFactory); -- cgit v1.2.3 From 05ab61200a181ff39034a5c3ba30a4ee2672971d Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 15 Mar 2020 17:42:57 +0100 Subject: Do not call UseContentRoot() on the web host builder This call has nothing to do with static web content and should not have ever been called with the web content path: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/?view=aspnetcore-3.1&tabs=windows#content-root Since this call is removed, the ContentRoot property is also removed from ApplicationHost as it is no longer needed. Finally, move validation of the static content path to the DashboardService where it is actually used. --- .../AppBase/BaseApplicationPaths.cs | 10 +--------- Emby.Server.Implementations/ApplicationHost.cs | 11 ----------- Jellyfin.Server/Program.cs | 20 +------------------- .../Configuration/IApplicationPaths.cs | 9 +++++++-- MediaBrowser.WebDashboard/Api/DashboardService.cs | 11 +++++++++++ 5 files changed, 20 insertions(+), 41 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs index 8bcd08745..bc4781743 100644 --- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs +++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs @@ -1,8 +1,6 @@ using System; using System.IO; using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Extensions; -using Microsoft.Extensions.Configuration; namespace Emby.Server.Implementations.AppBase { @@ -39,13 +37,7 @@ namespace Emby.Server.Implementations.AppBase /// The program data path. public string ProgramDataPath { get; } - /// - /// Gets the path to the web UI resources folder. - /// - /// The web UI resources path. - /// - /// This value is not relevant if is true. - /// + /// public string WebPath { get; } /// diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 7262268a9..52c517627 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -236,11 +236,6 @@ namespace Emby.Server.Implementations /// public int HttpsPort { get; private set; } - /// - /// Gets the content root for the webhost. - /// - public string ContentRoot { get; private set; } - /// /// Gets the server configuration manager. /// @@ -614,12 +609,6 @@ namespace Emby.Server.Implementations DiscoverTypes(); await RegisterServices(serviceCollection, startupConfig).ConfigureAwait(false); - - ContentRoot = ServerConfigurationManager.Configuration.DashboardSourcePath; - if (string.IsNullOrEmpty(ContentRoot)) - { - ContentRoot = ServerConfigurationManager.ApplicationPaths.WebPath; - } } public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func next) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index bfb2fc6b5..67251eb24 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -243,7 +243,7 @@ namespace Jellyfin.Server IConfiguration startupConfig, IApplicationPaths appPaths) { - var webhostBuilder = new WebHostBuilder() + return new WebHostBuilder() .UseKestrel(options => { var addresses = appHost.ServerConfigurationManager @@ -289,24 +289,6 @@ namespace Jellyfin.Server services.TryAdd(serviceCollection); }) .UseStartup(); - - // Set up static content hosting unless it has been disabled via config - if (!startupConfig.NoWebContent()) - { - // Fail startup if the web content does not exist - if (!Directory.Exists(appHost.ContentRoot) || !Directory.GetFiles(appHost.ContentRoot).Any()) - { - throw new InvalidOperationException( - "The server is expected to host web content, but the provided content directory is either " + - $"invalid or empty: {appHost.ContentRoot}. If you do not want to host web content with the " + - $"server, you may set the '{MediaBrowser.Controller.Extensions.ConfigurationExtensions.NoWebContentKey}' flag."); - } - - // Configure the web host to host the static web content - webhostBuilder.UseContentRoot(appHost.ContentRoot); - } - - return webhostBuilder; } /// diff --git a/MediaBrowser.Common/Configuration/IApplicationPaths.cs b/MediaBrowser.Common/Configuration/IApplicationPaths.cs index 5bdea7d8b..870b90796 100644 --- a/MediaBrowser.Common/Configuration/IApplicationPaths.cs +++ b/MediaBrowser.Common/Configuration/IApplicationPaths.cs @@ -1,3 +1,5 @@ +using MediaBrowser.Model.Configuration; + namespace MediaBrowser.Common.Configuration { /// @@ -12,9 +14,12 @@ namespace MediaBrowser.Common.Configuration string ProgramDataPath { get; } /// - /// Gets the path to the web UI resources folder + /// Gets the path to the web UI resources folder. /// - /// The web UI resources path. + /// + /// This value is not relevant if the server is configured to not host any static web content. Additionally, + /// the value for takes precedence over this one. + /// string WebPath { get; } /// diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 11901c25f..0114f5d60 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -136,6 +136,17 @@ namespace MediaBrowser.WebDashboard.Api _resultFactory = resultFactory; _resourceFileManager = resourceFileManager; _appConfig = appConfig; + + // Validate web content path + string webContentPath = DashboardUIPath; + bool webContentPathValid = appConfig.NoWebContent() || (Directory.Exists(webContentPath) && Directory.GetFiles(webContentPath).Any()); + if (!webContentPathValid) + { + throw new InvalidOperationException( + "The server is expected to host web content, but the provided content directory is either " + + $"invalid or empty: {webContentPath}. If you do not want to host web content with the server, " + + $"you may set the '{Controller.Extensions.ConfigurationExtensions.NoWebContentKey}' flag."); + } } /// -- cgit v1.2.3 From 1a63c3f3644f8144ac7761724476891f4dc1d2cd Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 20 Mar 2020 13:13:20 +0100 Subject: Inject IConfiguration instead of resolving manually --- Emby.Server.Implementations/EntryPoints/StartupWizard.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index bc6b8c956..9a41396ce 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -13,10 +13,8 @@ namespace Emby.Server.Implementations.EntryPoints /// public sealed class StartupWizard : IServerEntryPoint { - /// - /// The app host. - /// private readonly IServerApplicationHost _appHost; + private readonly IConfiguration _appConfig; private readonly IServerConfigurationManager _config; /// @@ -24,9 +22,10 @@ namespace Emby.Server.Implementations.EntryPoints /// /// The application host. /// The configuration manager. - public StartupWizard(IServerApplicationHost appHost, IServerConfigurationManager config) + public StartupWizard(IServerApplicationHost appHost, IConfiguration appConfig, IServerConfigurationManager config) { _appHost = appHost; + _appConfig = appConfig; _config = config; } @@ -38,7 +37,7 @@ namespace Emby.Server.Implementations.EntryPoints return Task.CompletedTask; } - if (_appHost.Resolve().NoWebContent()) + if (_appConfig.NoWebContent()) { BrowserLauncher.OpenSwaggerPage(_appHost); } -- cgit v1.2.3 From aa546dd36abb688cb3a5d10e589521ebf79ef610 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 21 Mar 2020 18:25:09 +0100 Subject: Rename command line option to --nowebclient and config setting to HostWebClient --- .../ConfigurationOptions.cs | 2 +- .../EntryPoints/StartupWizard.cs | 2 +- Jellyfin.Server/Program.cs | 4 ++-- Jellyfin.Server/Properties/launchSettings.json | 6 ++--- Jellyfin.Server/StartupOptions.cs | 10 ++++---- .../Extensions/ConfigurationExtensions.cs | 8 +++---- MediaBrowser.WebDashboard/Api/DashboardService.cs | 27 ++++++++++++---------- 7 files changed, 31 insertions(+), 28 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index 814d4b8b5..4574a64fd 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -15,7 +15,7 @@ namespace Emby.Server.Implementations /// public static Dictionary DefaultConfiguration => new Dictionary { - { NoWebContentKey, bool.FalseString }, + { HostWebClientKey, bool.TrueString }, { HttpListenerHost.DefaultRedirectKey, "web/index.html" }, { FfmpegProbeSizeKey, "1G" }, { FfmpegAnalyzeDurationKey, "200M" }, diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 9a41396ce..8e9771931 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -37,7 +37,7 @@ namespace Emby.Server.Implementations.EntryPoints return Task.CompletedTask; } - if (_appConfig.NoWebContent()) + if (!_appConfig.HostWebClient()) { BrowserLauncher.OpenSwaggerPage(_appHost); } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 67251eb24..d9ca14136 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -490,9 +490,9 @@ namespace Jellyfin.Server IApplicationPaths appPaths, IConfiguration? startupConfig = null) { - // Use the swagger API page as the default redirect path if not hosting the jellyfin-web content + // Use the swagger API page as the default redirect path if not hosting the web client var inMemoryDefaultConfig = ConfigurationOptions.DefaultConfiguration; - if (startupConfig != null && startupConfig.NoWebContent()) + if (startupConfig != null && !startupConfig.HostWebClient()) { inMemoryDefaultConfig[HttpListenerHost.DefaultRedirectKey] = "swagger/index.html"; } diff --git a/Jellyfin.Server/Properties/launchSettings.json b/Jellyfin.Server/Properties/launchSettings.json index d68a611c1..53d9fe165 100644 --- a/Jellyfin.Server/Properties/launchSettings.json +++ b/Jellyfin.Server/Properties/launchSettings.json @@ -3,9 +3,9 @@ "Jellyfin.Server": { "commandName": "Project" }, - "Jellyfin.Server (nowebcontent)": { + "Jellyfin.Server (nowebclient)": { "commandName": "Project", - "commandLineArgs": "--nowebcontent" + "commandLineArgs": "--nowebclient" } } -} \ No newline at end of file +} diff --git a/Jellyfin.Server/StartupOptions.cs b/Jellyfin.Server/StartupOptions.cs index 0abc0fd91..c93577d3e 100644 --- a/Jellyfin.Server/StartupOptions.cs +++ b/Jellyfin.Server/StartupOptions.cs @@ -19,10 +19,10 @@ namespace Jellyfin.Server public string? DataDir { get; set; } /// - /// Gets or sets a value indicating whether the server should not host static web content. + /// Gets or sets a value indicating whether the server should not host the web client. /// - [Option(ConfigurationExtensions.NoWebContentKey, Required = false, HelpText = "Indicates that the web server should not host any static web content.")] - public bool NoWebContent { get; set; } + [Option("nowebclient", Required = false, HelpText = "Indicates that the web server should not host the web client.")] + public bool NoWebClient { get; set; } /// /// Gets or sets the path to the web directory. @@ -84,9 +84,9 @@ namespace Jellyfin.Server { var config = new Dictionary(); - if (NoWebContent) + if (NoWebClient) { - config.Add(ConfigurationExtensions.NoWebContentKey, bool.TrueString); + config.Add(ConfigurationExtensions.HostWebClientKey, bool.FalseString); } return config; diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs index 900cc6cb5..c95149984 100644 --- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs @@ -9,9 +9,9 @@ namespace MediaBrowser.Controller.Extensions public static class ConfigurationExtensions { /// - /// The key for a setting that indicates whether the application should host static web content. + /// The key for a setting that indicates whether the application should host web client content. /// - public const string NoWebContentKey = "nowebcontent"; + public const string HostWebClientKey = "hostwebclient"; /// /// The key for the FFmpeg probe size option. @@ -34,8 +34,8 @@ namespace MediaBrowser.Controller.Extensions /// The configuration to retrieve the value from. /// The parsed config value. /// The config value is not a valid bool string. See . - public static bool NoWebContent(this IConfiguration configuration) - => configuration.GetValue(NoWebContentKey); + public static bool HostWebClient(this IConfiguration configuration) + => configuration.GetValue(HostWebClientKey); /// /// Gets the FFmpeg probe size from the . diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 3e47ce682..a71d685fb 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -136,15 +136,18 @@ namespace MediaBrowser.WebDashboard.Api _fileSystem = fileSystem; _resultFactory = resultFactory; - // Validate web content path - string webContentPath = DashboardUIPath; - bool webContentPathValid = appConfig.NoWebContent() || (Directory.Exists(webContentPath) && Directory.GetFiles(webContentPath).Any()); - if (!webContentPathValid) + // If hosting the web client, validate the client content path + if (appConfig.HostWebClient()) { - throw new InvalidOperationException( - "The server is expected to host web content, but the provided content directory is either " + - $"invalid or empty: {webContentPath}. If you do not want to host web content with the server, " + - $"you may set the '{Controller.Extensions.ConfigurationExtensions.NoWebContentKey}' flag."); + string webContentPath = DashboardUIPath; + if (!Directory.Exists(webContentPath) || !Directory.GetFiles(webContentPath).Any()) + { + throw new InvalidOperationException( + "The server is expected to host the web client, but the provided content directory is either " + + $"invalid or empty: {webContentPath}. If you do not want to host the web client with the " + + "server, you may set the '--nowebclient' command line flag, or set" + + $"'{Controller.Extensions.ConfigurationExtensions.HostWebClientKey}=false' in your config settings."); + } } } @@ -156,13 +159,13 @@ namespace MediaBrowser.WebDashboard.Api /// /// Gets the path of the directory containing the static web interface content, or null if the server is not - /// hosting the static web content. + /// hosting the web client. /// public string DashboardUIPath { get { - if (_appConfig.NoWebContent()) + if (!_appConfig.HostWebClient()) { return null; } @@ -329,7 +332,7 @@ namespace MediaBrowser.WebDashboard.Api /// System.Object. public async Task Get(GetDashboardResource request) { - if (_appConfig.NoWebContent() || DashboardUIPath == null) + if (!_appConfig.HostWebClient() || DashboardUIPath == null) { throw new ResourceNotFoundException(); } @@ -405,7 +408,7 @@ namespace MediaBrowser.WebDashboard.Api public async Task Get(GetDashboardPackage request) { - if (_appConfig.NoWebContent() || DashboardUIPath == null) + if (!_appConfig.HostWebClient() || DashboardUIPath == null) { throw new ResourceNotFoundException(); } -- cgit v1.2.3