< Summary - Jellyfin

Information
Class: Jellyfin.Api.Middleware.BaseUrlRedirectionMiddleware
Assembly: Jellyfin.Api
File(s): /srv/git/jellyfin/Jellyfin.Api/Middleware/BaseUrlRedirectionMiddleware.cs
Line coverage
50%
Covered lines: 13
Uncovered lines: 13
Coverable lines: 26
Total lines: 78
Line coverage: 50%
Branch coverage
33%
Covered branches: 4
Total branches: 12
Branch coverage: 33.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 1/23/2026 - 12:11:06 AM Line coverage: 100% (4/4) Total lines: 784/19/2026 - 12:14:27 AM Line coverage: 50% (13/26) Branch coverage: 33.3% (4/12) Total lines: 78 4/19/2026 - 12:14:27 AM Line coverage: 50% (13/26) Branch coverage: 33.3% (4/12) Total lines: 78

Coverage delta

Coverage delta 50 -50

Metrics

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

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    {
 2132        _next = next;
 2133        _logger = logger;
 2134        _configuration = configuration;
 2135    }
 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    {
 17045        var localPath = httpContext.Request.Path.ToString();
 17046        var baseUrlPrefix = serverConfigurationManager.GetNetworkConfiguration().BaseUrl;
 47
 17048        if (string.IsNullOrEmpty(localPath)
 17049            || string.Equals(localPath, baseUrlPrefix, StringComparison.OrdinalIgnoreCase)
 17050            || string.Equals(localPath, baseUrlPrefix + "/", StringComparison.OrdinalIgnoreCase)
 17051            || !localPath.StartsWith(baseUrlPrefix, StringComparison.OrdinalIgnoreCase)
 17052           )
 53        {
 54            // Redirect health endpoint
 055            if (string.Equals(localPath, "/health", StringComparison.OrdinalIgnoreCase)
 056                || string.Equals(localPath, "/health/", StringComparison.OrdinalIgnoreCase))
 57            {
 058                _logger.LogDebug("Redirecting /health check");
 059                httpContext.Response.Redirect(baseUrlPrefix + "/health");
 060                return;
 61            }
 62
 63            // Always redirect back to the default path if the base prefix is invalid or missing
 064            _logger.LogDebug("Normalizing an URL at {LocalPath}", localPath);
 65
 066            var port = httpContext.Request.Host.Port ?? -1;
 067            var uri = new UriBuilder(httpContext.Request.Scheme, httpContext.Request.Host.Host, port, localPath).Uri;
 068            var redirectUri = new UriBuilder(httpContext.Request.Scheme, httpContext.Request.Host.Host, port, baseUrlPre
 069            var target = uri.MakeRelativeUri(redirectUri).ToString();
 070            _logger.LogDebug("Redirecting to {Target}", target);
 71
 072            httpContext.Response.Redirect(target);
 073            return;
 74        }
 75
 17076        await _next(httpContext).ConfigureAwait(false);
 17077    }
 78}