diff options
| author | Claus Vium <cvium@users.noreply.github.com> | 2022-10-07 09:57:16 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-07 09:57:16 +0200 |
| commit | 81b04ddbb54201d2e07310e3c700cca8a94d8955 (patch) | |
| tree | a4e9aeb70e35b3e47a7d8af17b328e88a1c77ed0 /Jellyfin.Server | |
| parent | 6bf71c0fd355e9c95a1e142019d9bc5cce34200d (diff) | |
| parent | 14027f962ce074623fd89967ca9565bbeb785066 (diff) | |
Merge branch 'master' into providermanager-cleanup
Diffstat (limited to 'Jellyfin.Server')
| -rw-r--r-- | Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs | 6 | ||||
| -rw-r--r-- | Jellyfin.Server/Filters/AdditionalModelFilter.cs | 29 | ||||
| -rw-r--r-- | Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs | 11 | ||||
| -rw-r--r-- | Jellyfin.Server/Jellyfin.Server.csproj | 14 | ||||
| -rw-r--r-- | Jellyfin.Server/Middleware/ResponseTimeMiddleware.cs | 40 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs | 18 | ||||
| -rw-r--r-- | Jellyfin.Server/Program.cs | 12 | ||||
| -rw-r--r-- | Jellyfin.Server/Startup.cs | 17 |
8 files changed, 99 insertions, 48 deletions
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index 3df8481fd4..66fa3bc31b 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -440,6 +440,12 @@ namespace Jellyfin.Server.Extensions .Cast<IOpenApiAny>() .ToArray() }); + + // Swashbuckle doesn't use JsonOptions to describe responses, so we need to manually describe it. + options.MapType<Version>(() => new OpenApiSchema + { + Type = "string" + }); } } } diff --git a/Jellyfin.Server/Filters/AdditionalModelFilter.cs b/Jellyfin.Server/Filters/AdditionalModelFilter.cs index 87a59e0b45..487948f815 100644 --- a/Jellyfin.Server/Filters/AdditionalModelFilter.cs +++ b/Jellyfin.Server/Filters/AdditionalModelFilter.cs @@ -1,4 +1,8 @@ -using MediaBrowser.Common.Plugins; +using System; +using Jellyfin.Extensions; +using Jellyfin.Server.Migrations; +using MediaBrowser.Common.Plugins; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.ApiClient; using MediaBrowser.Model.Entities; @@ -14,6 +18,19 @@ namespace Jellyfin.Server.Filters /// </summary> public class AdditionalModelFilter : IDocumentFilter { + // Array of options that should not be visible in the api spec. + private static readonly Type[] _ignoredConfigurations = { typeof(MigrationOptions) }; + private readonly IServerConfigurationManager _serverConfigurationManager; + + /// <summary> + /// Initializes a new instance of the <see cref="AdditionalModelFilter"/> class. + /// </summary> + /// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> + public AdditionalModelFilter(IServerConfigurationManager serverConfigurationManager) + { + _serverConfigurationManager = serverConfigurationManager; + } + /// <inheritdoc /> public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { @@ -29,6 +46,16 @@ namespace Jellyfin.Server.Filters context.SchemaGenerator.GenerateSchema(typeof(SessionMessageType), context.SchemaRepository); context.SchemaGenerator.GenerateSchema(typeof(ServerDiscoveryInfo), context.SchemaRepository); + + foreach (var configuration in _serverConfigurationManager.GetConfigurationStores()) + { + if (_ignoredConfigurations.IndexOf(configuration.ConfigurationType) != -1) + { + continue; + } + + context.SchemaGenerator.GenerateSchema(configuration.ConfigurationType, context.SchemaRepository); + } } } } diff --git a/Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs b/Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs index 7e7e4ca95b..bb264d5127 100644 --- a/Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs +++ b/Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs @@ -69,15 +69,8 @@ namespace Jellyfin.Server.Infrastructure /// <inheritdoc /> protected override Task WriteFileAsync(ActionContext context, PhysicalFileResult result, RangeItemHeaderValue? range, long rangeLength) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } + ArgumentNullException.ThrowIfNull(context); + ArgumentNullException.ThrowIfNull(result); if (range != null && rangeLength == 0) { diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj index fb021f3afa..b2d79050b1 100644 --- a/Jellyfin.Server/Jellyfin.Server.csproj +++ b/Jellyfin.Server/Jellyfin.Server.csproj @@ -29,26 +29,26 @@ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" /> - <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.406" PrivateAssets="All" /> + <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="All" /> <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" /> </ItemGroup> <ItemGroup> - <PackageReference Include="CommandLineParser" Version="2.8.0" /> + <PackageReference Include="CommandLineParser" Version="2.9.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" /> - <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="6.0.3" /> - <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="6.0.3" /> + <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="6.0.9" /> + <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="6.0.9" /> <PackageReference Include="prometheus-net" Version="6.0.0" /> <PackageReference Include="prometheus-net.AspNetCore" Version="6.0.0" /> <PackageReference Include="Serilog.AspNetCore" Version="4.1.0" /> <PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" /> - <PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" /> + <PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" /> <PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> - <PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" /> + <PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.Graylog" Version="2.3.0" /> - <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.7" /> + <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.2" /> </ItemGroup> <ItemGroup> diff --git a/Jellyfin.Server/Middleware/ResponseTimeMiddleware.cs b/Jellyfin.Server/Middleware/ResponseTimeMiddleware.cs index da9b691365..1c25696cd1 100644 --- a/Jellyfin.Server/Middleware/ResponseTimeMiddleware.cs +++ b/Jellyfin.Server/Middleware/ResponseTimeMiddleware.cs @@ -19,41 +19,44 @@ namespace Jellyfin.Server.Middleware private readonly RequestDelegate _next; private readonly ILogger<ResponseTimeMiddleware> _logger; - private readonly bool _enableWarning; - private readonly long _warningThreshold; - /// <summary> /// Initializes a new instance of the <see cref="ResponseTimeMiddleware"/> class. /// </summary> /// <param name="next">Next request delegate.</param> /// <param name="logger">Instance of the <see cref="ILogger{ExceptionMiddleware}"/> interface.</param> - /// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> public ResponseTimeMiddleware( RequestDelegate next, - ILogger<ResponseTimeMiddleware> logger, - IServerConfigurationManager serverConfigurationManager) + ILogger<ResponseTimeMiddleware> logger) { _next = next; _logger = logger; - - _enableWarning = serverConfigurationManager.Configuration.EnableSlowResponseWarning; - _warningThreshold = serverConfigurationManager.Configuration.SlowResponseThresholdMs; } /// <summary> /// Invoke request. /// </summary> /// <param name="context">Request context.</param> + /// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> /// <returns>Task.</returns> - public async Task Invoke(HttpContext context) + public async Task Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager) { var watch = new Stopwatch(); watch.Start(); - + var enableWarning = serverConfigurationManager.Configuration.EnableSlowResponseWarning; + var warningThreshold = serverConfigurationManager.Configuration.SlowResponseThresholdMs; context.Response.OnStarting(() => { watch.Stop(); - LogWarning(context, watch); + if (enableWarning && watch.ElapsedMilliseconds > warningThreshold) + { + _logger.LogWarning( + "Slow HTTP Response from {Url} to {RemoteIp} in {Elapsed:g} with Status Code {StatusCode}", + context.Request.GetDisplayUrl(), + context.GetNormalizedRemoteIp(), + watch.Elapsed, + context.Response.StatusCode); + } + var responseTimeForCompleteRequest = watch.ElapsedMilliseconds; context.Response.Headers[ResponseHeaderResponseTime] = responseTimeForCompleteRequest.ToString(CultureInfo.InvariantCulture); return Task.CompletedTask; @@ -62,18 +65,5 @@ namespace Jellyfin.Server.Middleware // Call the next delegate/middleware in the pipeline await this._next(context).ConfigureAwait(false); } - - private void LogWarning(HttpContext context, Stopwatch watch) - { - if (_enableWarning && watch.ElapsedMilliseconds > _warningThreshold) - { - _logger.LogWarning( - "Slow HTTP Response from {Url} to {RemoteIp} in {Elapsed:g} with Status Code {StatusCode}", - context.Request.GetDisplayUrl(), - context.GetNormalizedRemoteIp(), - watch.Elapsed, - context.Response.StatusCode); - } - } } } diff --git a/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs index afd7aee5d0..ba0e33585c 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs @@ -5,6 +5,7 @@ using Emby.Server.Implementations.Data; using Jellyfin.Data.Entities.Security; using Jellyfin.Server.Implementations; using MediaBrowser.Controller; +using MediaBrowser.Controller.Library; using Microsoft.Extensions.Logging; using SQLitePCL.pretty; @@ -20,6 +21,7 @@ namespace Jellyfin.Server.Migrations.Routines private readonly ILogger<MigrateAuthenticationDb> _logger; private readonly JellyfinDbProvider _dbProvider; private readonly IServerApplicationPaths _appPaths; + private readonly IUserManager _userManager; /// <summary> /// Initializes a new instance of the <see cref="MigrateAuthenticationDb"/> class. @@ -27,11 +29,17 @@ namespace Jellyfin.Server.Migrations.Routines /// <param name="logger">The logger.</param> /// <param name="dbProvider">The database provider.</param> /// <param name="appPaths">The server application paths.</param> - public MigrateAuthenticationDb(ILogger<MigrateAuthenticationDb> logger, JellyfinDbProvider dbProvider, IServerApplicationPaths appPaths) + /// <param name="userManager">The user manager.</param> + public MigrateAuthenticationDb( + ILogger<MigrateAuthenticationDb> logger, + JellyfinDbProvider dbProvider, + IServerApplicationPaths appPaths, + IUserManager userManager) { _logger = logger; _dbProvider = dbProvider; _appPaths = appPaths; + _userManager = userManager; } /// <inheritdoc /> @@ -74,6 +82,14 @@ namespace Jellyfin.Server.Migrations.Routines } else { + var userId = new Guid(row[6].ToString()); + var user = _userManager.GetUserById(userId); + if (user is null) + { + // User doesn't exist, don't bring over the device. + continue; + } + dbContext.Devices.Add(new Device( new Guid(row[6].ToString()), row[3].ToString(), diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 1323d8a480..a6f0b705dc 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -243,7 +243,7 @@ namespace Jellyfin.Server } } - appHost.Dispose(); + await appHost.DisposeAsync().ConfigureAwait(false); } if (_restartOnShutdown) @@ -545,12 +545,14 @@ namespace Jellyfin.Server const string ResourcePath = "Jellyfin.Server.Resources.Configuration.logging.json"; Stream resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath) ?? throw new InvalidOperationException($"Invalid resource path: '{ResourcePath}'"); - Stream dst = new FileStream(configPath, FileMode.CreateNew, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous); await using (resource.ConfigureAwait(false)) - await using (dst.ConfigureAwait(false)) { - // Copy the resource contents to the expected file path for the config file - await resource.CopyToAsync(dst).ConfigureAwait(false); + Stream dst = new FileStream(configPath, FileMode.CreateNew, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous); + await using (dst.ConfigureAwait(false)) + { + // Copy the resource contents to the expected file path for the config file + await resource.CopyToAsync(dst).ConfigureAwait(false); + } } } diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 8eb5f21960..1954a5c558 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -103,6 +104,22 @@ namespace Jellyfin.Server }) .ConfigurePrimaryHttpMessageHandler(defaultHttpClientHandlerDelegate); + services.AddHttpClient(NamedClient.Dlna, c => + { + c.DefaultRequestHeaders.UserAgent.ParseAdd( + string.Format( + CultureInfo.InvariantCulture, + "{0}/{1} UPnP/1.0 {2}/{3}", + MediaBrowser.Common.System.OperatingSystem.Name, + Environment.OSVersion, + _serverApplicationHost.Name, + _serverApplicationHost.ApplicationVersionString)); + + c.DefaultRequestHeaders.Add("CPFN.UPNP.ORG", _serverApplicationHost.FriendlyName); // Required for UPnP DeviceArchitecture v2.0 + c.DefaultRequestHeaders.Add("FriendlyName.DLNA.ORG", _serverApplicationHost.FriendlyName); // REVIEW: where does this come from? + }) + .ConfigurePrimaryHttpMessageHandler(defaultHttpClientHandlerDelegate); + services.AddHealthChecks() .AddDbContextCheck<JellyfinDb>(); |
