From 69f60b317bc4db421566c2d97dcf78f8495106f9 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Tue, 29 Mar 2022 06:15:15 -0700 Subject: [PATCH] Preserve parsed & raw header value ordering (#67227) --- .../System/Net/Http/Headers/HttpHeaders.cs | 8 +++---- .../UnitTests/Headers/HttpHeadersTest.cs | 21 ++++++++++++++++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs index c54c97e9b30da..ef5e20841e9e5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs @@ -1162,8 +1162,8 @@ internal static void GetStoreValuesAsStringOrStringArray(HeaderDescriptor descri } int currentIndex = 0; - ReadStoreValues(values, info.RawValue, null, ref currentIndex); ReadStoreValues(values, info.ParsedAndInvalidValues, descriptor.Parser, ref currentIndex); + ReadStoreValues(values, info.RawValue, null, ref currentIndex); Debug.Assert(currentIndex == length); } @@ -1196,8 +1196,8 @@ internal static int GetStoreValuesIntoStringArray(HeaderDescriptor descriptor, o } int currentIndex = 0; - ReadStoreValues(values, info.RawValue, null, ref currentIndex); ReadStoreValues(values, info.ParsedAndInvalidValues, descriptor.Parser, ref currentIndex); + ReadStoreValues(values, info.RawValue, null, ref currentIndex); Debug.Assert(currentIndex == length); } @@ -1208,9 +1208,7 @@ private static int GetValueCount(HeaderStoreItemInfo info) { Debug.Assert(info != null); - int valueCount = Count(info.RawValue); - valueCount += Count(info.ParsedAndInvalidValues); - return valueCount; + return Count(info.ParsedAndInvalidValues) + Count(info.RawValue); static int Count(object? valueStore) => valueStore is null ? 0 : diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs index 7ec416358208e..9935a60644bbf 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs @@ -51,6 +51,25 @@ public void TryAddWithoutValidation_ValidAndInvalidValues_InsertionOrderIsPreser Assert.Equal(new[] { "text/bar", "invalid", "text/baz" }, accept); } + [Fact] + public void MixedAddAndTryAddWithoutValidation_ParsedAndRawValues_InsertionOrderIsPreserved() + { + HttpHeaders headers = new HttpRequestMessage().Headers; + + headers.Add("Accept", "text/foo"); + headers.TryAddWithoutValidation("Accept", "text/bar"); + headers.TryAddWithoutValidation("Accept", "invalid"); + + var expectedValues = new string[] { "text/foo", "text/bar", "invalid" }; + + Assert.Equal(expectedValues, headers.NonValidated["Accept"]); + + Assert.True(headers.TryGetValues("Accept", out IEnumerable? values)); + Assert.Equal(expectedValues, values); + + Assert.Equal(expectedValues, headers.NonValidated["Accept"]); + } + [Theory] [InlineData(null)] [InlineData("")] @@ -1431,7 +1450,7 @@ public void NonValidated_SetValidAndInvalidHeaderValues_AllHeaderValuesReturned( headers.TryAddWithoutValidation(headers.Descriptor, "value2,value3"); headers.TryAddWithoutValidation(headers.Descriptor, invalidHeaderValue); - string expectedValue = "value2,value3---" + invalidHeaderValue + "---" + parsedPrefix + "1"; + string expectedValue = $"{parsedPrefix}1---value2,value3---{invalidHeaderValue}"; Assert.Equal(1, headers.NonValidated.Count);