DynamicCorsMiddleware.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using System;
  2. using System.Threading.Tasks;
  3. using Microsoft.AspNetCore.Cors.Infrastructure;
  4. using Microsoft.AspNetCore.Http;
  5. using Microsoft.Extensions.Logging;
  6. using Microsoft.Net.Http.Headers;
  7. namespace Jellyfin.Server.Middleware
  8. {
  9. /// <summary>
  10. /// Dynamic cors middleware.
  11. /// </summary>
  12. public class DynamicCorsMiddleware
  13. {
  14. private readonly RequestDelegate _next;
  15. private readonly ILogger<DynamicCorsMiddleware> _logger;
  16. private readonly CorsMiddleware _corsMiddleware;
  17. /// <summary>
  18. /// Initializes a new instance of the <see cref="DynamicCorsMiddleware"/> class.
  19. /// </summary>
  20. /// <param name="next">Next request delegate.</param>
  21. /// <param name="corsService">Instance of the <see cref="ICorsService"/> interface.</param>
  22. /// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
  23. /// <param name="policyName">The cors policy name.</param>
  24. public DynamicCorsMiddleware(
  25. RequestDelegate next,
  26. ICorsService corsService,
  27. ILoggerFactory loggerFactory,
  28. string policyName)
  29. {
  30. _corsMiddleware = new CorsMiddleware(next, corsService, loggerFactory, policyName);
  31. _next = next;
  32. _logger = loggerFactory.CreateLogger<DynamicCorsMiddleware>();
  33. }
  34. /// <summary>
  35. /// Invoke request.
  36. /// </summary>
  37. /// <param name="context">Request context.</param>
  38. /// <param name="corsPolicyProvider">Instance of the <see cref="ICorsPolicyProvider"/> interface.</param>
  39. /// <returns>Task.</returns>
  40. ///
  41. public async Task Invoke(HttpContext context, ICorsPolicyProvider corsPolicyProvider)
  42. {
  43. // Only execute if is preflight request.
  44. if (string.Equals(context.Request.Method, CorsConstants.PreflightHttpMethod, StringComparison.OrdinalIgnoreCase))
  45. {
  46. // Invoke original cors middleware.
  47. await _corsMiddleware.Invoke(context, corsPolicyProvider).ConfigureAwait(false);
  48. if (context.Response.Headers.TryGetValue(HeaderNames.AccessControlAllowOrigin, out var headerValue)
  49. && string.Equals(headerValue, "*", StringComparison.Ordinal))
  50. {
  51. context.Response.Headers[HeaderNames.AccessControlAllowOrigin] = context.Request.Host.Value;
  52. // Always allow credentials.
  53. context.Response.Headers[HeaderNames.AccessControlAllowCredentials] = "true";
  54. _logger.LogDebug("Overwriting CORS response header: {HeaderName}: {HeaderValue}", HeaderNames.AccessControlAllowOrigin, context.Request.Host.Value);
  55. }
  56. }
  57. // Call the next delegate/middleware in the pipeline
  58. await this._next(context).ConfigureAwait(false);
  59. }
  60. }
  61. }