diff options
| author | Joshua M. Boniface <joshua@boniface.me> | 2019-08-19 14:57:48 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-08-19 14:57:48 -0400 |
| commit | d95c04787cc4486f4ea5caaef20f6ac407a3f84a (patch) | |
| tree | 7e3193614c5a132ae63034c2bb7e07956a5670e6 /Jellyfin.Server/Program.cs | |
| parent | 3ba709fcc32d7255a2cb2466dde8c2479130a2bc (diff) | |
| parent | d99278da1dcac4d3c60739e864597aa01f916636 (diff) | |
Merge branch 'master' into h265
Diffstat (limited to 'Jellyfin.Server/Program.cs')
| -rw-r--r-- | Jellyfin.Server/Program.cs | 141 |
1 files changed, 94 insertions, 47 deletions
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index fab584bef..594441af0 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -18,43 +18,53 @@ using Jellyfin.Drawing.Skia; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.Globalization; -using MediaBrowser.Model.IO; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Serilog; using Serilog.AspNetCore; +using SQLitePCL; using ILogger = Microsoft.Extensions.Logging.ILogger; namespace Jellyfin.Server { + /// <summary> + /// Class containing the entry point of the application. + /// </summary> public static class Program { private static readonly CancellationTokenSource _tokenSource = new CancellationTokenSource(); private static readonly ILoggerFactory _loggerFactory = new SerilogLoggerFactory(); private static ILogger _logger; private static bool _restartOnShutdown; - private static IConfiguration appConfig; - public static async Task Main(string[] args) + /// <summary> + /// The entry point of the application. + /// </summary> + /// <param name="args">The command line arguments passed.</param> + /// <returns><see cref="Task" />.</returns> + public static Task Main(string[] args) { // For backwards compatibility. // Modify any input arguments now which start with single-hyphen to POSIX standard // double-hyphen to allow parsing by CommandLineParser package. - const string pattern = @"^(-[^-\s]{2})"; // Match -xx, not -x, not --xx, not xx - const string substitution = @"-$1"; // Prepend with additional single-hyphen - var regex = new Regex(pattern); + const string Pattern = @"^(-[^-\s]{2})"; // Match -xx, not -x, not --xx, not xx + const string Substitution = @"-$1"; // Prepend with additional single-hyphen + var regex = new Regex(Pattern); for (var i = 0; i < args.Length; i++) { - args[i] = regex.Replace(args[i], substitution); + args[i] = regex.Replace(args[i], Substitution); } // Parse the command line arguments and either start the app or exit indicating error - await Parser.Default.ParseArguments<StartupOptions>(args) - .MapResult(StartApp, _ => Task.CompletedTask).ConfigureAwait(false); + return Parser.Default.ParseArguments<StartupOptions>(args) + .MapResult(StartApp, _ => Task.CompletedTask); } - public static void Shutdown() + /// <summary> + /// Shuts down the application. + /// </summary> + internal static void Shutdown() { if (!_tokenSource.IsCancellationRequested) { @@ -62,7 +72,10 @@ namespace Jellyfin.Server } } - public static void Restart() + /// <summary> + /// Restarts the application. + /// </summary> + internal static void Restart() { _restartOnShutdown = true; @@ -76,7 +89,7 @@ namespace Jellyfin.Server // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); - appConfig = await CreateConfiguration(appPaths).ConfigureAwait(false); + IConfiguration appConfig = await CreateConfiguration(appPaths).ConfigureAwait(false); CreateLogger(appConfig, appPaths); @@ -116,41 +129,57 @@ namespace Jellyfin.Server ApplicationHost.LogEnvironmentInfo(_logger, appPaths); - SQLitePCL.Batteries_V2.Init(); - // Increase the max http request limit // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others. ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); + // Disable the "Expect: 100-Continue" header by default + // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c + ServicePointManager.Expect100Continue = false; + +// CA5359: Do Not Disable Certificate Validation +#pragma warning disable CA5359 + // Allow all https requests ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; }); +#pragma warning restore CA5359 - var fileSystem = new ManagedFileSystem(_loggerFactory, appPaths); + Batteries_V2.Init(); + if (raw.sqlite3_enable_shared_cache(1) != raw.SQLITE_OK) + { + _logger.LogWarning("Failed to enable shared cache for SQLite"); + } - using (var appHost = new CoreAppHost( + var appHost = new CoreAppHost( appPaths, _loggerFactory, options, - fileSystem, + new ManagedFileSystem(_loggerFactory.CreateLogger<ManagedFileSystem>(), appPaths), new NullImageEncoder(), - new NetworkManager(_loggerFactory), - appConfig)) + new NetworkManager(_loggerFactory.CreateLogger<NetworkManager>()), + appConfig); + try { await appHost.InitAsync(new ServiceCollection()).ConfigureAwait(false); - appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager); + appHost.ImageProcessor.ImageEncoder = GetImageEncoder(appPaths, appHost.LocalizationManager); await appHost.RunStartupTasksAsync().ConfigureAwait(false); - try - { - // Block main thread until shutdown - await Task.Delay(-1, _tokenSource.Token).ConfigureAwait(false); - } - catch (TaskCanceledException) - { - // Don't throw on cancellation - } + // Block main thread until shutdown + await Task.Delay(-1, _tokenSource.Token).ConfigureAwait(false); + } + catch (TaskCanceledException) + { + // Don't throw on cancellation + } + catch (Exception ex) + { + _logger.LogCritical(ex, "Error while starting server."); + } + finally + { + appHost?.Dispose(); } if (_restartOnShutdown) @@ -161,12 +190,13 @@ namespace Jellyfin.Server /// <summary> /// Create the data, config and log paths from the variety of inputs(command line args, - /// environment variables) or decide on what default to use. For Windows it's %AppPath% - /// for everything else the XDG approach is followed: - /// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + /// environment variables) or decide on what default to use. For Windows it's %AppPath% + /// for everything else the + /// <a href="https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG approach</a> + /// is followed. /// </summary> - /// <param name="options">StartupOptions</param> - /// <returns>ServerApplicationPaths</returns> + /// <param name="options">The <see cref="StartupOptions" /> for this instance.</param> + /// <returns><see cref="ServerApplicationPaths" />.</returns> private static ServerApplicationPaths CreateApplicationPaths(StartupOptions options) { // dataDir @@ -183,7 +213,9 @@ namespace Jellyfin.Server if (string.IsNullOrEmpty(dataDir)) { // LocalApplicationData follows the XDG spec on unix machines - dataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "jellyfin"); + dataDir = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + "jellyfin"); } } @@ -202,20 +234,26 @@ namespace Jellyfin.Server if (string.IsNullOrEmpty(configDir)) { - if (options.DataDir != null || Directory.Exists(Path.Combine(dataDir, "config")) || RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (options.DataDir != null + || Directory.Exists(Path.Combine(dataDir, "config")) + || RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Hang config folder off already set dataDir configDir = Path.Combine(dataDir, "config"); } else { - // $XDG_CONFIG_HOME defines the base directory relative to which user specific configuration files should be stored. + // $XDG_CONFIG_HOME defines the base directory relative to which + // user specific configuration files should be stored. configDir = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME"); - // If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME /.config should be used. + // If $XDG_CONFIG_HOME is either not set or empty, + // a default equal to $HOME /.config should be used. if (string.IsNullOrEmpty(configDir)) { - configDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".config"); + configDir = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + ".config"); } configDir = Path.Combine(configDir, "jellyfin"); @@ -243,13 +281,17 @@ namespace Jellyfin.Server } else { - // $XDG_CACHE_HOME defines the base directory relative to which user specific non-essential data files should be stored. + // $XDG_CACHE_HOME defines the base directory relative to which + // user specific non-essential data files should be stored. cacheDir = Environment.GetEnvironmentVariable("XDG_CACHE_HOME"); - // If $XDG_CACHE_HOME is either not set or empty, a default equal to $HOME/.cache should be used. + // If $XDG_CACHE_HOME is either not set or empty, + // a default equal to $HOME/.cache should be used. if (string.IsNullOrEmpty(cacheDir)) { - cacheDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".cache"); + cacheDir = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + ".cache"); } cacheDir = Path.Combine(cacheDir, "jellyfin"); @@ -358,17 +400,22 @@ namespace Jellyfin.Server } private static IImageEncoder GetImageEncoder( - IFileSystem fileSystem, IApplicationPaths appPaths, ILocalizationManager localizationManager) { try { - return new SkiaEncoder(_loggerFactory, appPaths, fileSystem, localizationManager); + // Test if the native lib is available + SkiaEncoder.TestSkia(); + + return new SkiaEncoder( + _loggerFactory.CreateLogger<SkiaEncoder>(), + appPaths, + localizationManager); } catch (Exception ex) { - _logger.LogInformation(ex, "Skia not available. Will fallback to NullIMageEncoder. {0}"); + _logger.LogWarning(ex, "Skia not available. Will fallback to NullIMageEncoder."); } return new NullImageEncoder(); @@ -382,7 +429,7 @@ namespace Jellyfin.Server if (string.IsNullOrWhiteSpace(module)) { - module = Environment.GetCommandLineArgs().First(); + module = Environment.GetCommandLineArgs()[0]; } string commandLineArgsString; @@ -394,7 +441,7 @@ namespace Jellyfin.Server else { commandLineArgsString = string.Join( - " ", + ' ', Environment.GetCommandLineArgs().Skip(1).Select(NormalizeCommandLineArgument)); } |
