diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs index f07fdbd72a6c04..addd5ae321d040 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Globalization; -using System.IO; using System.Text; namespace System.Net.Http.Headers @@ -22,9 +21,6 @@ internal static class HeaderUtilities internal const string BytesUnit = "bytes"; - // Validator - internal static readonly Action, string> TokenValidator = ValidateToken; - internal static void SetQuality(UnvalidatedObjectCollection parameters, double? value) { Debug.Assert(parameters != null); @@ -372,11 +368,6 @@ internal static void DumpHeaders(StringBuilder sb, params HttpHeaders?[] headers sb.Append('}'); } - private static void ValidateToken(HttpHeaderValueCollection collection, string value) - { - CheckValidToken(value, "item"); - } - internal static UnvalidatedObjectCollection? Clone(this UnvalidatedObjectCollection? source) { if (source == null) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs index 92a88c22a3edfd..bae8addd668fec 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs @@ -22,8 +22,7 @@ public ICollection Allow { if (_allow == null) { - _allow = new HttpHeaderValueCollection(KnownHeaders.Allow.Descriptor, - this, HeaderUtilities.TokenValidator); + _allow = new HttpHeaderValueCollection(KnownHeaders.Allow.Descriptor, this); } return _allow; } @@ -43,8 +42,7 @@ public ICollection ContentEncoding { if (_contentEncoding == null) { - _contentEncoding = new HttpHeaderValueCollection(KnownHeaders.ContentEncoding.Descriptor, - this, HeaderUtilities.TokenValidator); + _contentEncoding = new HttpHeaderValueCollection(KnownHeaders.ContentEncoding.Descriptor, this); } return _contentEncoding; } @@ -56,8 +54,7 @@ public ICollection ContentLanguage { if (_contentLanguage == null) { - _contentLanguage = new HttpHeaderValueCollection(KnownHeaders.ContentLanguage.Descriptor, - this, HeaderUtilities.TokenValidator); + _contentLanguage = new HttpHeaderValueCollection(KnownHeaders.ContentLanguage.Descriptor, this); } return _contentLanguage; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs index 0acffa6098ac80..b5fae3e1eec5ea 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs @@ -27,11 +27,6 @@ public CacheControlHeaderValue? CacheControl set { _parent.SetOrRemoveParsedValue(KnownHeaders.CacheControl.Descriptor, value); } } - public HttpHeaderValueCollection Connection - { - get { return ConnectionCore; } - } - public bool? ConnectionClose { get @@ -46,30 +41,23 @@ public bool? ConnectionClose if (value == true) { _connectionCloseSet = true; - ConnectionCore.SetSpecialValue(); + if (!_parent.ContainsParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose)) + { + _parent.AddParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose); + } } else { _connectionCloseSet = value != null; - ConnectionCore.RemoveSpecialValue(); + // We intentionally ignore the return value. It's OK if "close" wasn't in the store. + _parent.RemoveParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose); } } } internal static bool? GetConnectionClose(HttpHeaders parent, HttpGeneralHeaders? headers) { - // If we've already initialized the connection header value collection - // and it contains the special value, or if we haven't and the headers contain - // the parsed special value, return true. We don't just access ConnectionCore, - // as doing so will unnecessarily initialize the collection even if it's not needed. - if (headers?._connection != null) - { - if (headers._connection.IsSpecialValueSet) - { - return true; - } - } - else if (parent.ContainsParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose)) + if (parent.ContainsParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose)) { return true; } @@ -104,32 +92,15 @@ public HttpHeaderValueCollection Trailer { if (_trailer == null) { - _trailer = new HttpHeaderValueCollection(KnownHeaders.Trailer.Descriptor, - _parent, HeaderUtilities.TokenValidator); + _trailer = new HttpHeaderValueCollection(KnownHeaders.Trailer.Descriptor, _parent); } return _trailer; } } - public HttpHeaderValueCollection TransferEncoding - { - get { return TransferEncodingCore; } - } - internal static bool? GetTransferEncodingChunked(HttpHeaders parent, HttpGeneralHeaders? headers) { - // If we've already initialized the transfer encoding header value collection - // and it contains the special value, or if we haven't and the headers contain - // the parsed special value, return true. We don't just access TransferEncodingCore, - // as doing so will unnecessarily initialize the collection even if it's not needed. - if (headers?._transferEncoding != null) - { - if (headers._transferEncoding.IsSpecialValueSet) - { - return true; - } - } - else if (parent.ContainsParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked)) + if (parent.ContainsParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked)) { return true; } @@ -154,12 +125,16 @@ public bool? TransferEncodingChunked if (value == true) { _transferEncodingChunkedSet = true; - TransferEncodingCore.SetSpecialValue(); + if (!_parent.ContainsParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked)) + { + _parent.AddParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked); + } } else { _transferEncodingChunkedSet = value != null; - TransferEncodingCore.RemoveSpecialValue(); + // We intentionally ignore the return value. It's OK if "chunked" wasn't in the store. + _parent.RemoveParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked); } } } @@ -200,27 +175,25 @@ public HttpHeaderValueCollection Warning } } - private HttpHeaderValueCollection ConnectionCore + public HttpHeaderValueCollection Connection { get { if (_connection == null) { - _connection = new HttpHeaderValueCollection(KnownHeaders.Connection.Descriptor, - _parent, HeaderUtilities.ConnectionClose, HeaderUtilities.TokenValidator); + _connection = new HttpHeaderValueCollection(KnownHeaders.Connection.Descriptor, _parent); } return _connection; } } - private HttpHeaderValueCollection TransferEncodingCore + public HttpHeaderValueCollection TransferEncoding { get { if (_transferEncoding == null) { - _transferEncoding = new HttpHeaderValueCollection( - KnownHeaders.TransferEncoding.Descriptor, _parent, HeaderUtilities.TransferEncodingChunked); + _transferEncoding = new HttpHeaderValueCollection(KnownHeaders.TransferEncoding.Descriptor, _parent); } return _transferEncoding; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs index 68ba04e5b67815..97c458a6d6b855 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -35,8 +34,6 @@ public sealed class HttpHeaderValueCollection : ICollection where T : clas { private readonly HeaderDescriptor _descriptor; private readonly HttpHeaders _store; - private readonly T? _specialValue; - private readonly Action, T>? _validator; public int Count { @@ -48,45 +45,10 @@ public bool IsReadOnly get { return false; } } - internal bool IsSpecialValueSet - { - get - { - // If this collection instance has a "special value", then check whether that value was already set. - if (_specialValue == null) - { - return false; - } - return _store.ContainsParsedValue(_descriptor, _specialValue); - } - } - internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store) - : this(descriptor, store, null, null) { - } - - internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store, - Action, T> validator) - : this(descriptor, store, null, validator) - { - } - - internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store, T specialValue) - : this(descriptor, store, specialValue, null) - { - } - - internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store, T? specialValue, - Action, T>? validator) - { - Debug.Assert(descriptor.Name != null); - Debug.Assert(store != null); - _store = store; _descriptor = descriptor; - _specialValue = specialValue; - _validator = validator; } public void Add(T item) @@ -204,27 +166,6 @@ public override string ToString() return _store.GetHeaderString(_descriptor); } - internal void SetSpecialValue() - { - Debug.Assert(_specialValue != null, - "This method can only be used if the collection has a 'special value' set."); - - if (!_store.ContainsParsedValue(_descriptor, _specialValue)) - { - _store.AddParsedValue(_descriptor, _specialValue); - } - } - - internal void RemoveSpecialValue() - { - Debug.Assert(_specialValue != null, - "This method can only be used if the collection has a 'special value' set."); - - // We're not interested in the return value. It's OK if the "special value" wasn't in the store - // before calling RemoveParsedValue(). - _store.RemoveParsedValue(_descriptor, _specialValue); - } - private void CheckValue(T item) { if (item == null) @@ -232,10 +173,13 @@ private void CheckValue(T item) throw new ArgumentNullException(nameof(item)); } - // If this instance has a custom validator for validating arguments, call it now. - if (_validator != null) + if (_descriptor.Parser == GenericHeaderParser.TokenListParser) { - _validator(this, item); + // The collection expects valid HTTP tokens, which are typed as string. + // Unlike other parsed values (which are always valid by construction), + // we can't assume the provided string is a valid token. So validate it before we use it. + Debug.Assert(typeof(T) == typeof(string)); + HeaderUtilities.CheckValidToken((string)(object)item, nameof(item)); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs index 1731a954bf0a8d..684728b19c55ba 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs @@ -51,26 +51,17 @@ public AuthenticationHeaderValue? Authorization set { SetOrRemoveParsedValue(KnownHeaders.Authorization.Descriptor, value); } } - public HttpHeaderValueCollection Expect - { - get { return ExpectCore; } - } - public bool? ExpectContinue { get { - // ExpectCore will force the collection into existence, so avoid accessing it if possible. - if (_expectContinueSet || ContainsParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue)) + if (ContainsParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue)) { - if (ExpectCore.IsSpecialValueSet) - { - return true; - } - if (_expectContinueSet) - { - return false; - } + return true; + } + if (_expectContinueSet) + { + return false; } return null; @@ -80,12 +71,16 @@ public bool? ExpectContinue if (value == true) { _expectContinueSet = true; - ExpectCore.SetSpecialValue(); + if (!ContainsParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue)) + { + AddParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue); + } } else { _expectContinueSet = value != null; - ExpectCore.RemoveSpecialValue(); + // We intentionally ignore the return value. It's OK if "100-continue" wasn't in the store. + RemoveParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue); } } } @@ -189,8 +184,8 @@ public Uri? Referrer public HttpHeaderValueCollection UserAgent => GetSpecializedCollection(UserAgentSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.UserAgent.Descriptor, thisRef)); - private HttpHeaderValueCollection ExpectCore => - _expect ??= new HttpHeaderValueCollection(KnownHeaders.Expect.Descriptor, this, HeaderUtilities.ExpectContinue); + public HttpHeaderValueCollection Expect => + _expect ??= new HttpHeaderValueCollection(KnownHeaders.Expect.Descriptor, this); #endregion diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs index 2c03f00acf7972..442db3beb2f49b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs @@ -35,7 +35,7 @@ private T GetSpecializedCollection(int slot, Func cre } public HttpHeaderValueCollection AcceptRanges => - GetSpecializedCollection(AcceptRangesSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptRanges.Descriptor, thisRef, HeaderUtilities.TokenValidator)); + GetSpecializedCollection(AcceptRangesSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptRanges.Descriptor, thisRef)); public TimeSpan? Age { @@ -68,7 +68,7 @@ public RetryConditionHeaderValue? RetryAfter GetSpecializedCollection(ServerSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.Server.Descriptor, thisRef)); public HttpHeaderValueCollection Vary => - GetSpecializedCollection(VarySlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.Vary.Descriptor, thisRef, HeaderUtilities.TokenValidator)); + GetSpecializedCollection(VarySlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.Vary.Descriptor, thisRef)); public HttpHeaderValueCollection WwwAuthenticate => GetSpecializedCollection(WwwAuthenticateSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.WWWAuthenticate.Descriptor, thisRef)); diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeaderValueCollectionTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeaderValueCollectionTest.cs index cab7599b16ea95..dec7eb661f7cf6 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeaderValueCollectionTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeaderValueCollectionTest.cs @@ -1,12 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Net.Http.Headers; -using System.Text; using Xunit; @@ -18,8 +16,6 @@ public class HttpHeaderValueCollectionTest private static readonly HeaderDescriptor knownStringHeader = (new KnownHeader("known-string-header", HttpHeaderType.General, new MockHeaderParser(typeof(string)))).Descriptor; private static readonly HeaderDescriptor knownUriHeader = (new KnownHeader("known-uri-header", HttpHeaderType.General, new MockHeaderParser(typeof(Uri)))).Descriptor; - private static readonly Uri specialValue = new Uri("http://special/"); - private static readonly Uri invalidValue = new Uri("http://invalid/"); private static readonly TransferCodingHeaderValue specialChunked = new TransferCodingHeaderValue("chunked"); // Note that this type just forwards calls to HttpHeaders. So this test method focuses on making sure @@ -34,45 +30,6 @@ public void IsReadOnly_CallProperty_AlwaysFalse() Assert.False(collection.IsReadOnly); } - [Fact] - public void Count_AddSingleValueThenQueryCount_ReturnsValueCountWithSpecialValues() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownStringHeader, headers, - "special"); - - Assert.Equal(0, collection.Count); - - headers.Add(knownStringHeader, "value2"); - Assert.Equal(1, collection.Count); - - headers.Clear(); - headers.Add(knownStringHeader, "special"); - Assert.Equal(1, collection.Count); - headers.Add(knownStringHeader, "special"); - headers.Add(knownStringHeader, "special"); - Assert.Equal(3, collection.Count); - } - - [Fact] - public void Count_AddMultipleValuesThenQueryCount_ReturnsValueCountWithSpecialValues() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownStringHeader, headers, - "special"); - - Assert.Equal(0, collection.Count); - - collection.Add("value1"); - headers.Add(knownStringHeader, "special"); - Assert.Equal(2, collection.Count); - - headers.Add(knownStringHeader, "special"); - headers.Add(knownStringHeader, "value2"); - headers.Add(knownStringHeader, "special"); - Assert.Equal(5, collection.Count); - } - [Fact] public void Add_CallWithNullValue_Throw() { @@ -86,8 +43,7 @@ public void Add_CallWithNullValue_Throw() public void Add_AddValues_AllValuesAdded() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); collection.Add(new Uri("http://www.example.org/1/")); collection.Add(new Uri("http://www.example.org/2/")); @@ -150,7 +106,6 @@ public void ParseAdd_CallWithNullValue_NothingAdded() HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); collection.ParseAdd(null); - Assert.False(collection.IsSpecialValueSet); Assert.Equal(0, collection.Count); Assert.Equal(string.Empty, collection.ToString()); } @@ -159,8 +114,7 @@ public void ParseAdd_CallWithNullValue_NothingAdded() public void ParseAdd_AddValues_AllValuesAdded() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); collection.ParseAdd("http://www.example.org/1/"); collection.ParseAdd("http://www.example.org/2/"); @@ -169,19 +123,6 @@ public void ParseAdd_AddValues_AllValuesAdded() Assert.Equal(3, collection.Count); } - [Fact] - public void ParseAdd_UseSpecialValue_Added() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.ParseAdd(specialValue.AbsoluteUri); - - Assert.True(collection.IsSpecialValueSet); - Assert.Equal(specialValue.ToString(), collection.ToString()); - } - [Fact] public void ParseAdd_AddBadValue_Throws() { @@ -198,7 +139,6 @@ public void TryParseAdd_CallWithNullValue_NothingAdded() Assert.True(headers.WwwAuthenticate.TryParseAdd(null)); - Assert.False(headers.WwwAuthenticate.IsSpecialValueSet); Assert.Equal(0, headers.WwwAuthenticate.Count); Assert.Equal(string.Empty, headers.WwwAuthenticate.ToString()); } @@ -207,8 +147,7 @@ public void TryParseAdd_CallWithNullValue_NothingAdded() public void TryParseAdd_AddValues_AllAdded() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); Assert.True(collection.TryParseAdd("http://www.example.org/1/")); Assert.True(collection.TryParseAdd("http://www.example.org/2/")); @@ -217,19 +156,6 @@ public void TryParseAdd_AddValues_AllAdded() Assert.Equal(3, collection.Count); } - [Fact] - public void TryParseAdd_UseSpecialValue_Added() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - Assert.True(collection.TryParseAdd(specialValue.AbsoluteUri)); - - Assert.True(collection.IsSpecialValueSet); - Assert.Equal(specialValue.ToString(), collection.ToString()); - } - [Fact] public void TryParseAdd_AddBadValue_False() { @@ -268,27 +194,6 @@ public void Clear_AddValuesThenClear_NoElementsInCollection() Assert.Equal(0, collection.Count); } - [Fact] - public void Clear_AddValuesAndSpecialValueThenClear_EverythingCleared() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.SetSpecialValue(); - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.Add(new Uri("http://www.example.org/3/")); - - Assert.Equal(4, collection.Count); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - - collection.Clear(); - - Assert.Equal(0, collection.Count); - Assert.False(collection.IsSpecialValueSet, "Special value was removed by Clear()."); - } - [Fact] public void Contains_CallWithNullValue_Throw() { @@ -389,21 +294,13 @@ public void CopyTo_NoValues_DoesNotChangeArray() public void CopyTo_AddSingleValue_ContainsSingleValue() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); collection.Add(new Uri("http://www.example.org/")); Uri[] array = new Uri[1]; collection.CopyTo(array, 0); Assert.Equal(new Uri("http://www.example.org/"), array[0]); - - // Now only set the special value: nothing should be added to the array. - headers.Clear(); - headers.Add(knownUriHeader, specialValue.ToString()); - array[0] = null; - collection.CopyTo(array, 0); - Assert.Equal(specialValue, array[0]); } [Fact] @@ -426,79 +323,11 @@ public void CopyTo_AddMultipleValues_ContainsAllValuesInTheRightOrder() Assert.Null(array[4]); } - [Fact] - public void CopyTo_AddValuesAndSpecialValue_AllValuesCopied() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.SetSpecialValue(); - collection.Add(new Uri("http://www.example.org/3/")); - - Uri[] array = new Uri[5]; - collection.CopyTo(array, 1); - - Assert.Null(array[0]); - Assert.Equal(new Uri("http://www.example.org/1/"), array[1]); - Assert.Equal(new Uri("http://www.example.org/2/"), array[2]); - Assert.Equal(specialValue, array[3]); - Assert.Equal(new Uri("http://www.example.org/3/"), array[4]); - - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - - [Fact] - public void CopyTo_OnlySpecialValue_Copied() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.SetSpecialValue(); - headers.Add(knownUriHeader, specialValue.ToString()); - headers.Add(knownUriHeader, specialValue.ToString()); - headers.Add(knownUriHeader, specialValue.ToString()); - - Uri[] array = new Uri[4]; - array[0] = null; - collection.CopyTo(array, 0); - - Assert.Equal(specialValue, array[0]); - Assert.Equal(specialValue, array[1]); - Assert.Equal(specialValue, array[2]); - Assert.Equal(specialValue, array[3]); - - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - - [Fact] - public void CopyTo_OnlySpecialValueEmptyDestination_Copied() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.SetSpecialValue(); - headers.Add(knownUriHeader, specialValue.ToString()); - - Uri[] array = new Uri[2]; - collection.CopyTo(array, 0); - - Assert.Equal(specialValue, array[0]); - Assert.Equal(specialValue, array[1]); - - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - [Fact] public void CopyTo_ArrayTooSmall_Throw() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownStringHeader, headers, - "special"); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownStringHeader, headers); string[] array = new string[1]; array[0] = null; @@ -665,170 +494,6 @@ public void GetEnumerator_AddValuesAndGetEnumeratorFromInterface_AllValuesReturn } } - [Fact] - public void GetEnumerator_AddValuesAndSpecialValueAndGetEnumeratorFromInterface_AllValuesReturned() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.Add(new Uri("http://www.example.org/3/")); - collection.SetSpecialValue(); - - System.Collections.IEnumerable enumerable = collection; - - // The "special value" should be ignored and not part of the resulting collection. - int i = 1; - bool specialFound = false; - foreach (var item in enumerable) - { - if (item.Equals(specialValue)) - { - specialFound = true; - } - else - { - Assert.Equal(new Uri("http://www.example.org/" + i + "/"), item); - i++; - } - } - - Assert.True(specialFound); - - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - - [Fact] - public void GetEnumerator_AddValuesAndSpecialValue_AllValuesReturned() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.SetSpecialValue(); - collection.Add(new Uri("http://www.example.org/3/")); - - System.Collections.IEnumerable enumerable = collection; - - // The special value we added above, must be part of the collection returned by GetEnumerator(). - int i = 1; - bool specialFound = false; - foreach (var item in enumerable) - { - if (item.Equals(specialValue)) - { - specialFound = true; - } - else - { - Assert.Equal(new Uri("http://www.example.org/" + i + "/"), item); - i++; - } - } - - Assert.True(specialFound); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - - [Fact] - public void IsSpecialValueSet_NoSpecialValueUsed_ReturnsFalse() - { - // Create a new collection _without_ specifying a special value. - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - null, null); - - Assert.False(collection.IsSpecialValueSet, - "Special value is set even though collection doesn't define a special value."); - } - - [Fact] - public void RemoveSpecialValue_AddRemoveSpecialValue_SpecialValueGetsRemoved() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.SetSpecialValue(); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - Assert.Equal(1, headers.GetValues(knownUriHeader).Count()); - - collection.RemoveSpecialValue(); - Assert.False(collection.IsSpecialValueSet, "Special value is set."); - - // Since the only header value was the "special value", removing it will remove the whole header - // from the collection. - Assert.False(headers.Contains(knownUriHeader)); - } - - [Fact] - public void RemoveSpecialValue_AddValueAndSpecialValueThenRemoveSpecialValue_SpecialValueGetsRemoved() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/")); - collection.SetSpecialValue(); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - Assert.Equal(2, headers.GetValues(knownUriHeader).Count()); - - collection.RemoveSpecialValue(); - Assert.False(collection.IsSpecialValueSet, "Special value is set."); - Assert.Equal(1, headers.GetValues(knownUriHeader).Count()); - } - - [Fact] - public void RemoveSpecialValue_AddTwoValuesAndSpecialValueThenRemoveSpecialValue_SpecialValueGetsRemoved() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.SetSpecialValue(); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - Assert.Equal(3, headers.GetValues(knownUriHeader).Count()); - - // The difference between this test and the previous one is that HttpHeaders in this case will use - // a List to store the two remaining values, whereas in the previous case it will just store - // the remaining value (no list). - collection.RemoveSpecialValue(); - Assert.False(collection.IsSpecialValueSet, "Special value is set."); - Assert.Equal(2, headers.GetValues(knownUriHeader).Count()); - } - - [Fact] - public void Ctor_ProvideValidator_ValidatorIsUsedWhenAddingValues() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - MockValidator); - - // Adding an arbitrary Uri should not throw. - collection.Add(new Uri("http://some/")); - - // When we add 'invalidValue' our MockValidator will throw. - Assert.Throws(() => { collection.Add(invalidValue); }); - } - - [Fact] - public void Ctor_ProvideValidator_ValidatorIsUsedWhenRemovingValues() - { - // Use different ctor overload than in previous test to make sure all ctor overloads work correctly. - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue, MockValidator); - - // When we remove 'invalidValue' our MockValidator will throw. - Assert.Throws(() => { collection.Remove(invalidValue); }); - } - [Fact] public void ToString_SpecialValues_Success() { @@ -895,14 +560,6 @@ public void ToString_EmptyValue_Success() #region Helper methods - private static void MockValidator(HttpHeaderValueCollection collection, Uri value) - { - if (value == invalidValue) - { - throw new MockException(); - } - } - public class MockException : Exception { public MockException() { }