< Summary - Jellyfin

Information
Class: Jellyfin.Api.Middleware.UrlDecodeQueryFeature
Assembly: Jellyfin.Api
File(s): /srv/git/jellyfin/Jellyfin.Api/Middleware/UrlDecodeQueryFeature.cs
Line coverage
92%
Covered lines: 23
Uncovered lines: 2
Coverable lines: 25
Total lines: 83
Line coverage: 92%
Branch coverage
78%
Covered branches: 11
Total branches: 14
Branch coverage: 78.5%
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%
get_Query()50%22100%
set_Query(...)83.33%12.871281.81%

File(s)

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

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using Jellyfin.Extensions;
 5using Microsoft.AspNetCore.Http;
 6using Microsoft.AspNetCore.Http.Features;
 7using Microsoft.Extensions.Primitives;
 8
 9namespace Jellyfin.Api.Middleware;
 10
 11/// <summary>
 12/// Defines the <see cref="UrlDecodeQueryFeature"/>.
 13/// </summary>
 14public class UrlDecodeQueryFeature : IQueryFeature
 15{
 16    private IQueryCollection? _store;
 17
 18    /// <summary>
 19    /// Initializes a new instance of the <see cref="UrlDecodeQueryFeature"/> class.
 20    /// </summary>
 21    /// <param name="feature">The <see cref="IQueryFeature"/> instance.</param>
 22    public UrlDecodeQueryFeature(IQueryFeature feature)
 23    {
 18624        Query = feature.Query;
 18625    }
 26
 27    /// <summary>
 28    /// Gets or sets a value indicating the url decoded <see cref="IQueryCollection"/>.
 29    /// </summary>
 30    public IQueryCollection Query
 31    {
 32        get
 33        {
 13134            return _store ?? QueryCollection.Empty;
 35        }
 36
 37        set
 38        {
 39            // Only interested in where the querystring is encoded which shows up as one key with nothing in the value.
 18640            if (value.Count != 1)
 41            {
 16442                _store = value;
 16443                return;
 44            }
 45
 46            // Encoded querystrings have no value, so don't process anything if a value is present.
 2247            var (key, stringValues) = value.First();
 2248            if (!string.IsNullOrEmpty(stringValues))
 49            {
 1750                _store = value;
 1751                return;
 52            }
 53
 554            if (!key.Contains('=', StringComparison.Ordinal))
 55            {
 156                _store = value;
 157                return;
 58            }
 59
 460            var pairs = new Dictionary<string, StringValues>();
 2461            foreach (var pair in key.SpanSplit('&'))
 62            {
 863                var i = pair.IndexOf('=');
 864                if (i == -1)
 65                {
 66                    // encoded is an equals.
 67                    // We use TryAdd so duplicate keys get ignored
 068                    pairs.TryAdd(pair.ToString(), StringValues.Empty);
 069                    continue;
 70                }
 71
 872                var k = pair[..i].ToString();
 873                var v = pair[(i + 1)..].ToString();
 874                if (!pairs.TryAdd(k, new StringValues(v)))
 75                {
 276                    pairs[k] = StringValues.Concat(pairs[k], v);
 77                }
 78            }
 79
 480            _store = new QueryCollection(pairs);
 481        }
 82    }
 83}