2020-08-10 17:58:06 +00:00
|
|
|
using System;
|
|
|
|
using System.ComponentModel;
|
2020-08-31 14:47:38 +00:00
|
|
|
using System.Net.Http.Headers;
|
2020-08-10 17:58:06 +00:00
|
|
|
using Jellyfin.Api.TypeConverters;
|
2019-11-24 14:27:58 +00:00
|
|
|
using Jellyfin.Server.Extensions;
|
2020-09-03 19:44:49 +00:00
|
|
|
using Jellyfin.Server.Implementations;
|
2020-04-24 03:24:40 +00:00
|
|
|
using Jellyfin.Server.Middleware;
|
2020-08-19 12:31:45 +00:00
|
|
|
using MediaBrowser.Common.Net;
|
2019-11-24 14:27:58 +00:00
|
|
|
using MediaBrowser.Controller;
|
|
|
|
using MediaBrowser.Controller.Configuration;
|
2020-09-02 14:03:15 +00:00
|
|
|
using MediaBrowser.Controller.Extensions;
|
2019-11-24 14:27:58 +00:00
|
|
|
using Microsoft.AspNetCore.Builder;
|
|
|
|
using Microsoft.AspNetCore.Hosting;
|
2020-09-02 14:03:15 +00:00
|
|
|
using Microsoft.Extensions.Configuration;
|
2019-11-24 14:27:58 +00:00
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2020-09-02 14:03:15 +00:00
|
|
|
using Microsoft.Extensions.FileProviders;
|
2019-11-24 14:27:58 +00:00
|
|
|
using Microsoft.Extensions.Hosting;
|
2020-04-26 01:35:51 +00:00
|
|
|
using Prometheus;
|
2019-11-24 14:27:58 +00:00
|
|
|
|
|
|
|
namespace Jellyfin.Server
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// Startup configuration for the Kestrel webhost.
|
|
|
|
/// </summary>
|
|
|
|
public class Startup
|
|
|
|
{
|
|
|
|
private readonly IServerConfigurationManager _serverConfigurationManager;
|
2020-09-02 22:31:42 +00:00
|
|
|
private readonly IServerApplicationHost _serverApplicationHost;
|
2019-11-24 14:27:58 +00:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes a new instance of the <see cref="Startup" /> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="serverConfigurationManager">The server configuration manager.</param>
|
2020-09-02 22:31:42 +00:00
|
|
|
/// <param name="serverApplicationHost">The server application host.</param>
|
|
|
|
public Startup(
|
|
|
|
IServerConfigurationManager serverConfigurationManager,
|
|
|
|
IServerApplicationHost serverApplicationHost)
|
2019-11-24 14:27:58 +00:00
|
|
|
{
|
|
|
|
_serverConfigurationManager = serverConfigurationManager;
|
2020-09-02 22:31:42 +00:00
|
|
|
_serverApplicationHost = serverApplicationHost;
|
2019-11-24 14:27:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <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 22:38:52 +00:00
|
|
|
services.AddHttpsRedirection(options =>
|
|
|
|
{
|
|
|
|
options.HttpsPort = _serverApplicationHost.HttpsPort;
|
|
|
|
});
|
2020-09-05 15:10:05 +00:00
|
|
|
services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies());
|
2019-11-24 14:27:58 +00:00
|
|
|
|
|
|
|
services.AddJellyfinApiSwagger();
|
|
|
|
|
|
|
|
// configure custom legacy authentication
|
|
|
|
services.AddCustomAuthentication();
|
|
|
|
|
|
|
|
services.AddJellyfinApiAuthorization();
|
2020-08-19 12:31:45 +00:00
|
|
|
|
2020-09-02 22:31:42 +00:00
|
|
|
var productHeader = new ProductInfoHeaderValue(
|
|
|
|
_serverApplicationHost.Name.Replace(' ', '-'),
|
|
|
|
_serverApplicationHost.ApplicationVersionString);
|
2020-08-19 12:31:45 +00:00
|
|
|
services
|
2020-08-31 14:47:38 +00:00
|
|
|
.AddHttpClient(NamedClient.Default, c =>
|
|
|
|
{
|
2020-08-31 15:15:20 +00:00
|
|
|
c.DefaultRequestHeaders.UserAgent.Add(productHeader);
|
2020-08-31 14:47:38 +00:00
|
|
|
})
|
|
|
|
.ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler());
|
|
|
|
|
|
|
|
services.AddHttpClient(NamedClient.MusicBrainz, c =>
|
|
|
|
{
|
2020-08-31 15:15:20 +00:00
|
|
|
c.DefaultRequestHeaders.UserAgent.Add(productHeader);
|
2020-09-02 22:31:42 +00:00
|
|
|
c.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue($"({_serverApplicationHost.ApplicationUserAgentAddress})"));
|
2020-08-31 14:47:38 +00:00
|
|
|
})
|
|
|
|
.ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler());
|
2020-09-03 15:26:22 +00:00
|
|
|
|
|
|
|
services.AddHealthChecks()
|
2020-09-03 19:44:49 +00:00
|
|
|
.AddDbContextCheck<JellyfinDb>();
|
2019-11-24 14:27:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Configures the app builder for the webhost.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="app">The application builder.</param>
|
|
|
|
/// <param name="env">The webhost environment.</param>
|
2020-09-02 14:03:15 +00:00
|
|
|
/// <param name="appConfig">The application config.</param>
|
2019-11-24 14:27:58 +00:00
|
|
|
public void Configure(
|
|
|
|
IApplicationBuilder app,
|
|
|
|
IWebHostEnvironment env,
|
2020-09-02 14:03:15 +00:00
|
|
|
IConfiguration appConfig)
|
2019-11-24 14:27:58 +00:00
|
|
|
{
|
2020-09-03 23:11:12 +00:00
|
|
|
// Only add base url redirection if a base url is set.
|
|
|
|
if (!string.IsNullOrEmpty(_serverConfigurationManager.Configuration.BaseUrl))
|
2019-11-24 14:27:58 +00:00
|
|
|
{
|
2020-09-03 23:11:12 +00:00
|
|
|
app.UseBaseUrlRedirection();
|
2019-11-24 14:27:58 +00:00
|
|
|
}
|
|
|
|
|
2020-09-03 23:11:12 +00: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 13:36:22 +00:00
|
|
|
|
2020-09-03 23:11:12 +00:00
|
|
|
mainApp.UseMiddleware<ExceptionMiddleware>();
|
2020-07-14 11:26:47 +00:00
|
|
|
|
2020-09-03 23:11:12 +00:00
|
|
|
mainApp.UseMiddleware<ResponseTimeMiddleware>();
|
2019-11-24 14:27:58 +00:00
|
|
|
|
2020-09-03 23:11:12 +00:00
|
|
|
mainApp.UseWebSockets();
|
2019-11-24 14:27:58 +00:00
|
|
|
|
2020-09-03 23:11:12 +00:00
|
|
|
mainApp.UseResponseCompression();
|
2020-09-03 12:05:16 +00:00
|
|
|
|
2020-09-05 15:10:05 +00:00
|
|
|
mainApp.UseCors();
|
2019-11-24 14:27:58 +00:00
|
|
|
|
2020-09-03 23:11:12 +00:00
|
|
|
if (_serverConfigurationManager.Configuration.RequireHttps
|
|
|
|
&& _serverApplicationHost.ListenWithHttps)
|
2020-09-02 14:03:15 +00:00
|
|
|
{
|
2020-09-03 23:11:12 +00:00
|
|
|
mainApp.UseHttpsRedirection();
|
|
|
|
}
|
2020-04-26 15:28:17 +00:00
|
|
|
|
2020-09-03 23:11:12 +00:00
|
|
|
mainApp.UseStaticFiles();
|
|
|
|
if (appConfig.HostWebClient())
|
|
|
|
{
|
|
|
|
mainApp.UseStaticFiles(new StaticFileOptions
|
|
|
|
{
|
|
|
|
FileProvider = new PhysicalFileProvider(_serverConfigurationManager.ApplicationPaths.WebPath),
|
|
|
|
RequestPath = "/web"
|
|
|
|
});
|
|
|
|
}
|
2020-09-02 22:31:42 +00:00
|
|
|
|
2020-09-03 23:11:12 +00:00
|
|
|
mainApp.UseAuthentication();
|
|
|
|
mainApp.UseJellyfinApiSwagger(_serverConfigurationManager);
|
|
|
|
mainApp.UseRouting();
|
|
|
|
mainApp.UseAuthorization();
|
2019-11-24 14:27:58 +00:00
|
|
|
|
2020-09-03 23:11:12 +00:00
|
|
|
mainApp.UseLanFiltering();
|
|
|
|
mainApp.UseIpBasedAccessValidation();
|
|
|
|
mainApp.UseWebSocketHandler();
|
|
|
|
mainApp.UseServerStartupMessage();
|
2020-09-02 22:31:42 +00:00
|
|
|
|
2020-04-26 15:28:17 +00:00
|
|
|
if (_serverConfigurationManager.Configuration.EnableMetrics)
|
|
|
|
{
|
2020-09-03 23:14:50 +00:00
|
|
|
// Must be registered after any middleware that could change HTTP response codes or the data will be bad
|
|
|
|
mainApp.UseHttpMetrics();
|
2020-04-26 15:28:17 +00:00
|
|
|
}
|
2020-09-03 23:14:50 +00:00
|
|
|
|
2020-09-03 23:11:12 +00:00
|
|
|
mainApp.UseEndpoints(endpoints =>
|
|
|
|
{
|
|
|
|
endpoints.MapControllers();
|
|
|
|
if (_serverConfigurationManager.Configuration.EnableMetrics)
|
|
|
|
{
|
|
|
|
endpoints.MapMetrics("/metrics");
|
|
|
|
}
|
|
|
|
|
|
|
|
endpoints.MapHealthChecks("/health");
|
|
|
|
});
|
2019-11-24 14:27:58 +00:00
|
|
|
});
|
|
|
|
|
2020-08-10 17:58:06 +00:00
|
|
|
// Add type descriptor for legacy datetime parsing.
|
|
|
|
TypeDescriptor.AddAttributes(typeof(DateTime?), new TypeConverterAttribute(typeof(DateTimeTypeConverter)));
|
2019-11-24 14:27:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|