[#5430] CookieTempDataProvider chunking broken

This commit is contained in:
Kiran Challa 2016-10-28 14:08:34 -07:00
parent 5d5b282dbd
commit 32710bbfbe
4 changed files with 37 additions and 20 deletions

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.AspNetCore.Internal; using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal; using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -41,10 +42,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
if (context.Request.Cookies.ContainsKey(CookieName)) if (context.Request.Cookies.ContainsKey(CookieName))
{ {
var base64EncodedValue = _chunkingCookieManager.GetRequestCookie(context, CookieName); var encodedValue = _chunkingCookieManager.GetRequestCookie(context, CookieName);
if (!string.IsNullOrEmpty(base64EncodedValue)) if (!string.IsNullOrEmpty(encodedValue))
{ {
var protectedData = Convert.FromBase64String(base64EncodedValue); var protectedData = Base64UrlTextEncoder.Decode(encodedValue);
var unprotectedData = _dataProtector.Unprotect(protectedData); var unprotectedData = _dataProtector.Unprotect(protectedData);
return _tempDataSerializer.Deserialize(unprotectedData); return _tempDataSerializer.Deserialize(unprotectedData);
} }
@ -73,8 +74,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
{ {
var bytes = _tempDataSerializer.Serialize(values); var bytes = _tempDataSerializer.Serialize(values);
bytes = _dataProtector.Protect(bytes); bytes = _dataProtector.Protect(bytes);
var base64EncodedValue = Convert.ToBase64String(bytes); var encodedValue = Base64UrlTextEncoder.Encode(bytes);
_chunkingCookieManager.AppendResponseCookie(context, CookieName, base64EncodedValue, cookieOptions); _chunkingCookieManager.AppendResponseCookie(context, CookieName, encodedValue, cookieOptions);
} }
else else
{ {

View File

@ -1,17 +1,19 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.Net.Http.Headers;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class TempDataInCookiesTest : TempDataTestBase, IClassFixture<MvcTestFixture<BasicWebSite.StartupWithCookieTempDataProvider>> public class TempDataInCookiesTest : TempDataTestBase, IClassFixture<MvcTestFixture<BasicWebSite.StartupWithCookieTempDataProvider>>
{ {
private const int DefaultChunkSize = 4070;
public TempDataInCookiesTest(MvcTestFixture<BasicWebSite.StartupWithCookieTempDataProvider> fixture) public TempDataInCookiesTest(MvcTestFixture<BasicWebSite.StartupWithCookieTempDataProvider> fixture)
{ {
Client = fixture.Client; Client = fixture.Client;
@ -20,10 +22,10 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
protected override HttpClient Client { get; } protected override HttpClient Client { get; }
[Theory] [Theory]
[InlineData(DefaultChunkSize)] [InlineData(ChunkingCookieManager.DefaultChunkSize)]
[InlineData(DefaultChunkSize * 1.5)] [InlineData(ChunkingCookieManager.DefaultChunkSize * 1.5)]
[InlineData(DefaultChunkSize * 2)] [InlineData(ChunkingCookieManager.DefaultChunkSize * 2)]
[InlineData(DefaultChunkSize * 3)] [InlineData(ChunkingCookieManager.DefaultChunkSize * 3)]
public async Task RoundTripLargeData_WorksWithChunkingCookies(int size) public async Task RoundTripLargeData_WorksWithChunkingCookies(int size)
{ {
// Arrange // Arrange
@ -35,6 +37,15 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
// Assert 1 // Assert 1
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var cookies = response.Headers.GetValues(HeaderNames.SetCookie);
var cookieTempDataProviderCookies = cookies.Where(cookie => cookie.Contains(CookieTempDataProvider.CookieName));
Assert.NotNull(cookieTempDataProviderCookies);
// Verify that all the cookies from CookieTempDataProvider are within the maximum size
foreach (var cookie in cookieTempDataProviderCookies)
{
Assert.True(cookie.Length <= ChunkingCookieManager.DefaultChunkSize);
}
// Act 2 // Act 2
response = await Client.SendAsync(GetRequest("/TempData/GetLargeValueFromTempData", response)); response = await Client.SendAsync(GetRequest("/TempData/GetLargeValueFromTempData", response));

View File

@ -21,6 +21,10 @@
"FiltersWebSite": "1.0.0", "FiltersWebSite": "1.0.0",
"FormatterWebSite": "1.0.0", "FormatterWebSite": "1.0.0",
"HtmlGenerationWebSite": "1.0.0", "HtmlGenerationWebSite": "1.0.0",
"Microsoft.AspNetCore.ChunkingCookieManager.Sources": {
"version": "1.1.0-*",
"type": "build"
},
"Microsoft.AspNetCore.Mvc": "1.1.0-*", "Microsoft.AspNetCore.Mvc": "1.1.0-*",
"Microsoft.AspNetCore.Mvc.Formatters.Xml": "1.1.0-*", "Microsoft.AspNetCore.Mvc.Formatters.Xml": "1.1.0-*",
"Microsoft.AspNetCore.Mvc.TestCommon": { "Microsoft.AspNetCore.Mvc.TestCommon": {

View File

@ -6,6 +6,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.AspNetCore.Http.Internal; using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal; using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -31,19 +32,19 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
} }
[Fact] [Fact]
public void LoadTempData_Base64DecodesAnd_UnprotectsData_FromCookie() public void LoadTempData_Base64UrlDecodesAnd_UnprotectsData_FromCookie()
{ {
// Arrange // Arrange
var expectedValues = new Dictionary<string, object>(); var expectedValues = new Dictionary<string, object>();
expectedValues.Add("int", 10); expectedValues.Add("int", 10);
var tempDataProviderSerializer = new TempDataSerializer(); var tempDataProviderSerializer = new TempDataSerializer();
var expectedDataToUnprotect = tempDataProviderSerializer.Serialize(expectedValues); var expectedDataToUnprotect = tempDataProviderSerializer.Serialize(expectedValues);
var base64EncodedDataInCookie = Convert.ToBase64String(expectedDataToUnprotect); var base64AndUrlEncodedDataInCookie = Base64UrlTextEncoder.Encode(expectedDataToUnprotect);
var dataProtector = new PassThroughDataProtector(); var dataProtector = new PassThroughDataProtector();
var tempDataProvider = GetProvider(dataProtector); var tempDataProvider = GetProvider(dataProtector);
var requestCookies = new RequestCookieCollection(new Dictionary<string, string>() var requestCookies = new RequestCookieCollection(new Dictionary<string, string>()
{ {
{ CookieTempDataProvider.CookieName, base64EncodedDataInCookie } { CookieTempDataProvider.CookieName, base64AndUrlEncodedDataInCookie }
}); });
var httpContext = new Mock<HttpContext>(); var httpContext = new Mock<HttpContext>();
httpContext httpContext
@ -59,14 +60,14 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
} }
[Fact] [Fact]
public void SaveTempData_ProtectsAnd_Base64EncodesDataAnd_SetsCookie() public void SaveTempData_ProtectsAnd_Base64UrlEncodesDataAnd_SetsCookie()
{ {
// Arrange // Arrange
var values = new Dictionary<string, object>(); var values = new Dictionary<string, object>();
values.Add("int", 10); values.Add("int", 10);
var tempDataProviderStore = new TempDataSerializer(); var tempDataProviderStore = new TempDataSerializer();
var expectedDataToProtect = tempDataProviderStore.Serialize(values); var expectedDataToProtect = tempDataProviderStore.Serialize(values);
var expectedDataInCookie = Convert.ToBase64String(expectedDataToProtect); var expectedDataInCookie = Base64UrlTextEncoder.Encode(expectedDataToProtect);
var dataProtector = new PassThroughDataProtector(); var dataProtector = new PassThroughDataProtector();
var tempDataProvider = GetProvider(dataProtector); var tempDataProvider = GetProvider(dataProtector);
var responseCookies = new MockResponseCookieCollection(); var responseCookies = new MockResponseCookieCollection();
@ -99,7 +100,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
values.Add("int", 10); values.Add("int", 10);
var tempDataProviderStore = new TempDataSerializer(); var tempDataProviderStore = new TempDataSerializer();
var expectedDataToProtect = tempDataProviderStore.Serialize(values); var expectedDataToProtect = tempDataProviderStore.Serialize(values);
var expectedDataInCookie = Convert.ToBase64String(expectedDataToProtect); var expectedDataInCookie = Base64UrlTextEncoder.Encode(expectedDataToProtect);
var dataProtector = new PassThroughDataProtector(); var dataProtector = new PassThroughDataProtector();
var tempDataProvider = GetProvider(dataProtector); var tempDataProvider = GetProvider(dataProtector);
var responseCookies = new MockResponseCookieCollection(); var responseCookies = new MockResponseCookieCollection();
@ -140,7 +141,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
values.Add("int", 10); values.Add("int", 10);
var tempDataProviderStore = new TempDataSerializer(); var tempDataProviderStore = new TempDataSerializer();
var expectedDataToProtect = tempDataProviderStore.Serialize(values); var expectedDataToProtect = tempDataProviderStore.Serialize(values);
var expectedDataInCookie = Convert.ToBase64String(expectedDataToProtect); var expectedDataInCookie = Base64UrlTextEncoder.Encode(expectedDataToProtect);
var dataProtector = new PassThroughDataProtector(); var dataProtector = new PassThroughDataProtector();
var tempDataProvider = GetProvider( var tempDataProvider = GetProvider(
dataProtector, dataProtector,
@ -178,12 +179,12 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
values.Add("int", 10); values.Add("int", 10);
var tempDataProviderStore = new TempDataSerializer(); var tempDataProviderStore = new TempDataSerializer();
var serializedData = tempDataProviderStore.Serialize(values); var serializedData = tempDataProviderStore.Serialize(values);
var base64EncodedData = Convert.ToBase64String(serializedData); var base64AndUrlEncodedData = Base64UrlTextEncoder.Encode(serializedData);
var dataProtector = new PassThroughDataProtector(); var dataProtector = new PassThroughDataProtector();
var tempDataProvider = GetProvider(dataProtector); var tempDataProvider = GetProvider(dataProtector);
var requestCookies = new RequestCookieCollection(new Dictionary<string, string>() var requestCookies = new RequestCookieCollection(new Dictionary<string, string>()
{ {
{ CookieTempDataProvider.CookieName, base64EncodedData } { CookieTempDataProvider.CookieName, base64AndUrlEncodedData }
}); });
var responseCookies = new MockResponseCookieCollection(); var responseCookies = new MockResponseCookieCollection();
var httpContext = new Mock<HttpContext>(); var httpContext = new Mock<HttpContext>();