Files
jellyfin-jellyfin-1/Jellyfin.Server/Startup.cs

237 lines
10 KiB
C#
Raw Normal View History

using System;
using System.Net;
using System.Net.Http;
2020-08-31 08:47:38 -06:00
using System.Net.Http.Headers;
2020-10-02 13:30:31 -06:00
using System.Net.Mime;
using System.Text;
using Emby.Server.Implementations.EntryPoints;
2023-01-13 21:37:37 -05:00
using Jellyfin.Api.Middleware;
using Jellyfin.LiveTv.Extensions;
using Jellyfin.LiveTv.Recordings;
using Jellyfin.MediaEncoding.Hls.Extensions;
using Jellyfin.Networking;
using Jellyfin.Networking.HappyEyeballs;
using Jellyfin.Server.Extensions;
using Jellyfin.Server.HealthChecks;
2020-09-03 13:44:49 -06:00
using Jellyfin.Server.Implementations;
using Jellyfin.Server.Implementations.Extensions;
using Jellyfin.Server.Infrastructure;
2020-08-19 06:31:45 -06:00
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Extensions;
2024-02-06 16:18:17 -05:00
using MediaBrowser.XbmcMetadata;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
2020-10-02 13:30:31 -06:00
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
2020-04-25 21:35:51 -04:00
using Prometheus;
namespace Jellyfin.Server
{
/// <summary>
/// Startup configuration for the Kestrel webhost.
/// </summary>
public class Startup
{
private readonly CoreAppHost _serverApplicationHost;
2023-01-11 22:07:41 -05:00
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IConfiguration _startupConfig;
/// <summary>
/// Initializes a new instance of the <see cref="Startup" /> class.
/// </summary>
2023-01-11 22:07:41 -05:00
/// <param name="appHost">The server application host.</param>
/// <param name="startupConfig">The server startupConfig.</param>
public Startup(CoreAppHost appHost, IConfiguration startupConfig)
{
2023-01-11 22:07:41 -05:00
_serverApplicationHost = appHost;
_serverConfigurationManager = appHost.ConfigurationManager;
_startupConfig = startupConfig;
}
/// <summary>
/// Configures the service collection for the webhost.
/// </summary>
/// <param name="services">The service collection.</param>
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.AddHttpContextAccessor();
2020-09-03 00:38:52 +02:00
services.AddHttpsRedirection(options =>
{
options.HttpsPort = _serverApplicationHost.HttpsPort;
});
// TODO remove once this is fixed upstream https://github.com/dotnet/aspnetcore/issues/34371
services.AddSingleton<IActionResultExecutor<PhysicalFileResult>, SymlinkFollowingPhysicalFileResultExecutor>();
2021-01-19 10:36:37 +00:00
services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies(), _serverConfigurationManager.GetNetworkConfiguration());
services.AddJellyfinDbContext(_startupConfig.GetSqliteSecondLevelCacheDisabled());
services.AddJellyfinApiSwagger();
// configure custom legacy authentication
services.AddCustomAuthentication();
services.AddJellyfinApiAuthorization();
2020-08-19 06:31:45 -06:00
var productHeader = new ProductInfoHeaderValue(
_serverApplicationHost.Name.Replace(' ', '-'),
_serverApplicationHost.ApplicationVersionString);
2020-11-19 07:35:34 -07:00
var acceptJsonHeader = new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json, 1.0);
var acceptXmlHeader = new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Xml, 0.9);
var acceptAnyHeader = new MediaTypeWithQualityHeaderValue("*/*", 0.8);
Func<IServiceProvider, HttpMessageHandler> eyeballsHttpClientHandlerDelegate = (_) => new SocketsHttpHandler()
{
AutomaticDecompression = DecompressionMethods.All,
RequestHeaderEncodingSelector = (_, _) => Encoding.UTF8,
ConnectCallback = HttpClientExtension.OnConnect
};
Func<IServiceProvider, HttpMessageHandler> defaultHttpClientHandlerDelegate = (_) => new SocketsHttpHandler()
{
AutomaticDecompression = DecompressionMethods.All,
RequestHeaderEncodingSelector = (_, _) => Encoding.UTF8
};
2023-01-11 22:07:41 -05:00
services.AddHttpClient(NamedClient.Default, c =>
2020-08-31 08:47:38 -06:00
{
2020-08-31 09:15:20 -06:00
c.DefaultRequestHeaders.UserAgent.Add(productHeader);
2020-11-18 18:20:31 -07:00
c.DefaultRequestHeaders.Accept.Add(acceptJsonHeader);
2020-11-19 07:35:34 -07:00
c.DefaultRequestHeaders.Accept.Add(acceptXmlHeader);
2020-11-18 18:20:31 -07:00
c.DefaultRequestHeaders.Accept.Add(acceptAnyHeader);
2020-08-31 08:47:38 -06:00
})
.ConfigurePrimaryHttpMessageHandler(eyeballsHttpClientHandlerDelegate);
2020-08-31 08:47:38 -06:00
services.AddHttpClient(NamedClient.MusicBrainz, c =>
{
2020-08-31 09:15:20 -06:00
c.DefaultRequestHeaders.UserAgent.Add(productHeader);
c.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue($"({_serverApplicationHost.ApplicationUserAgentAddress})"));
2020-12-01 09:57:13 -07:00
c.DefaultRequestHeaders.Accept.Add(acceptXmlHeader);
2020-11-18 18:20:31 -07:00
c.DefaultRequestHeaders.Accept.Add(acceptAnyHeader);
2020-08-31 08:47:38 -06:00
})
.ConfigurePrimaryHttpMessageHandler(eyeballsHttpClientHandlerDelegate);
services.AddHttpClient(NamedClient.DirectIp, c =>
{
c.DefaultRequestHeaders.UserAgent.Add(productHeader);
c.DefaultRequestHeaders.Accept.Add(acceptJsonHeader);
c.DefaultRequestHeaders.Accept.Add(acceptXmlHeader);
c.DefaultRequestHeaders.Accept.Add(acceptAnyHeader);
})
.ConfigurePrimaryHttpMessageHandler(defaultHttpClientHandlerDelegate);
2020-09-03 09:26:22 -06:00
services.AddHealthChecks()
2023-01-16 12:14:44 -05:00
.AddCheck<DbContextFactoryHealthCheck<JellyfinDbContext>>(nameof(JellyfinDbContext));
services.AddHlsPlaylistGenerator();
services.AddLiveTvServices();
services.AddHostedService<RecordingsHost>();
services.AddHostedService<AutoDiscoveryHost>();
services.AddHostedService<PortForwardingHost>();
2024-02-06 16:18:17 -05:00
services.AddHostedService<NfoUserDataSaver>();
services.AddHostedService<LibraryChangedNotifier>();
services.AddHostedService<UserDataChangeNotifier>();
services.AddHostedService<RecordingNotifier>();
}
/// <summary>
/// Configures the app builder for the webhost.
/// </summary>
/// <param name="app">The application builder.</param>
/// <param name="env">The webhost environment.</param>
/// <param name="appConfig">The application config.</param>
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
IConfiguration appConfig)
{
2020-09-07 19:10:14 -06:00
app.UseBaseUrlRedirection();
2020-09-03 17:11:12 -06:00
// Wrap rest of configuration so everything only listens on BaseUrl.
2020-12-01 21:16:36 +00:00
var config = _serverConfigurationManager.GetNetworkConfiguration();
app.Map(config.BaseUrl, mainApp =>
2020-09-03 17:11:12 -06:00
{
if (env.IsDevelopment())
{
mainApp.UseDeveloperExceptionPage();
}
2020-04-21 07:36:22 -06:00
mainApp.UseForwardedHeaders();
2020-09-03 17:11:12 -06:00
mainApp.UseMiddleware<ExceptionMiddleware>();
2020-09-03 17:11:12 -06:00
mainApp.UseMiddleware<ResponseTimeMiddleware>();
2020-09-03 17:11:12 -06:00
mainApp.UseWebSockets();
2020-09-03 17:11:12 -06:00
mainApp.UseResponseCompression();
2020-09-03 14:05:16 +02:00
2020-09-05 09:10:05 -06:00
mainApp.UseCors();
2020-12-01 21:16:36 +00:00
if (config.RequireHttps && _serverApplicationHost.ListenWithHttps)
{
2020-09-03 17:11:12 -06:00
mainApp.UseHttpsRedirection();
}
// This must be injected before any path related middleware.
mainApp.UsePathTrim();
2020-09-03 17:11:12 -06:00
if (appConfig.HostWebClient())
{
2020-10-02 13:30:31 -06:00
var extensionProvider = new FileExtensionContentTypeProvider();
2020-12-04 14:12:59 -07:00
// subtitles octopus requires .data, .mem files.
2020-10-02 13:30:31 -06:00
extensionProvider.Mappings.Add(".data", MediaTypeNames.Application.Octet);
2020-12-04 14:12:59 -07:00
extensionProvider.Mappings.Add(".mem", MediaTypeNames.Application.Octet);
mainApp.UseDefaultFiles(new DefaultFilesOptions
{
FileProvider = new PhysicalFileProvider(_serverConfigurationManager.ApplicationPaths.WebPath),
RequestPath = "/web"
});
2020-09-03 17:11:12 -06:00
mainApp.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(_serverConfigurationManager.ApplicationPaths.WebPath),
2020-10-02 13:30:31 -06:00
RequestPath = "/web",
ContentTypeProvider = extensionProvider
2020-09-03 17:11:12 -06:00
});
mainApp.UseRobotsRedirection();
2020-09-03 17:11:12 -06:00
}
mainApp.UseStaticFiles();
2020-09-03 17:11:12 -06:00
mainApp.UseAuthentication();
mainApp.UseJellyfinApiSwagger(_serverConfigurationManager);
2021-05-05 22:52:39 +01:00
mainApp.UseQueryStringDecoding();
2020-09-03 17:11:12 -06:00
mainApp.UseRouting();
mainApp.UseAuthorization();
2020-09-03 17:11:12 -06:00
mainApp.UseLanFiltering();
2023-02-17 19:27:36 +01:00
mainApp.UseIPBasedAccessValidation();
2020-09-03 17:11:12 -06:00
mainApp.UseWebSocketHandler();
mainApp.UseServerStartupMessage();
if (_serverConfigurationManager.Configuration.EnableMetrics)
{
2020-09-03 17:14:50 -06:00
// Must be registered after any middleware that could change HTTP response codes or the data will be bad
mainApp.UseHttpMetrics();
}
2020-09-03 17:14:50 -06:00
2020-09-03 17:11:12 -06:00
mainApp.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
if (_serverConfigurationManager.Configuration.EnableMetrics)
{
2023-01-11 22:09:14 -05:00
endpoints.MapMetrics();
2020-09-03 17:11:12 -06:00
}
endpoints.MapHealthChecks("/health");
});
});
}
}
}