< Summary - Jellyfin

Information
Class: Jellyfin.Api.Middleware.BaseUrlRedirectionMiddleware
Assembly: Jellyfin.Api
File(s): /srv/git/jellyfin/Jellyfin.Api/Middleware/BaseUrlRedirectionMiddleware.cs
Line coverage
100%
Covered lines: 4
Uncovered lines: 0
Coverable lines: 4
Total lines: 78
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%

File(s)

/srv/git/jellyfin/Jellyfin.Api/Middleware/BaseUrlRedirectionMiddleware.cs

#LineLine coverage
 1using System;
 2using System.Threading.Tasks;
 3using MediaBrowser.Common.Net;
 4using MediaBrowser.Controller.Configuration;
 5using Microsoft.AspNetCore.Http;
 6using Microsoft.Extensions.Configuration;
 7using Microsoft.Extensions.Logging;
 8using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
 9
 10namespace Jellyfin.Api.Middleware;
 11
 12/// <summary>
 13/// Redirect requests without baseurl prefix to the baseurl prefixed URL.
 14/// </summary>
 15public class BaseUrlRedirectionMiddleware
 16{
 17    private readonly RequestDelegate _next;
 18    private readonly ILogger<BaseUrlRedirectionMiddleware> _logger;
 19    private readonly IConfiguration _configuration;
 20
 21    /// <summary>
 22    /// Initializes a new instance of the <see cref="BaseUrlRedirectionMiddleware"/> class.
 23    /// </summary>
 24    /// <param name="next">The next delegate in the pipeline.</param>
 25    /// <param name="logger">The logger.</param>
 26    /// <param name="configuration">The application configuration.</param>
 27    public BaseUrlRedirectionMiddleware(
 28        RequestDelegate next,
 29        ILogger<BaseUrlRedirectionMiddleware> logger,
 30        IConfiguration configuration)
 31    {
 2232        _next = next;
 2233        _logger = logger;
 2234        _configuration = configuration;
 2235    }
 36
 37    /// <summary>
 38    /// Executes the middleware action.
 39    /// </summary>
 40    /// <param name="httpContext">The current HTTP context.</param>
 41    /// <param name="serverConfigurationManager">The server configuration manager.</param>
 42    /// <returns>The async task.</returns>
 43    public async Task Invoke(HttpContext httpContext, IServerConfigurationManager serverConfigurationManager)
 44    {
 45        var localPath = httpContext.Request.Path.ToString();
 46        var baseUrlPrefix = serverConfigurationManager.GetNetworkConfiguration().BaseUrl;
 47
 48        if (string.IsNullOrEmpty(localPath)
 49            || string.Equals(localPath, baseUrlPrefix, StringComparison.OrdinalIgnoreCase)
 50            || string.Equals(localPath, baseUrlPrefix + "/", StringComparison.OrdinalIgnoreCase)
 51            || !localPath.StartsWith(baseUrlPrefix, StringComparison.OrdinalIgnoreCase)
 52           )
 53        {
 54            // Redirect health endpoint
 55            if (string.Equals(localPath, "/health", StringComparison.OrdinalIgnoreCase)
 56                || string.Equals(localPath, "/health/", StringComparison.OrdinalIgnoreCase))
 57            {
 58                _logger.LogDebug("Redirecting /health check");
 59                httpContext.Response.Redirect(baseUrlPrefix + "/health");
 60                return;
 61            }
 62
 63            // Always redirect back to the default path if the base prefix is invalid or missing
 64            _logger.LogDebug("Normalizing an URL at {LocalPath}", localPath);
 65
 66            var port = httpContext.Request.Host.Port ?? -1;
 67            var uri = new UriBuilder(httpContext.Request.Scheme, httpContext.Request.Host.Host, port, localPath).Uri;
 68            var redirectUri = new UriBuilder(httpContext.Request.Scheme, httpContext.Request.Host.Host, port, baseUrlPre
 69            var target = uri.MakeRelativeUri(redirectUri).ToString();
 70            _logger.LogDebug("Redirecting to {Target}", target);
 71
 72            httpContext.Response.Redirect(target);
 73            return;
 74        }
 75
 76        await _next(httpContext).ConfigureAwait(false);
 77    }
 78}