From a069f6b636e343f7a1839783ee23f9ae7eca32c3 Mon Sep 17 00:00:00 2001 From: John Luo Date: Wed, 21 Sep 2016 12:48:00 -0700 Subject: [PATCH] Store each header value separately --- .../CacheEntry/CacheEntrySerializer.cs | 26 +++++++++++--- .../CacheEntrySerializerTests.cs | 35 +++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.ResponseCaching/CacheEntry/CacheEntrySerializer.cs b/src/Microsoft.AspNetCore.ResponseCaching/CacheEntry/CacheEntrySerializer.cs index 385d5ebf78..21534dd13f 100644 --- a/src/Microsoft.AspNetCore.ResponseCaching/CacheEntry/CacheEntrySerializer.cs +++ b/src/Microsoft.AspNetCore.ResponseCaching/CacheEntry/CacheEntrySerializer.cs @@ -93,7 +93,9 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal // Header count (int) // Header(s) // Key (string) - // Value (string) + // ValueCount (int) + // Value(s) + // Value (string) // ContainsBody (bool) // Body length (int) // Body (byte[]) @@ -107,8 +109,20 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal for (var index = 0; index < headerCount; index++) { var key = reader.ReadString(); - var value = reader.ReadString(); - headers[key] = value; + var headerValueCount = reader.ReadInt32(); + if (headerValueCount > 1) + { + var headerValues = new string[headerValueCount]; + for (var valueIndex = 0; valueIndex < headerValueCount; valueIndex++) + { + headerValues[valueIndex] = reader.ReadString(); + } + headers[key] = headerValues; + } + else if (headerValueCount == 1) + { + headers[key] = reader.ReadString(); + } } var containsBody = reader.ReadBoolean(); @@ -202,7 +216,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal foreach (var header in entry.Headers) { writer.Write(header.Key); - writer.Write(header.Value); + writer.Write(header.Value.Count); + foreach (var headerValue in header.Value) + { + writer.Write(headerValue); + } } if (entry.Body == null) diff --git a/test/Microsoft.AspNetCore.ResponseCaching.Tests/CacheEntrySerializerTests.cs b/test/Microsoft.AspNetCore.ResponseCaching.Tests/CacheEntrySerializerTests.cs index 493906f20b..966fdee6e0 100644 --- a/test/Microsoft.AspNetCore.ResponseCaching.Tests/CacheEntrySerializerTests.cs +++ b/test/Microsoft.AspNetCore.ResponseCaching.Tests/CacheEntrySerializerTests.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.ResponseCaching.Internal; +using Microsoft.Extensions.Primitives; using Xunit; namespace Microsoft.AspNetCore.ResponseCaching.Tests @@ -76,6 +77,40 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests AssertCachedResponseEqual(cachedResponse, (CachedResponse)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedResponse))); } + [Fact] + public void RoundTrip_CachedResponseWithMultivalueHeaders_Succeeds() + { + var headers = new HeaderDictionary(); + headers["keyA"] = new StringValues(new[] { "ValueA", "ValueB" }); + var cachedResponse = new CachedResponse() + { + BodyKeyPrefix = FastGuid.NewGuid().IdString, + Created = DateTimeOffset.UtcNow, + StatusCode = StatusCodes.Status200OK, + Body = Encoding.ASCII.GetBytes("Hello world"), + Headers = headers + }; + + AssertCachedResponseEqual(cachedResponse, (CachedResponse)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedResponse))); + } + + [Fact] + public void RoundTrip_CachedResponseWithEmptyHeaders_Succeeds() + { + var headers = new HeaderDictionary(); + headers["keyA"] = StringValues.Empty; + var cachedResponse = new CachedResponse() + { + BodyKeyPrefix = FastGuid.NewGuid().IdString, + Created = DateTimeOffset.UtcNow, + StatusCode = StatusCodes.Status200OK, + Body = Encoding.ASCII.GetBytes("Hello world"), + Headers = headers + }; + + AssertCachedResponseEqual(cachedResponse, (CachedResponse)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedResponse))); + } + [Fact] public void RoundTrip_CachedVaryByRule_EmptyRules_Succeeds() {