From 81d675990f87586061bdce5d585dad28f7e181fa Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 5 May 2021 22:52:39 +0100 Subject: [PATCH 01/29] Enable automatic url decoding --- .../ApiApplicationBuilderExtensions.cs | 10 +++ .../QueryStringDecodingMiddleware.cs | 42 +++++++++++ .../Middleware/UrlDecodeQueryFeature.cs | 75 +++++++++++++++++++ Jellyfin.Server/Startup.cs | 1 + 4 files changed, 128 insertions(+) create mode 100644 Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs create mode 100644 Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index 88e2b4152b..e291677475 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -78,6 +78,16 @@ namespace Jellyfin.Server.Extensions return appBuilder.UseMiddleware(); } + /// + /// Enables url decoding before binding to the application pipeline. + /// + /// The . + /// The updated application builder. + public static IApplicationBuilder UseQueryStringDecoding(this IApplicationBuilder appBuilder) + { + return appBuilder.UseMiddleware(); + } + /// /// Adds base url redirection to the application pipeline. /// diff --git a/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs new file mode 100644 index 0000000000..954dc4ccd9 --- /dev/null +++ b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Server.Middleware +{ + /// + /// URL decodes the querystring before binding. + /// + public class QueryStringDecodingMiddleware + { + private readonly RequestDelegate _next; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// The next delegate in the pipeline. + /// The logger. + public QueryStringDecodingMiddleware( + RequestDelegate next, + ILogger logger) + { + _next = next; + _logger = logger; + } + + /// + /// Executes the middleware action. + /// + /// The current HTTP context. + /// The async task. + public async Task Invoke(HttpContext httpContext) + { + httpContext.Features.Set(new UrlDecodeQueryFeature(httpContext.Features.Get())); + + await _next(httpContext).ConfigureAwait(false); + } + } +} diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs new file mode 100644 index 0000000000..0232b89ce1 --- /dev/null +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; +using System.Linq; +using System.Web; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.Primitives; + +namespace Jellyfin.Server.Middleware +{ + /// + /// Defines the . + /// + public class UrlDecodeQueryFeature : IQueryFeature + { + private IQueryCollection? _store; + + /// + /// Initializes a new instance of the class. + /// + /// The instance. + public UrlDecodeQueryFeature(IQueryFeature feature) + { + Query = feature.Query; + } + + /// + /// Gets or sets a value indicating the url decoded . + /// + public IQueryCollection Query + { + get + { + return _store ?? QueryCollection.Empty; + } + + set + { + // Only interested in where the querystring is encoded which shows up as one key with everything else in the value. + if (value.Count != 1) + { + _store = value; + return; + } + + // Encoded querystrings have no value, so don't process anything if a values is present. + var kvp = value.First(); + if (!string.IsNullOrEmpty(kvp.Value)) + { + _store = value; + return; + } + + // Unencode and re-parse querystring. + var unencodedKey = HttpUtility.UrlDecode(kvp.Key); + + if (string.Equals(unencodedKey, kvp.Key, System.StringComparison.Ordinal)) + { + _store = value; + return; + } + + var pairs = new Dictionary(); + var queryString = unencodedKey.Split('&', System.StringSplitOptions.RemoveEmptyEntries); + + foreach (var pair in queryString) + { + var item = pair.Split('=', System.StringSplitOptions.RemoveEmptyEntries); + pairs.Add(item[0], new StringValues(item.Length == 2 ? item[1] : string.Empty)); + } + + _store = new QueryCollection(pairs); + } + } + } +} diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index e56e61092b..f27d286584 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -150,6 +150,7 @@ namespace Jellyfin.Server mainApp.UseAuthentication(); mainApp.UseJellyfinApiSwagger(_serverConfigurationManager); + mainApp.UseQueryStringDecoding(); mainApp.UseRouting(); mainApp.UseAuthorization(); From a7bccd4fe0a1c046e335a91e85b8e806b50d58bc Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 5 May 2021 23:09:04 +0100 Subject: [PATCH 02/29] removed unneeded logger. --- Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs index 954dc4ccd9..d6d955c4f1 100644 --- a/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs +++ b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs @@ -12,19 +12,15 @@ namespace Jellyfin.Server.Middleware public class QueryStringDecodingMiddleware { private readonly RequestDelegate _next; - private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The next delegate in the pipeline. - /// The logger. public QueryStringDecodingMiddleware( - RequestDelegate next, - ILogger logger) + RequestDelegate next) { _next = next; - _logger = logger; } /// From dabeabc553afc4551356566f9184e6659f604cee Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 5 May 2021 23:14:05 +0100 Subject: [PATCH 03/29] corrected comments --- Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index 0232b89ce1..b18ba70512 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -35,14 +35,14 @@ namespace Jellyfin.Server.Middleware set { - // Only interested in where the querystring is encoded which shows up as one key with everything else in the value. + // Only interested in where the querystring is encoded which shows up as one key with nothing in the value. if (value.Count != 1) { _store = value; return; } - // Encoded querystrings have no value, so don't process anything if a values is present. + // Encoded querystrings have no value, so don't process anything if a value is present. var kvp = value.First(); if (!string.IsNullOrEmpty(kvp.Value)) { @@ -55,6 +55,7 @@ namespace Jellyfin.Server.Middleware if (string.Equals(unencodedKey, kvp.Key, System.StringComparison.Ordinal)) { + // Don't do anything if it's not encoded. _store = value; return; } From c8061f92bec0d1e12e2b57012c6c72c629374327 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 5 May 2021 23:15:24 +0100 Subject: [PATCH 04/29] slight format correction. --- Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs index d6d955c4f1..08fbbce0b2 100644 --- a/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs +++ b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs @@ -17,8 +17,7 @@ namespace Jellyfin.Server.Middleware /// Initializes a new instance of the class. /// /// The next delegate in the pipeline. - public QueryStringDecodingMiddleware( - RequestDelegate next) + public QueryStringDecodingMiddleware(RequestDelegate next) { _next = next; } From 4f5c9e95041a39ae549bfa3f36bbeda054bce3ca Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 7 May 2021 14:02:42 +0100 Subject: [PATCH 05/29] tests and small fix. --- Jellyfin.Api/Controllers/SystemController.cs | 8 +++- .../Middleware/UrlDecodeQueryFeature.cs | 9 +++- .../Controllers/EncodedQueryStringTest.cs | 47 +++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs diff --git a/Jellyfin.Api/Controllers/SystemController.cs b/Jellyfin.Api/Controllers/SystemController.cs index bbbe5fb8da..5c64d731b6 100644 --- a/Jellyfin.Api/Controllers/SystemController.cs +++ b/Jellyfin.Api/Controllers/SystemController.cs @@ -84,13 +84,19 @@ namespace Jellyfin.Api.Controllers /// /// Pings the system. /// + /// Optional: Parameters to echo back in the response. /// Information retrieved. /// The server name. [HttpGet("Ping", Name = "GetPingSystem")] [HttpPost("Ping", Name = "PostPingSystem")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult PingSystem() + public ActionResult PingSystem([FromQuery]Dictionary? @params = null) { + if (@params != null && @params.Count > 0) + { + Response.Headers.Add("querystring", string.Join("&", @params.Select(x => x.Key + "=" + x.Value))); + } + return _appHost.Name; } diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index b18ba70512..44b30baac0 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -66,7 +66,14 @@ namespace Jellyfin.Server.Middleware foreach (var pair in queryString) { var item = pair.Split('=', System.StringSplitOptions.RemoveEmptyEntries); - pairs.Add(item[0], new StringValues(item.Length == 2 ? item[1] : string.Empty)); + if (item.Length > 0) + { + pairs.Add(item[0], new StringValues(item.Length == 2 ? item[1] : string.Empty)); + } + else + { + pairs.Add(pair, string.Empty); + } } _store = new QueryCollection(pairs); diff --git a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs new file mode 100644 index 0000000000..ce5ac11ea5 --- /dev/null +++ b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs @@ -0,0 +1,47 @@ +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Jellyfin.Api.Tests.Controllers +{ + /// + /// Defines the test for encoded querystrings in the url. + /// + public class EncodedQueryStringTest : IClassFixture + { + private readonly JellyfinApplicationFactory _factory; + + public EncodedQueryStringTest(JellyfinApplicationFactory factory) + { + _factory = factory; + } + + [Fact] + public async Task Ensure_Ping_Working() + { + var client = _factory.CreateClient(); + + var response = await client.GetAsync("system/ping").ConfigureAwait(false); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + + [Theory] + [InlineData("a=1&b=2&c=3", "a=1&b=2&c=3")] // won't be processed as there is more than 1. + [InlineData("a=1", "a=1")] // won't be processed as it has a value + [InlineData("%3D", "==")] // will decode with an empty string value '=' = ''. + [InlineData("a%3D1%26b%3D2%26c%3D3", "a=1&b=2&c=3")] // will be processed. + + public async Task Ensure_Decoding_Of_Urls_Is_Working(string sourceUrl, string unencodedUrl) + { + var client = _factory.CreateClient(); + + var response = await client.GetAsync("system/ping?" + sourceUrl).ConfigureAwait(false); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal(unencodedUrl, response.Headers.GetValues("querystring").First()); + } + } +} From af1fe1af6fee7f4e5cf73d92266df21b291169d9 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 7 May 2021 14:37:26 +0100 Subject: [PATCH 06/29] Moved into test controller. --- Jellyfin.Api/Controllers/SystemController.cs | 8 +--- Jellyfin.Api/Controllers/TestController.cs | 41 +++++++++++++++++++ .../Controllers/EncodedQueryStringTest.cs | 2 +- 3 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 Jellyfin.Api/Controllers/TestController.cs diff --git a/Jellyfin.Api/Controllers/SystemController.cs b/Jellyfin.Api/Controllers/SystemController.cs index 5c64d731b6..bbbe5fb8da 100644 --- a/Jellyfin.Api/Controllers/SystemController.cs +++ b/Jellyfin.Api/Controllers/SystemController.cs @@ -84,19 +84,13 @@ namespace Jellyfin.Api.Controllers /// /// Pings the system. /// - /// Optional: Parameters to echo back in the response. /// Information retrieved. /// The server name. [HttpGet("Ping", Name = "GetPingSystem")] [HttpPost("Ping", Name = "PostPingSystem")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult PingSystem([FromQuery]Dictionary? @params = null) + public ActionResult PingSystem() { - if (@params != null && @params.Count > 0) - { - Response.Headers.Add("querystring", string.Join("&", @params.Select(x => x.Key + "=" + x.Value))); - } - return _appHost.Name; } diff --git a/Jellyfin.Api/Controllers/TestController.cs b/Jellyfin.Api/Controllers/TestController.cs new file mode 100644 index 0000000000..b76895696a --- /dev/null +++ b/Jellyfin.Api/Controllers/TestController.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Linq; +using Jellyfin.Api.Constants; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Jellyfin.Api.Controllers +{ + /// + /// Controller for testing. + /// + [Route("Tests")] + public class TestController : BaseJellyfinApiController + { + /// + /// Initializes a new instance of the class. + /// + public TestController() + { + } + + /// + /// Tests the url decoding. + /// + /// Parameters to echo back in the response. + /// An . + /// Information retrieved. + [HttpGet("Decoding", Name = "TestUrlDecoding")] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult TestUrlDecoding([FromQuery]Dictionary? @params = null) + { + if (@params != null && @params.Count > 0) + { + Response.Headers.Add("querystring", string.Join("&", @params.Select(x => x.Key + "=" + x.Value))); + } + + return Ok(); + } + } +} diff --git a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs index ce5ac11ea5..212fb118cb 100644 --- a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs +++ b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs @@ -39,7 +39,7 @@ namespace Jellyfin.Api.Tests.Controllers { var client = _factory.CreateClient(); - var response = await client.GetAsync("system/ping?" + sourceUrl).ConfigureAwait(false); + var response = await client.GetAsync("Tests/Decoding?" + sourceUrl).ConfigureAwait(false); Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(unencodedUrl, response.Headers.GetValues("querystring").First()); } From 043e69d252d5862ec5466ad037fea05f5aaef40f Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 7 May 2021 18:49:57 +0100 Subject: [PATCH 07/29] Update tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs Co-authored-by: Cody Robibero --- tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs index 212fb118cb..dd81ad1346 100644 --- a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs +++ b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs @@ -34,7 +34,6 @@ namespace Jellyfin.Api.Tests.Controllers [InlineData("a=1", "a=1")] // won't be processed as it has a value [InlineData("%3D", "==")] // will decode with an empty string value '=' = ''. [InlineData("a%3D1%26b%3D2%26c%3D3", "a=1&b=2&c=3")] // will be processed. - public async Task Ensure_Decoding_Of_Urls_Is_Working(string sourceUrl, string unencodedUrl) { var client = _factory.CreateClient(); From 5f70b4ead16965acf4dbaf7bb486ecf072fb2a1b Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 7 May 2021 18:50:38 +0100 Subject: [PATCH 08/29] Update tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs Co-authored-by: Cody Robibero --- .../Controllers/EncodedQueryStringTest.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs index dd81ad1346..80175039ea 100644 --- a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs +++ b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs @@ -20,15 +20,6 @@ namespace Jellyfin.Api.Tests.Controllers _factory = factory; } - [Fact] - public async Task Ensure_Ping_Working() - { - var client = _factory.CreateClient(); - - var response = await client.GetAsync("system/ping").ConfigureAwait(false); - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - } - [Theory] [InlineData("a=1&b=2&c=3", "a=1&b=2&c=3")] // won't be processed as there is more than 1. [InlineData("a=1", "a=1")] // won't be processed as it has a value From 5ad8b53f5d1a540453d897cddf924aa6fee46570 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 7 May 2021 18:51:04 +0100 Subject: [PATCH 09/29] Update Jellyfin.Api/Controllers/TestController.cs Co-authored-by: Cody Robibero --- Jellyfin.Api/Controllers/TestController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Api/Controllers/TestController.cs b/Jellyfin.Api/Controllers/TestController.cs index b76895696a..a960bb24f5 100644 --- a/Jellyfin.Api/Controllers/TestController.cs +++ b/Jellyfin.Api/Controllers/TestController.cs @@ -26,7 +26,7 @@ namespace Jellyfin.Api.Controllers /// Parameters to echo back in the response. /// An . /// Information retrieved. - [HttpGet("Decoding", Name = "TestUrlDecoding")] + [HttpGet("UrlDecode")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult TestUrlDecoding([FromQuery]Dictionary? @params = null) { From 4c8cfaa61c513e51aab4440244a067ca39175dd5 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 7 May 2021 18:51:15 +0100 Subject: [PATCH 10/29] Update Jellyfin.Api/Controllers/TestController.cs Co-authored-by: Cody Robibero --- Jellyfin.Api/Controllers/TestController.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jellyfin.Api/Controllers/TestController.cs b/Jellyfin.Api/Controllers/TestController.cs index a960bb24f5..1685045750 100644 --- a/Jellyfin.Api/Controllers/TestController.cs +++ b/Jellyfin.Api/Controllers/TestController.cs @@ -10,8 +10,7 @@ namespace Jellyfin.Api.Controllers /// /// Controller for testing. /// - [Route("Tests")] - public class TestController : BaseJellyfinApiController + public class TestsController : BaseJellyfinApiController { /// /// Initializes a new instance of the class. From 8b34f76b63dca54d59b4f3db2f5b485c32bd8e36 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 7 May 2021 18:51:31 +0100 Subject: [PATCH 11/29] Update Jellyfin.Api/Controllers/TestController.cs Co-authored-by: Cody Robibero --- Jellyfin.Api/Controllers/TestController.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Jellyfin.Api/Controllers/TestController.cs b/Jellyfin.Api/Controllers/TestController.cs index 1685045750..487a99fcbd 100644 --- a/Jellyfin.Api/Controllers/TestController.cs +++ b/Jellyfin.Api/Controllers/TestController.cs @@ -12,13 +12,6 @@ namespace Jellyfin.Api.Controllers /// public class TestsController : BaseJellyfinApiController { - /// - /// Initializes a new instance of the class. - /// - public TestController() - { - } - /// /// Tests the url decoding. /// From dca02987106d0433ee4139fb380dd78d92921dae Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 7 May 2021 20:11:32 +0100 Subject: [PATCH 12/29] changed --- .../{TestController.cs => TestsController.cs} | 14 ++++++++------ .../Controllers/EncodedQueryStringTest.cs | 6 ++++-- 2 files changed, 12 insertions(+), 8 deletions(-) rename Jellyfin.Api/Controllers/{TestController.cs => TestsController.cs} (64%) diff --git a/Jellyfin.Api/Controllers/TestController.cs b/Jellyfin.Api/Controllers/TestsController.cs similarity index 64% rename from Jellyfin.Api/Controllers/TestController.cs rename to Jellyfin.Api/Controllers/TestsController.cs index 487a99fcbd..1d1e1899fd 100644 --- a/Jellyfin.Api/Controllers/TestController.cs +++ b/Jellyfin.Api/Controllers/TestsController.cs @@ -20,14 +20,16 @@ namespace Jellyfin.Api.Controllers /// Information retrieved. [HttpGet("UrlDecode")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult TestUrlDecoding([FromQuery]Dictionary? @params = null) + public ContentResult TestUrlDecoding([FromQuery]Dictionary? @params = null) { - if (@params != null && @params.Count > 0) + return new ContentResult() { - Response.Headers.Add("querystring", string.Join("&", @params.Select(x => x.Key + "=" + x.Value))); - } - - return Ok(); + Content = (@params != null && @params.Count > 0) + ? string.Join("&", @params.Select(x => x.Key + "=" + x.Value)) + : string.Empty, + ContentType = "text/plain; charset=utf-8", + StatusCode = 200 + }; } } } diff --git a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs index 80175039ea..d6a423dcdd 100644 --- a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs +++ b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using System.Linq; using System.Net; @@ -29,9 +30,10 @@ namespace Jellyfin.Api.Tests.Controllers { var client = _factory.CreateClient(); - var response = await client.GetAsync("Tests/Decoding?" + sourceUrl).ConfigureAwait(false); + var response = await client.GetAsync("Tests/UrlDecode?" + sourceUrl).ConfigureAwait(false); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.Equal(unencodedUrl, response.Headers.GetValues("querystring").First()); + string reply = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + Assert.Equal(unencodedUrl, reply); } } } From bd71de131c384765b9240b7a54649e2c9258b133 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sat, 8 May 2021 12:52:25 +0100 Subject: [PATCH 13/29] Changed to use span --- .../Middleware/UrlDecodeQueryFeature.cs | 21 ++++++++++++------- .../Jellyfin.Api.Tests.csproj | 1 + ...llyfin.Server.Implementations.Tests.csproj | 1 + .../Middleware}/EncodedQueryStringTest.cs | 3 ++- 4 files changed, 17 insertions(+), 9 deletions(-) rename tests/{Jellyfin.Api.Tests/Controllers => Jellyfin.Server.Implementations.Tests/Middleware}/EncodedQueryStringTest.cs (93%) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index 44b30baac0..c89a318e16 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using MediaBrowser.Common.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.Primitives; @@ -61,19 +62,23 @@ namespace Jellyfin.Server.Middleware } var pairs = new Dictionary(); - var queryString = unencodedKey.Split('&', System.StringSplitOptions.RemoveEmptyEntries); + var queryString = unencodedKey.SpanSplit('&'); foreach (var pair in queryString) { - var item = pair.Split('=', System.StringSplitOptions.RemoveEmptyEntries); - if (item.Length > 0) + var item = pair.Split('='); + item.MoveNext(); + + var key = item.Current; + var val = item.MoveNext() ? item.Current : string.Empty; + if (key.Length == 0 && val.Length == 0) { - pairs.Add(item[0], new StringValues(item.Length == 2 ? item[1] : string.Empty)); - } - else - { - pairs.Add(pair, string.Empty); + // encoded is an equals. + pairs.Add(pair.ToString(), new StringValues(string.Empty)); + continue; } + + pairs.Add(key.ToString(), new StringValues(val.ToString())); } _store = new QueryCollection(pairs); diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 397b863b70..e3577caeee 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -37,6 +37,7 @@ + diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index 27713d58a3..ccc18d6869 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -42,6 +42,7 @@ + diff --git a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs similarity index 93% rename from tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs rename to tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs index d6a423dcdd..e5865fb5ac 100644 --- a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs @@ -5,9 +5,10 @@ using System.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; +using Jellyfin.Server.Integration.Tests; using Xunit; -namespace Jellyfin.Api.Tests.Controllers +namespace Jellyfin.Server.Implementations.Tests.Middleware { /// /// Defines the test for encoded querystrings in the url. From cb74a8697554008d37ae9359794b132c4945746b Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sat, 8 May 2021 13:33:47 +0100 Subject: [PATCH 14/29] Moved test --- .../EncodedQueryStringTest.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) rename tests/{Jellyfin.Server.Implementations.Tests/Middleware => Jellyfin.Server.Integration.Tests}/EncodedQueryStringTest.cs (87%) diff --git a/tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs b/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs similarity index 87% rename from tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs rename to tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs index e5865fb5ac..a89d6e86f7 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs +++ b/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs @@ -1,14 +1,8 @@ -using System; -using System.IO; -using System.Linq; using System.Net; -using System.Net.Http; -using System.Text; using System.Threading.Tasks; -using Jellyfin.Server.Integration.Tests; using Xunit; -namespace Jellyfin.Server.Implementations.Tests.Middleware +namespace Jellyfin.Server.Integration.Tests { /// /// Defines the test for encoded querystrings in the url. From 903bf2a086c49266c010f947180bd660b2c58931 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sat, 8 May 2021 16:00:41 +0100 Subject: [PATCH 15/29] changed to use index --- Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index c89a318e16..dd05f7bc5c 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -66,19 +66,17 @@ namespace Jellyfin.Server.Middleware foreach (var pair in queryString) { - var item = pair.Split('='); - item.MoveNext(); + var section = pair.ToString(); + var i = section.IndexOf('=', System.StringComparison.Ordinal); - var key = item.Current; - var val = item.MoveNext() ? item.Current : string.Empty; - if (key.Length == 0 && val.Length == 0) + if (i == -1) { // encoded is an equals. - pairs.Add(pair.ToString(), new StringValues(string.Empty)); + pairs.Add(section, new StringValues(string.Empty)); continue; } - pairs.Add(key.ToString(), new StringValues(val.ToString())); + pairs.Add(section[0..i], new StringValues(section[(i + 1)..])); } _store = new QueryCollection(pairs); From 85ecea77221ff6dfda73a7b75efb5d29f2e3cc96 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 11 May 2021 21:45:15 +0100 Subject: [PATCH 16/29] corrected tests --- .../Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs b/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs index a89d6e86f7..0d1e408c85 100644 --- a/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs +++ b/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs @@ -19,7 +19,6 @@ namespace Jellyfin.Server.Integration.Tests [Theory] [InlineData("a=1&b=2&c=3", "a=1&b=2&c=3")] // won't be processed as there is more than 1. [InlineData("a=1", "a=1")] // won't be processed as it has a value - [InlineData("%3D", "==")] // will decode with an empty string value '=' = ''. [InlineData("a%3D1%26b%3D2%26c%3D3", "a=1&b=2&c=3")] // will be processed. public async Task Ensure_Decoding_Of_Urls_Is_Working(string sourceUrl, string unencodedUrl) { From d0bfb56d2ef0607b10d83706f7ec76fc16bb4cf9 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 12 May 2021 16:19:08 +0100 Subject: [PATCH 17/29] changed to slice. --- Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index dd05f7bc5c..7d2c30b9db 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Web; @@ -66,17 +67,16 @@ namespace Jellyfin.Server.Middleware foreach (var pair in queryString) { - var section = pair.ToString(); - var i = section.IndexOf('=', System.StringComparison.Ordinal); + var i = pair.IndexOf('='); if (i == -1) { // encoded is an equals. - pairs.Add(section, new StringValues(string.Empty)); + pairs.Add(pair[0..i].ToString(), new StringValues(string.Empty)); continue; } - pairs.Add(section[0..i], new StringValues(section[(i + 1)..])); + pairs.Add(pair[0..i].ToString(), new StringValues(pair[(i + 1)..].ToString())); } _store = new QueryCollection(pairs); From 53bfe0e77de6b3d9e8bb4b9740c8fbe009b145c5 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sat, 15 May 2021 20:24:41 +0100 Subject: [PATCH 18/29] Changes as requested --- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 3 +-- .../Controllers/EncoderController.cs | 6 +++--- .../EncodedQueryStringTest.cs | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) rename Jellyfin.Api/Controllers/TestsController.cs => tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs (87%) diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index e3577caeee..806e4ea1d0 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -36,8 +36,7 @@ - - + diff --git a/Jellyfin.Api/Controllers/TestsController.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs similarity index 87% rename from Jellyfin.Api/Controllers/TestsController.cs rename to tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs index 1d1e1899fd..98ea00de6a 100644 --- a/Jellyfin.Api/Controllers/TestsController.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Jellyfin.Api.Constants; using Microsoft.AspNetCore.Authorization; @@ -8,9 +8,9 @@ using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api.Controllers { /// - /// Controller for testing. + /// Controller for testing the encoded url. /// - public class TestsController : BaseJellyfinApiController + public class EncoderController : BaseJellyfinApiController { /// /// Tests the url decoding. diff --git a/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs b/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs index 0d1e408c85..29d3fe33d0 100644 --- a/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs +++ b/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs @@ -24,7 +24,7 @@ namespace Jellyfin.Server.Integration.Tests { var client = _factory.CreateClient(); - var response = await client.GetAsync("Tests/UrlDecode?" + sourceUrl).ConfigureAwait(false); + var response = await client.GetAsync("Encoder/UrlDecode?" + sourceUrl).ConfigureAwait(false); Assert.Equal(HttpStatusCode.OK, response.StatusCode); string reply = await response.Content.ReadAsStringAsync().ConfigureAwait(false); Assert.Equal(unencodedUrl, reply); From 8a58d552a69a9a4078c9923519b8e66fcf2d6c5e Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Tue, 25 May 2021 00:35:16 +0200 Subject: [PATCH 19/29] Update tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj --- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 806e4ea1d0..397b863b70 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -36,7 +36,7 @@ - + From b59e81dcdfb18d2d9585b0a4d6a433d76b879c66 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:20:37 +0100 Subject: [PATCH 20/29] Update Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs Co-authored-by: Claus Vium --- Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs index 08fbbce0b2..ab3355e6aa 100644 --- a/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs +++ b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs @@ -1,4 +1,3 @@ -using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; From cc2166550f727efedb0a4775a7275f2e4973616a Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:20:44 +0100 Subject: [PATCH 21/29] Update Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs Co-authored-by: Claus Vium --- Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs index ab3355e6aa..fd0ebbf438 100644 --- a/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs +++ b/Jellyfin.Server/Middleware/QueryStringDecodingMiddleware.cs @@ -1,7 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; -using Microsoft.Extensions.Logging; namespace Jellyfin.Server.Middleware { From e1a0b5d2a14d901f277d9179b23efbea3eba0f3a Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:21:15 +0100 Subject: [PATCH 22/29] Update Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs Co-authored-by: Claus Vium --- Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index 7d2c30b9db..987c66da79 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -72,7 +72,7 @@ namespace Jellyfin.Server.Middleware if (i == -1) { // encoded is an equals. - pairs.Add(pair[0..i].ToString(), new StringValues(string.Empty)); + pairs.Add(pair[..i].ToString(), StringValues.Empty); continue; } From e71c10df46f80085bcae98dba821785f0cc6351a Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:21:22 +0100 Subject: [PATCH 23/29] Update tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs Co-authored-by: Claus Vium --- .../Controllers/EncoderController.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs index 98ea00de6a..be9c138902 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs @@ -1,7 +1,5 @@ using System.Collections.Generic; using System.Linq; -using Jellyfin.Api.Constants; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; From 133ce65e2892ef0f5628c3dad7a0f49f4558812a Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:21:30 +0100 Subject: [PATCH 24/29] Update tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs Co-authored-by: Claus Vium --- .../Controllers/EncoderController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs index be9c138902..14f92f0d82 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/EncoderController.cs @@ -18,7 +18,7 @@ namespace Jellyfin.Api.Controllers /// Information retrieved. [HttpGet("UrlDecode")] [ProducesResponseType(StatusCodes.Status200OK)] - public ContentResult TestUrlDecoding([FromQuery]Dictionary? @params = null) + public ContentResult TestUrlDecoding([FromQuery] Dictionary? @params = null) { return new ContentResult() { From 371f8629b1be0f54e8703470b34a29ab2fb36d8c Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:21:47 +0100 Subject: [PATCH 25/29] Update Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs Co-authored-by: Claus Vium --- Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index 987c66da79..bcc79a5f29 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -76,7 +76,7 @@ namespace Jellyfin.Server.Middleware continue; } - pairs.Add(pair[0..i].ToString(), new StringValues(pair[(i + 1)..].ToString())); + pairs.Add(pair[..i].ToString(), new StringValues(pair[(i + 1)..].ToString())); } _store = new QueryCollection(pairs); From c1fa7cbbf824796e0aa2b143edba88da77235828 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:22:11 +0100 Subject: [PATCH 26/29] Update Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs Co-authored-by: Claus Vium --- Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index bcc79a5f29..890947ba08 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -45,7 +45,7 @@ namespace Jellyfin.Server.Middleware } // Encoded querystrings have no value, so don't process anything if a value is present. - var kvp = value.First(); + var (key, stringValues) = value.First(); if (!string.IsNullOrEmpty(kvp.Value)) { _store = value; From ada052fcb1f37c0253dcc3fa0edbb81c630169c5 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:22:17 +0100 Subject: [PATCH 27/29] Update Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs Co-authored-by: Claus Vium --- Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index 890947ba08..91d2ce124b 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -53,7 +53,7 @@ namespace Jellyfin.Server.Middleware } // Unencode and re-parse querystring. - var unencodedKey = HttpUtility.UrlDecode(kvp.Key); + var unencodedKey = HttpUtility.UrlDecode(key); if (string.Equals(unencodedKey, kvp.Key, System.StringComparison.Ordinal)) { From 37326a80993346c66e2f562677bf9ccd43d581b5 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:22:28 +0100 Subject: [PATCH 28/29] Update Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs Co-authored-by: Claus Vium --- Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index 91d2ce124b..b3b3b391e7 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -55,7 +55,7 @@ namespace Jellyfin.Server.Middleware // Unencode and re-parse querystring. var unencodedKey = HttpUtility.UrlDecode(key); - if (string.Equals(unencodedKey, kvp.Key, System.StringComparison.Ordinal)) + if (string.Equals(unencodedKey, key, System.StringComparison.Ordinal)) { // Don't do anything if it's not encoded. _store = value; From 147612f59bb5870f04197087e3d5fcd954061471 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 7 Jun 2021 16:22:37 +0100 Subject: [PATCH 29/29] Update Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs Co-authored-by: Claus Vium --- Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index b3b3b391e7..804e58b5ac 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -46,7 +46,7 @@ namespace Jellyfin.Server.Middleware // Encoded querystrings have no value, so don't process anything if a value is present. var (key, stringValues) = value.First(); - if (!string.IsNullOrEmpty(kvp.Value)) + if (!string.IsNullOrEmpty(stringValues)) { _store = value; return;