jellyfin/Jellyfin.Server/Startup.cs

173 lines
6.6 KiB
C#
Raw Normal View History

using System;
using System.ComponentModel;
2020-08-31 10:47:38 -04:00
using System.Net.Http.Headers;
2020-10-02 15:30:31 -04:00
using System.Net.Mime;
using Jellyfin.Api.TypeConverters;
using Jellyfin.Server.Extensions;
2020-09-03 15:44:49 -04:00
using Jellyfin.Server.Implementations;
2020-04-23 23:24:40 -04:00
using Jellyfin.Server.Middleware;
2020-08-19 08:31:45 -04:00
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
2020-10-02 15:30:31 -04: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 IServerConfigurationManager _serverConfigurationManager;
private readonly IServerApplicationHost _serverApplicationHost;
/// <summary>
/// Initializes a new instance of the <see cref="Startup" /> class.
/// </summary>
/// <param name="serverConfigurationManager">The server configuration manager.</param>
/// <param name="serverApplicationHost">The server application host.</param>
public Startup(
IServerConfigurationManager serverConfigurationManager,
IServerApplicationHost serverApplicationHost)
{
_serverConfigurationManager = serverConfigurationManager;
_serverApplicationHost = serverApplicationHost;
}
/// <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-02 18:38:52 -04:00
services.AddHttpsRedirection(options =>
{
options.HttpsPort = _serverApplicationHost.HttpsPort;
});
services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies(), _serverConfigurationManager.Configuration.KnownProxies);
services.AddJellyfinApiSwagger();
// configure custom legacy authentication
services.AddCustomAuthentication();
services.AddJellyfinApiAuthorization();
2020-08-19 08:31:45 -04:00
var productHeader = new ProductInfoHeaderValue(
_serverApplicationHost.Name.Replace(' ', '-'),
_serverApplicationHost.ApplicationVersionString);
2020-08-19 08:31:45 -04:00
services
2020-08-31 10:47:38 -04:00
.AddHttpClient(NamedClient.Default, c =>
{
2020-08-31 11:15:20 -04:00
c.DefaultRequestHeaders.UserAgent.Add(productHeader);
2020-08-31 10:47:38 -04:00
})
.ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler());
services.AddHttpClient(NamedClient.MusicBrainz, c =>
{
2020-08-31 11:15:20 -04:00
c.DefaultRequestHeaders.UserAgent.Add(productHeader);
c.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue($"({_serverApplicationHost.ApplicationUserAgentAddress})"));
2020-08-31 10:47:38 -04:00
})
.ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler());
2020-09-03 11:26:22 -04:00
services.AddHealthChecks()
2020-09-03 15:44:49 -04:00
.AddDbContextCheck<JellyfinDb>();
}
/// <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 21:10:14 -04:00
app.UseBaseUrlRedirection();
2020-09-03 19:11:12 -04:00
// Wrap rest of configuration so everything only listens on BaseUrl.
app.Map(_serverConfigurationManager.Configuration.BaseUrl, mainApp =>
{
if (env.IsDevelopment())
{
mainApp.UseDeveloperExceptionPage();
}
2020-04-21 09:36:22 -04:00
mainApp.UseForwardedHeaders();
2020-09-03 19:11:12 -04:00
mainApp.UseMiddleware<ExceptionMiddleware>();
2020-09-03 19:11:12 -04:00
mainApp.UseMiddleware<ResponseTimeMiddleware>();
2020-09-03 19:11:12 -04:00
mainApp.UseWebSockets();
2020-09-03 19:11:12 -04:00
mainApp.UseResponseCompression();
2020-09-03 08:05:16 -04:00
2020-09-05 11:10:05 -04:00
mainApp.UseCors();
2020-09-03 19:11:12 -04:00
if (_serverConfigurationManager.Configuration.RequireHttps
&& _serverApplicationHost.ListenWithHttps)
{
2020-09-03 19:11:12 -04:00
mainApp.UseHttpsRedirection();
}
2020-09-03 19:11:12 -04:00
mainApp.UseStaticFiles();
if (appConfig.HostWebClient())
{
2020-10-02 15:30:31 -04:00
var extensionProvider = new FileExtensionContentTypeProvider();
// subtitles octopus requires .data files.
extensionProvider.Mappings.Add(".data", MediaTypeNames.Application.Octet);
2020-09-03 19:11:12 -04:00
mainApp.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(_serverConfigurationManager.ApplicationPaths.WebPath),
2020-10-02 15:30:31 -04:00
RequestPath = "/web",
ContentTypeProvider = extensionProvider
2020-09-03 19:11:12 -04:00
});
}
2020-09-03 19:11:12 -04:00
mainApp.UseAuthentication();
mainApp.UseJellyfinApiSwagger(_serverConfigurationManager);
mainApp.UseRouting();
mainApp.UseAuthorization();
2020-09-03 19:11:12 -04:00
mainApp.UseLanFiltering();
mainApp.UseIpBasedAccessValidation();
mainApp.UseWebSocketHandler();
mainApp.UseServerStartupMessage();
if (_serverConfigurationManager.Configuration.EnableMetrics)
{
2020-09-03 19:14:50 -04:00
// Must be registered after any middleware that could change HTTP response codes or the data will be bad
mainApp.UseHttpMetrics();
}
2020-09-03 19:14:50 -04:00
2020-09-03 19:11:12 -04:00
mainApp.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
if (_serverConfigurationManager.Configuration.EnableMetrics)
{
endpoints.MapMetrics("/metrics");
}
endpoints.MapHealthChecks("/health");
});
});
// Add type descriptor for legacy datetime parsing.
TypeDescriptor.AddAttributes(typeof(DateTime?), new TypeConverterAttribute(typeof(DateTimeTypeConverter)));
}
}
}