diff options
Diffstat (limited to 'Jellyfin.Server/Extensions')
3 files changed, 109 insertions, 66 deletions
diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index 6066893de..a56baba33 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -69,16 +69,6 @@ namespace Jellyfin.Server.Extensions } /// <summary> - /// Adds LAN based access filtering to the application pipeline. - /// </summary> - /// <param name="appBuilder">The application builder.</param> - /// <returns>The updated application builder.</returns> - public static IApplicationBuilder UseLanFiltering(this IApplicationBuilder appBuilder) - { - return appBuilder.UseMiddleware<LanFilteringMiddleware>(); - } - - /// <summary> /// Enables url decoding before binding to the application pipeline. /// </summary> /// <param name="appBuilder">The <see cref="IApplicationBuilder"/>.</param> diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index 597643ed1..08c1a5065 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -19,6 +19,7 @@ using Jellyfin.Api.Controllers; using Jellyfin.Api.Formatters; using Jellyfin.Api.ModelBinders; using Jellyfin.Data.Enums; +using Jellyfin.Database.Implementations.Enums; using Jellyfin.Extensions.Json; using Jellyfin.Server.Configuration; using Jellyfin.Server.Filters; @@ -115,26 +116,7 @@ namespace Jellyfin.Server.Extensions .AddTransient<ICorsPolicyProvider, CorsPolicyProvider>() .Configure<ForwardedHeadersOptions>(options => { - // https://github.com/dotnet/aspnetcore/blob/master/src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs - // Enable debug logging on Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware to help investigate issues. - - options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost; - - if (config.KnownProxies.Length == 0) - { - options.KnownNetworks.Clear(); - options.KnownProxies.Clear(); - } - else - { - AddProxyAddresses(config, config.KnownProxies, options); - } - - // Only set forward limit if we have some known proxies or some known networks. - if (options.KnownProxies.Count != 0 || options.KnownNetworks.Count != 0) - { - options.ForwardLimit = null; - } + ConfigureForwardHeaders(config, options); }) .AddMvc(opts => { @@ -182,6 +164,30 @@ namespace Jellyfin.Server.Extensions return mvcBuilder.AddControllersAsServices(); } + internal static void ConfigureForwardHeaders(NetworkConfiguration config, ForwardedHeadersOptions options) + { + // https://github.com/dotnet/aspnetcore/blob/master/src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs + // Enable debug logging on Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware to help investigate issues. + + if (config.KnownProxies.Length == 0) + { + options.ForwardedHeaders = ForwardedHeaders.None; + options.KnownNetworks.Clear(); + options.KnownProxies.Clear(); + } + else + { + options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost; + AddProxyAddresses(config, config.KnownProxies, options); + } + + // Only set forward limit if we have some known proxies or some known networks. + if (options.KnownProxies.Count != 0 || options.KnownNetworks.Count != 0) + { + options.ForwardLimit = null; + } + } + /// <summary> /// Adds Swagger to the service collection. /// </summary> @@ -214,7 +220,7 @@ namespace Jellyfin.Server.Extensions }); // Add all xml doc files to swagger generator. - var xmlFiles = Directory.GetFiles( + var xmlFiles = Directory.EnumerateFiles( AppContext.BaseDirectory, "*.xml", SearchOption.TopDirectoryOnly); @@ -247,6 +253,7 @@ namespace Jellyfin.Server.Extensions c.AddSwaggerTypeMappings(); c.SchemaFilter<IgnoreEnumSchemaFilter>(); + c.OperationFilter<RetryOnTemporarilyUnavailableFilter>(); c.OperationFilter<SecurityRequirementsOperationFilter>(); c.OperationFilter<FileResponseFilter>(); c.OperationFilter<FileRequestFilter>(); diff --git a/Jellyfin.Server/Extensions/WebHostBuilderExtensions.cs b/Jellyfin.Server/Extensions/WebHostBuilderExtensions.cs index 6b95770ed..be9cf0f15 100644 --- a/Jellyfin.Server/Extensions/WebHostBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/WebHostBuilderExtensions.cs @@ -1,10 +1,14 @@ using System; +using System.Collections.Generic; using System.IO; using System.Net; +using System.Security.Cryptography.X509Certificates; using Jellyfin.Server.Helpers; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Net; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -35,56 +39,98 @@ public static class WebHostBuilderExtensions return builder .UseKestrel((builderContext, options) => { - var addresses = appHost.NetManager.GetAllBindInterfaces(false); + SetupJellyfinWebServer( + appHost.NetManager.GetAllBindInterfaces(false), + appHost.HttpPort, + appHost.ListenWithHttps ? appHost.HttpsPort : null, + appHost.Certificate, + startupConfig, + appPaths, + logger, + builderContext, + options); + }) + .UseStartup(context => new Startup(appHost, context.Configuration)); + } - bool flagged = false; - foreach (var netAdd in addresses) + /// <summary> + /// Configures a Kestrel type webServer to bind to the specific arguments. + /// </summary> + /// <param name="addresses">The IP addresses that should be listend to.</param> + /// <param name="httpPort">The http port.</param> + /// <param name="httpsPort">If set the https port. If set you must also set the certificate.</param> + /// <param name="certificate">The certificate used for https port.</param> + /// <param name="startupConfig">The startup config.</param> + /// <param name="appPaths">The app paths.</param> + /// <param name="logger">A logger.</param> + /// <param name="builderContext">The kestrel build pipeline context.</param> + /// <param name="options">The kestrel server options.</param> + /// <exception cref="InvalidOperationException">Will be thrown when a https port is set but no or an invalid certificate is provided.</exception> + public static void SetupJellyfinWebServer( + IReadOnlyList<IPData> addresses, + int httpPort, + int? httpsPort, + X509Certificate2? certificate, + IConfiguration startupConfig, + IApplicationPaths appPaths, + ILogger logger, + WebHostBuilderContext builderContext, + KestrelServerOptions options) + { + bool flagged = false; + foreach (var netAdd in addresses) + { + var address = netAdd.Address; + logger.LogInformation("Kestrel is listening on {Address}", address.Equals(IPAddress.IPv6Any) ? "all interfaces" : address); + options.Listen(netAdd.Address, httpPort); + if (httpsPort.HasValue) + { + if (builderContext.HostingEnvironment.IsDevelopment()) { - var address = netAdd.Address; - logger.LogInformation("Kestrel is listening on {Address}", address.Equals(IPAddress.IPv6Any) ? "all interfaces" : address); - options.Listen(netAdd.Address, appHost.HttpPort); - if (appHost.ListenWithHttps) + try { options.Listen( address, - appHost.HttpsPort, - listenOptions => listenOptions.UseHttps(appHost.Certificate)); + httpsPort.Value, + listenOptions => listenOptions.UseHttps()); } - else if (builderContext.HostingEnvironment.IsDevelopment()) + catch (InvalidOperationException) { - try + if (!flagged) { - options.Listen( - address, - appHost.HttpsPort, - listenOptions => listenOptions.UseHttps()); - } - catch (InvalidOperationException) - { - if (!flagged) - { - logger.LogWarning("Failed to listen to HTTPS using the ASP.NET Core HTTPS development certificate. Please ensure it has been installed and set as trusted"); - flagged = true; - } + logger.LogWarning("Failed to listen to HTTPS using the ASP.NET Core HTTPS development certificate. Please ensure it has been installed and set as trusted"); + flagged = true; } } } - - // Bind to unix socket (only on unix systems) - if (startupConfig.UseUnixSocket() && Environment.OSVersion.Platform == PlatformID.Unix) + else { - var socketPath = StartupHelpers.GetUnixSocketPath(startupConfig, appPaths); - - // Workaround for https://github.com/aspnet/AspNetCore/issues/14134 - if (File.Exists(socketPath)) + if (certificate is null) { - File.Delete(socketPath); + throw new InvalidOperationException("Cannot run jellyfin with https without setting a valid certificate."); } - options.ListenUnixSocket(socketPath); - logger.LogInformation("Kestrel listening to unix socket {SocketPath}", socketPath); + options.Listen( + address, + httpsPort.Value, + listenOptions => listenOptions.UseHttps(certificate)); } - }) - .UseStartup(_ => new Startup(appHost)); + } + } + + // Bind to unix socket (only on unix systems) + if (startupConfig.UseUnixSocket() && Environment.OSVersion.Platform == PlatformID.Unix) + { + var socketPath = StartupHelpers.GetUnixSocketPath(startupConfig, appPaths); + + // Workaround for https://github.com/aspnet/AspNetCore/issues/14134 + if (File.Exists(socketPath)) + { + File.Delete(socketPath); + } + + options.ListenUnixSocket(socketPath); + logger.LogInformation("Kestrel listening to unix socket {SocketPath}", socketPath); + } } } |
