using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; namespace Jellyfin.Server.Middleware { /// /// Dynamic cors middleware. /// public class DynamicCorsMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; private readonly CorsMiddleware _corsMiddleware; /// /// Initializes a new instance of the class. /// /// Next request delegate. /// Instance of the interface. /// Instance of the interface. /// The cors policy name. public DynamicCorsMiddleware( RequestDelegate next, ICorsService corsService, ILoggerFactory loggerFactory, string policyName) { _corsMiddleware = new CorsMiddleware(next, corsService, loggerFactory, policyName); _next = next; _logger = loggerFactory.CreateLogger(); } /// /// Invoke request. /// /// Request context. /// Instance of the interface. /// Task. /// public async Task Invoke(HttpContext context, ICorsPolicyProvider corsPolicyProvider) { // Only execute if is preflight request. if (string.Equals(context.Request.Method, CorsConstants.PreflightHttpMethod, StringComparison.OrdinalIgnoreCase)) { // Invoke original cors middleware. await _corsMiddleware.Invoke(context, corsPolicyProvider).ConfigureAwait(false); if (context.Response.Headers.TryGetValue(HeaderNames.AccessControlAllowOrigin, out var headerValue) && string.Equals(headerValue, "*", StringComparison.Ordinal)) { context.Response.Headers[HeaderNames.AccessControlAllowOrigin] = context.Request.Host.Value; // Always allow credentials. context.Response.Headers[HeaderNames.AccessControlAllowCredentials] = "true"; _logger.LogDebug("Overwriting CORS response header: {HeaderName}: {HeaderValue}", HeaderNames.AccessControlAllowOrigin, context.Request.Host.Value); } } // Call the next delegate/middleware in the pipeline await this._next(context).ConfigureAwait(false); } } }