Update no-store behaviour

This commit is contained in:
John Luo 2016-08-23 17:11:18 -07:00
parent 62aabc1bae
commit 4f61c65931
3 changed files with 116 additions and 9 deletions

View File

@ -212,7 +212,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
// TODO: no-cache requests can be retrieved upon validation with origin
if (!string.IsNullOrEmpty(request.Headers[HeaderNames.CacheControl]))
{
if (RequestCacheControl.NoCache || RequestCacheControl.NoStore)
if (RequestCacheControl.NoCache)
{
return false;
}
@ -244,7 +244,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
}
// Check no-store
if (ResponseCacheControl.NoStore)
if (RequestCacheControl.NoStore || ResponseCacheControl.NoStore)
{
return false;
}

View File

@ -57,20 +57,34 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Assert.False(context.RequestIsCacheable());
}
[Theory]
[InlineData("no-cache")]
[InlineData("no-store")]
[InlineData("no-cache, no-store")]
public void RequestIsCacheable_ExplicitDisablingDirectives_NotAllowed(string directive)
[Fact]
public void RequestIsCacheable_NoCache_NotAllowed()
{
var httpContext = new DefaultHttpContext();
httpContext.Request.Method = "GET";
httpContext.Request.Headers[HeaderNames.CacheControl] = directive;
httpContext.Request.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
{
NoCache = true
};
var context = new ResponseCachingContext(httpContext, new TestResponseCache());
Assert.False(context.RequestIsCacheable());
}
[Fact]
public void RequestIsCacheable_NoStore_Allowed()
{
var httpContext = new DefaultHttpContext();
httpContext.Request.Method = "GET";
httpContext.Request.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
{
NoStore = true
};
var context = new ResponseCachingContext(httpContext, new TestResponseCache());
Assert.True(context.RequestIsCacheable());
}
[Fact]
public void RequestIsCacheable_LegacyDirectives_NotAllowed()
{
@ -162,7 +176,24 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
}
[Fact]
public void ResponseIsCacheable_NoStore_NotAllowed()
public void ResponseIsCacheable_RequestNoStore_NotAllowed()
{
var httpContext = new DefaultHttpContext();
httpContext.Request.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
{
NoStore = true
};
httpContext.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
{
Public = true
};
var context = new ResponseCachingContext(httpContext, new TestResponseCache());
Assert.False(context.ResponseIsCacheable());
}
[Fact]
public void ResponseIsCacheable_ResponseNoStore_NotAllowed()
{
var httpContext = new DefaultHttpContext();
httpContext.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()

View File

@ -347,6 +347,82 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
}
}
[Fact]
public async void ServesCachedContentIfSubsequentRequestContainsNoStore()
{
var builder = CreateBuilderWithResponseCaching(
async (context) =>
{
var uniqueId = Guid.NewGuid().ToString();
var headers = context.Response.GetTypedHeaders();
headers.CacheControl = new CacheControlHeaderValue()
{
Public = true,
MaxAge = TimeSpan.FromSeconds(10)
};
headers.Date = DateTimeOffset.UtcNow;
headers.Headers["X-Value"] = uniqueId;
await context.Response.WriteAsync(uniqueId);
});
using (var server = new TestServer(builder))
{
var client = server.CreateClient();
var initialResponse = await client.GetAsync("");
client.DefaultRequestHeaders.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue()
{
NoStore = true
};
var subsequentResponse = await client.GetAsync("");
initialResponse.EnsureSuccessStatusCode();
subsequentResponse.EnsureSuccessStatusCode();
foreach (var header in initialResponse.Headers)
{
Assert.Equal(initialResponse.Headers.GetValues(header.Key), subsequentResponse.Headers.GetValues(header.Key));
}
Assert.True(subsequentResponse.Headers.Contains(HeaderNames.Age));
Assert.Equal(await initialResponse.Content.ReadAsStringAsync(), await subsequentResponse.Content.ReadAsStringAsync());
}
}
[Fact]
public async void ServesFreshContentIfInitialRequestContainsNoStore()
{
var builder = CreateBuilderWithResponseCaching(
async (context) =>
{
var uniqueId = Guid.NewGuid().ToString();
var headers = context.Response.GetTypedHeaders();
headers.CacheControl = new CacheControlHeaderValue()
{
Public = true,
MaxAge = TimeSpan.FromSeconds(10)
};
headers.Date = DateTimeOffset.UtcNow;
headers.Headers["X-Value"] = uniqueId;
await context.Response.WriteAsync(uniqueId);
});
using (var server = new TestServer(builder))
{
var client = server.CreateClient();
client.DefaultRequestHeaders.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue()
{
NoStore = true
};
var initialResponse = await client.GetAsync("");
var subsequentResponse = await client.GetAsync("");
initialResponse.EnsureSuccessStatusCode();
subsequentResponse.EnsureSuccessStatusCode();
Assert.False(subsequentResponse.Headers.Contains(HeaderNames.Age));
Assert.NotEqual(await initialResponse.Content.ReadAsStringAsync(), await subsequentResponse.Content.ReadAsStringAsync());
}
}
private static IWebHostBuilder CreateBuilderWithResponseCaching(RequestDelegate requestDelegate) =>
CreateBuilderWithResponseCaching(app => { }, requestDelegate);