using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Net; using MediaBrowser.Model.Dto; using Microsoft.AspNetCore.Http; namespace MediaBrowser.Model.Services { // Remove this garbage class, it's just a bastard copy of NameValueCollection public class QueryParamCollection : List { public QueryParamCollection() { } public QueryParamCollection(IDictionary headers) { foreach (var pair in headers) { Add(pair.Key, pair.Value); } } public QueryParamCollection(Microsoft.AspNetCore.Http.IHeaderDictionary headers) { foreach (var pair in headers) { Add(pair.Key, pair.Value); } } // TODO remove this shit public QueryParamCollection(WebHeaderCollection webHeaderCollection) { foreach (var key in webHeaderCollection.AllKeys) { foreach (var value in webHeaderCollection.GetValues(key) ?? Array.Empty()) { Add(key, value); } } } // TODO remove this shit public QueryParamCollection(NameValueCollection nameValueCollection) { foreach (var key in nameValueCollection.AllKeys) { foreach (var value in nameValueCollection.GetValues(key) ?? Array.Empty()) { Add(key, value); } } } public QueryParamCollection(IQueryCollection queryCollection) { foreach (var pair in queryCollection) { Add(pair.Key, pair.Value); } } private static StringComparison GetStringComparison() { return StringComparison.OrdinalIgnoreCase; } private static StringComparer GetStringComparer() { return StringComparer.OrdinalIgnoreCase; } public string GetKey(int index) { return this[index].Name; } public string Get(int index) { return this[index].Value; } public virtual string[] GetValues(int index) { return new[] { Get(index) }; } /// /// Adds a new query parameter. /// public virtual void Add(string key, string value) { if (string.Equals(key, "content-length", StringComparison.OrdinalIgnoreCase)) { return; } Add(new NameValuePair(key, value)); } public virtual void Set(string key, string value) { if (string.IsNullOrEmpty(value)) { var parameters = GetItems(key); foreach (var p in parameters) { Remove(p); } return; } foreach (var pair in this) { var stringComparison = GetStringComparison(); if (string.Equals(key, pair.Name, stringComparison)) { pair.Value = value; return; } } Add(key, value); } /// /// Removes all parameters of the given name. /// /// The number of parameters that were removed /// is null. public virtual int Remove(string name) { return RemoveAll(p => p.Name == name); } public string Get(string name) { var stringComparison = GetStringComparison(); foreach (var pair in this) { if (string.Equals(pair.Name, name, stringComparison)) { return pair.Value; } } return null; } public virtual List GetItems(string name) { var stringComparison = GetStringComparison(); var list = new List(); foreach (var pair in this) { if (string.Equals(pair.Name, name, stringComparison)) { list.Add(pair); } } return list; } public virtual List GetValues(string name) { var stringComparison = GetStringComparison(); var list = new List(); foreach (var pair in this) { if (string.Equals(pair.Name, name, stringComparison)) { list.Add(pair.Value); } } return list; } public Dictionary ToDictionary() { var stringComparer = GetStringComparer(); var headers = new Dictionary(stringComparer); foreach (var pair in this) { headers[pair.Name] = pair.Value; } return headers; } public IEnumerable Keys { get { var keys = new string[this.Count]; for (var i = 0; i < keys.Length; i++) { keys[i] = this[i].Name; } return keys; } } /// /// Gets or sets a query parameter value by name. A query may contain multiple values of the same name /// (i.e. "x=1&x=2"), in which case the value is an array, which works for both getting and setting. /// /// The query parameter name /// The query parameter value or array of values public string this[string name] { get => Get(name); set => Set(name, value); } private string GetQueryStringValue(NameValuePair pair) { return pair.Name + "=" + pair.Value; } public override string ToString() { var vals = this.Select(GetQueryStringValue).ToArray(); return string.Join("&", vals); } } }