|  | @@ -5,7 +5,6 @@ using System.Collections.Generic;
 | 
	
		
			
				|  |  |  using System.Linq;
 | 
	
		
			
				|  |  |  using System.Net;
 | 
	
		
			
				|  |  |  using System.Threading.Tasks;
 | 
	
		
			
				|  |  | -using Jellyfin.Extensions;
 | 
	
		
			
				|  |  |  using MediaBrowser.Controller.Library;
 | 
	
		
			
				|  |  |  using MediaBrowser.Controller.Net;
 | 
	
		
			
				|  |  |  using Microsoft.AspNetCore.Http;
 | 
	
	
		
			
				|  | @@ -253,29 +252,57 @@ namespace Jellyfin.Server.Implementations.Security
 | 
	
		
			
				|  |  |                  return null;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            // Remove up until the first space
 | 
	
		
			
				|  |  |              authorizationHeader = authorizationHeader[(firstSpace + 1)..];
 | 
	
		
			
				|  |  | +            return GetParts(authorizationHeader);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 | 
	
		
			
				|  |  | +        /// <summary>
 | 
	
		
			
				|  |  | +        /// Get the authorization header components.
 | 
	
		
			
				|  |  | +        /// </summary>
 | 
	
		
			
				|  |  | +        /// <param name="authorizationHeader">The authorization header.</param>
 | 
	
		
			
				|  |  | +        /// <returns>Dictionary{System.StringSystem.String}.</returns>
 | 
	
		
			
				|  |  | +        public static Dictionary<string, string> GetParts(ReadOnlySpan<char> authorizationHeader)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            var result = new Dictionary<string, string>();
 | 
	
		
			
				|  |  | +            var escaped = false;
 | 
	
		
			
				|  |  | +            int start = 0;
 | 
	
		
			
				|  |  | +            string key = string.Empty;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            foreach (var item in authorizationHeader.Split(','))
 | 
	
		
			
				|  |  | +            int i;
 | 
	
		
			
				|  |  | +            for (i = 0; i < authorizationHeader.Length; i++)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                var trimmedItem = item.Trim();
 | 
	
		
			
				|  |  | -                var firstEqualsSign = trimmedItem.IndexOf('=');
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                if (firstEqualsSign > 0)
 | 
	
		
			
				|  |  | +                var token = authorizationHeader[i];
 | 
	
		
			
				|  |  | +                if (token == '"' || token == ',')
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -                    var key = trimmedItem[..firstEqualsSign].ToString();
 | 
	
		
			
				|  |  | -                    var value = NormalizeValue(trimmedItem[(firstEqualsSign + 1)..].Trim('"').ToString());
 | 
	
		
			
				|  |  | -                    result[key] = value;
 | 
	
		
			
				|  |  | +                    // Applying a XOR logic to evaluate whether it is opening or closing a value
 | 
	
		
			
				|  |  | +                    escaped = (!escaped) == (token == '"');
 | 
	
		
			
				|  |  | +                    if (token == ',' && !escaped)
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        // Meeting a comma after a closing escape char means the value is complete
 | 
	
		
			
				|  |  | +                        if (start < i)
 | 
	
		
			
				|  |  | +                        {
 | 
	
		
			
				|  |  | +                            result[key] = WebUtility.UrlDecode(authorizationHeader[start..i].Trim('"').ToString());
 | 
	
		
			
				|  |  | +                            key = string.Empty;
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        start = i + 1;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else if (!escaped && token == '=')
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    key = authorizationHeader[start.. i].Trim().ToString();
 | 
	
		
			
				|  |  | +                    start = i + 1;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            return result;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +            // Add last value
 | 
	
		
			
				|  |  | +            if (start < i)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                result[key] = WebUtility.UrlDecode(authorizationHeader[start..i].Trim('"').ToString());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private static string NormalizeValue(string value)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            return string.IsNullOrEmpty(value) ? value : WebUtility.HtmlEncode(value);
 | 
	
		
			
				|  |  | +            return result;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |