API review renames and updates continued

- Consolidate base key to be singular
This commit is contained in:
John Luo 2016-09-14 15:20:48 -07:00
parent ccfa090e6e
commit 6c13371fa0
29 changed files with 555 additions and 586 deletions

View File

@ -20,7 +20,7 @@ namespace ResponseCachingSample
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)
{ {
app.UseResponseCaching(); app.UseResponseCache();
app.Run(async (context) => app.Run(async (context) =>
{ {
// These settings should be configured by context.Response.Cache.* // These settings should be configured by context.Response.Cache.*

View File

@ -42,8 +42,8 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
// Serialization Format // Serialization Format
// Format version (int) // Format version (int)
// Type (char: 'B' for CachedResponseBody, 'R' for CachedResponse, 'V' for CachedVaryRules) // Type (char: 'B' for CachedResponseBody, 'R' for CachedResponse, 'V' for CachedVaryByRules)
// Type-dependent data (see CachedResponse and CachedVaryRules) // Type-dependent data (see CachedResponse and CachedVaryByRules)
public static object Read(BinaryReader reader) public static object Read(BinaryReader reader)
{ {
if (reader == null) if (reader == null)
@ -68,10 +68,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
} }
else if (type == 'V') else if (type == 'V')
{ {
return ReadCachedVaryRules(reader); return ReadCachedVaryByRules(reader);
} }
// Unable to read as CachedResponse or CachedVaryRules // Unable to read as CachedResponse or CachedVaryByRules
return null; return null;
} }
@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
// Header(s) (comma separated string) // Header(s) (comma separated string)
// Params count // Params count
// Param(s) (comma separated string) // Param(s) (comma separated string)
private static CachedVaryRules ReadCachedVaryRules(BinaryReader reader) private static CachedVaryByRules ReadCachedVaryByRules(BinaryReader reader)
{ {
var varyKeyPrefix = reader.ReadString(); var varyKeyPrefix = reader.ReadString();
@ -146,7 +146,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
param[index] = reader.ReadString(); param[index] = reader.ReadString();
} }
return new CachedVaryRules { VaryKeyPrefix = varyKeyPrefix, Headers = headers, Params = param }; return new CachedVaryByRules { VaryByKeyPrefix = varyKeyPrefix, Headers = headers, Params = param };
} }
// See serialization format above // See serialization format above
@ -174,10 +174,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
writer.Write('R'); writer.Write('R');
WriteCachedResponse(writer, entry as CachedResponse); WriteCachedResponse(writer, entry as CachedResponse);
} }
else if (entry is CachedVaryRules) else if (entry is CachedVaryByRules)
{ {
writer.Write('V'); writer.Write('V');
WriteCachedVaryRules(writer, entry as CachedVaryRules); WriteCachedVaryByRules(writer, entry as CachedVaryByRules);
} }
else else
{ {
@ -218,18 +218,18 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
} }
// See serialization format above // See serialization format above
private static void WriteCachedVaryRules(BinaryWriter writer, CachedVaryRules varyRules) private static void WriteCachedVaryByRules(BinaryWriter writer, CachedVaryByRules varyByRules)
{ {
writer.Write(varyRules.VaryKeyPrefix); writer.Write(varyByRules.VaryByKeyPrefix);
writer.Write(varyRules.Headers.Count); writer.Write(varyByRules.Headers.Count);
foreach (var header in varyRules.Headers) foreach (var header in varyByRules.Headers)
{ {
writer.Write(header); writer.Write(header);
} }
writer.Write(varyRules.Params.Count); writer.Write(varyByRules.Params.Count);
foreach (var param in varyRules.Params) foreach (var param in varyByRules.Params)
{ {
writer.Write(param); writer.Write(param);
} }

View File

@ -8,14 +8,14 @@ namespace Microsoft.AspNetCore.ResponseCaching
{ {
public class CachedResponse public class CachedResponse
{ {
public string BodyKeyPrefix { get; internal set; } public string BodyKeyPrefix { get; set; }
public DateTimeOffset Created { get; internal set; } public DateTimeOffset Created { get; set; }
public int StatusCode { get; internal set; } public int StatusCode { get; set; }
public IHeaderDictionary Headers { get; internal set; } = new HeaderDictionary(); public IHeaderDictionary Headers { get; set; } = new HeaderDictionary();
public byte[] Body { get; internal set; } public byte[] Body { get; set; }
} }
} }

View File

@ -5,6 +5,6 @@ namespace Microsoft.AspNetCore.ResponseCaching
{ {
public class CachedResponseBody public class CachedResponseBody
{ {
public byte[] Body { get; internal set; } public byte[] Body { get; set; }
} }
} }

View File

@ -5,12 +5,12 @@ using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.ResponseCaching namespace Microsoft.AspNetCore.ResponseCaching
{ {
public class CachedVaryRules public class CachedVaryByRules
{ {
public string VaryKeyPrefix { get; internal set; } public string VaryByKeyPrefix { get; set; }
public StringValues Headers { get; internal set; } public StringValues Headers { get; set; }
public StringValues Params { get; internal set; } public StringValues Params { get; set; }
} }
} }

View File

@ -7,19 +7,19 @@ using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder namespace Microsoft.AspNetCore.Builder
{ {
public static class ResponseCachingExtensions public static class ResponseCacheExtensions
{ {
public static IApplicationBuilder UseResponseCaching(this IApplicationBuilder app) public static IApplicationBuilder UseResponseCache(this IApplicationBuilder app)
{ {
if (app == null) if (app == null)
{ {
throw new ArgumentNullException(nameof(app)); throw new ArgumentNullException(nameof(app));
} }
return app.UseMiddleware<ResponseCachingMiddleware>(); return app.UseMiddleware<ResponseCacheMiddleware>();
} }
public static IApplicationBuilder UseResponseCaching(this IApplicationBuilder app, ResponseCachingOptions options) public static IApplicationBuilder UseResponseCache(this IApplicationBuilder app, ResponseCacheOptions options)
{ {
if (app == null) if (app == null)
{ {
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Builder
throw new ArgumentNullException(nameof(options)); throw new ArgumentNullException(nameof(options));
} }
return app.UseMiddleware<ResponseCachingMiddleware>(Options.Create(options)); return app.UseMiddleware<ResponseCacheMiddleware>(Options.Create(options));
} }
} }
} }

View File

@ -6,11 +6,11 @@ using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.ResponseCaching namespace Microsoft.AspNetCore.ResponseCaching
{ {
// TODO: Temporary interface for endpoints to specify options for response caching // TODO: Temporary interface for endpoints to specify options for response caching
public static class ResponseCachingHttpContextExtensions public static class ResponseCacheHttpContextExtensions
{ {
public static ResponseCachingFeature GetResponseCachingFeature(this HttpContext httpContext) public static ResponseCacheFeature GetResponseCacheFeature(this HttpContext httpContext)
{ {
return httpContext.Features.Get<ResponseCachingFeature>(); return httpContext.Features.Get<ResponseCacheFeature>();
} }
} }
} }

View File

@ -8,7 +8,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Microsoft.Extensions.DependencyInjection namespace Microsoft.Extensions.DependencyInjection
{ {
public static class ResponseCachingServiceCollectionExtensions public static class ResponseCacheServiceCollectionExtensions
{ {
public static IServiceCollection AddMemoryResponseCache(this IServiceCollection services) public static IServiceCollection AddMemoryResponseCache(this IServiceCollection services)
{ {
@ -18,8 +18,8 @@ namespace Microsoft.Extensions.DependencyInjection
} }
services.AddMemoryCache(); services.AddMemoryCache();
services.AddResponseCachingServices(); services.AddResponseCacheServices();
services.TryAdd(ServiceDescriptor.Singleton<IResponseCache, MemoryResponseCache>()); services.TryAdd(ServiceDescriptor.Singleton<IResponseCacheStore, MemoryResponseCacheStore>());
return services; return services;
} }
@ -32,16 +32,16 @@ namespace Microsoft.Extensions.DependencyInjection
} }
services.AddDistributedMemoryCache(); services.AddDistributedMemoryCache();
services.AddResponseCachingServices(); services.AddResponseCacheServices();
services.TryAdd(ServiceDescriptor.Singleton<IResponseCache, DistributedResponseCache>()); services.TryAdd(ServiceDescriptor.Singleton<IResponseCacheStore, DistributedResponseCacheStore>());
return services; return services;
} }
private static IServiceCollection AddResponseCachingServices(this IServiceCollection services) private static IServiceCollection AddResponseCacheServices(this IServiceCollection services)
{ {
services.TryAdd(ServiceDescriptor.Singleton<ICacheKeyProvider, CacheKeyProvider>()); services.TryAdd(ServiceDescriptor.Singleton<IResponseCacheKeyProvider, ResponseCacheKeyProvider>());
services.TryAdd(ServiceDescriptor.Singleton<ICacheabilityValidator, CacheabilityValidator>()); services.TryAdd(ServiceDescriptor.Singleton<IResponseCachePolicyProvider, ResponseCachePolicyProvider>());
return services; return services;
} }

View File

@ -1,38 +0,0 @@
// 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.
using System.Collections.Generic;
namespace Microsoft.AspNetCore.ResponseCaching
{
public interface ICacheKeyProvider
{
/// <summary>
/// Create a base key for storing items.
/// </summary>
/// <param name="context">The <see cref="ResponseCachingContext"/>.</param>
/// <returns>The created base key.</returns>
string CreateStorageBaseKey(ResponseCachingContext context);
/// <summary>
/// Create one or more base keys for looking up items.
/// </summary>
/// <param name="context">The <see cref="ResponseCachingContext"/>.</param>
/// <returns>An ordered <see cref="IEnumerable{T}"/> containing the base keys to try when looking up items.</returns>
IEnumerable<string> CreateLookupBaseKeys(ResponseCachingContext context);
/// <summary>
/// Create a vary key for storing items.
/// </summary>
/// <param name="context">The <see cref="ResponseCachingContext"/>.</param>
/// <returns>The created vary key.</returns>
string CreateStorageVaryKey(ResponseCachingContext context);
/// <summary>
/// Create one or more vary keys for looking up items.
/// </summary>
/// <param name="context">The <see cref="ResponseCachingContext"/>.</param>
/// <returns>An ordered <see cref="IEnumerable{T}"/> containing the vary keys to try when looking up items.</returns>
IEnumerable<string> CreateLookupVaryKeys(ResponseCachingContext context);
}
}

View File

@ -1,29 +0,0 @@
// 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.
namespace Microsoft.AspNetCore.ResponseCaching
{
public interface ICacheabilityValidator
{
/// <summary>
/// Determine the cacheability of an HTTP request.
/// </summary>
/// <param name="context">The <see cref="ResponseCachingContext"/>.</param>
/// <returns><c>true</c> if the request is cacheable; otherwise <c>false</c>.</returns>
bool IsRequestCacheable(ResponseCachingContext context);
/// <summary>
/// Determine the cacheability of an HTTP response.
/// </summary>
/// <param name="context">The <see cref="ResponseCachingContext"/>.</param>
/// <returns><c>true</c> if the response is cacheable; otherwise <c>false</c>.</returns>
bool IsResponseCacheable(ResponseCachingContext context);
/// <summary>
/// Determine the freshness of the cached entry.
/// </summary>
/// <param name="context">The <see cref="ResponseCachingContext"/>.</param>
/// <returns><c>true</c> if the cached entry is fresh; otherwise <c>false</c>.</returns>
bool IsCachedEntryFresh(ResponseCachingContext context);
}
}

View File

@ -0,0 +1,31 @@
// 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.
using System.Collections.Generic;
namespace Microsoft.AspNetCore.ResponseCaching
{
public interface IResponseCacheKeyProvider
{
/// <summary>
/// Create a base key for a response cache entry.
/// </summary>
/// <param name="context">The <see cref="ResponseCacheContext"/>.</param>
/// <returns>The created base key.</returns>
string CreateBaseKey(ResponseCacheContext context);
/// <summary>
/// Create a vary key for storing cached responses.
/// </summary>
/// <param name="context">The <see cref="ResponseCacheContext"/>.</param>
/// <returns>The created vary key.</returns>
string CreateStorageVaryByKey(ResponseCacheContext context);
/// <summary>
/// Create one or more vary keys for looking up cached responses.
/// </summary>
/// <param name="context">The <see cref="ResponseCacheContext"/>.</param>
/// <returns>An ordered <see cref="IEnumerable{T}"/> containing the vary keys to try when looking up items.</returns>
IEnumerable<string> CreateLookupVaryByKeys(ResponseCacheContext context);
}
}

View File

@ -0,0 +1,29 @@
// 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.
namespace Microsoft.AspNetCore.ResponseCaching
{
public interface IResponseCachePolicyProvider
{
/// <summary>
/// Determine wehther the response cache middleware should be executed for the incoming HTTP request.
/// </summary>
/// <param name="context">The <see cref="ResponseCacheContext"/>.</param>
/// <returns><c>true</c> if the request is cacheable; otherwise <c>false</c>.</returns>
bool IsRequestCacheable(ResponseCacheContext context);
/// <summary>
/// Determine whether the response received by the middleware be cached for future requests.
/// </summary>
/// <param name="context">The <see cref="ResponseCacheContext"/>.</param>
/// <returns><c>true</c> if the response is cacheable; otherwise <c>false</c>.</returns>
bool IsResponseCacheable(ResponseCacheContext context);
/// <summary>
/// Determine whether the response retrieved from the response cache is fresh and be served.
/// </summary>
/// <param name="context">The <see cref="ResponseCacheContext"/>.</param>
/// <returns><c>true</c> if the cached entry is fresh; otherwise <c>false</c>.</returns>
bool IsCachedEntryFresh(ResponseCacheContext context);
}
}

View File

@ -5,7 +5,7 @@ using System;
namespace Microsoft.AspNetCore.ResponseCaching namespace Microsoft.AspNetCore.ResponseCaching
{ {
public interface IResponseCache public interface IResponseCacheStore
{ {
object Get(string key); object Get(string key);
void Set(string key, object entry, TimeSpan validFor); void Set(string key, object entry, TimeSpan validFor);

View File

@ -6,11 +6,11 @@ using Microsoft.Extensions.Caching.Distributed;
namespace Microsoft.AspNetCore.ResponseCaching.Internal namespace Microsoft.AspNetCore.ResponseCaching.Internal
{ {
internal class DistributedResponseCache : IResponseCache public class DistributedResponseCacheStore : IResponseCacheStore
{ {
private readonly IDistributedCache _cache; private readonly IDistributedCache _cache;
public DistributedResponseCache(IDistributedCache cache) public DistributedResponseCacheStore(IDistributedCache cache)
{ {
if (cache == null) if (cache == null)
{ {

View File

@ -8,18 +8,18 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
{ {
internal static class InternalHttpContextExtensions internal static class InternalHttpContextExtensions
{ {
internal static void AddResponseCachingFeature(this HttpContext httpContext) internal static void AddResponseCacheFeature(this HttpContext httpContext)
{ {
if (httpContext.GetResponseCachingFeature() != null) if (httpContext.GetResponseCacheFeature() != null)
{ {
throw new InvalidOperationException($"Another instance of {nameof(ResponseCachingFeature)} already exists. Only one instance of {nameof(ResponseCachingMiddleware)} can be configured for an application."); throw new InvalidOperationException($"Another instance of {nameof(ResponseCacheFeature)} already exists. Only one instance of {nameof(ResponseCacheMiddleware)} can be configured for an application.");
} }
httpContext.Features.Set(new ResponseCachingFeature()); httpContext.Features.Set(new ResponseCacheFeature());
} }
internal static void RemoveResponseCachingFeature(this HttpContext httpContext) internal static void RemoveResponseCacheFeature(this HttpContext httpContext)
{ {
httpContext.Features.Set<ResponseCachingFeature>(null); httpContext.Features.Set<ResponseCacheFeature>(null);
} }
} }
} }

View File

@ -6,11 +6,11 @@ using Microsoft.Extensions.Caching.Memory;
namespace Microsoft.AspNetCore.ResponseCaching.Internal namespace Microsoft.AspNetCore.ResponseCaching.Internal
{ {
internal class MemoryResponseCache : IResponseCache public class MemoryResponseCacheStore : IResponseCacheStore
{ {
private readonly IMemoryCache _cache; private readonly IMemoryCache _cache;
public MemoryResponseCache(IMemoryCache cache) public MemoryResponseCacheStore(IMemoryCache cache)
{ {
if (cache == null) if (cache == null)
{ {

View File

@ -11,7 +11,7 @@ using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.ResponseCaching namespace Microsoft.AspNetCore.ResponseCaching
{ {
public class ResponseCachingContext public class ResponseCacheContext
{ {
private static readonly CacheControlHeaderValue EmptyCacheControl = new CacheControlHeaderValue(); private static readonly CacheControlHeaderValue EmptyCacheControl = new CacheControlHeaderValue();
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
private CacheControlHeaderValue _requestCacheControl; private CacheControlHeaderValue _requestCacheControl;
private CacheControlHeaderValue _responseCacheControl; private CacheControlHeaderValue _responseCacheControl;
internal ResponseCachingContext( internal ResponseCacheContext(
HttpContext httpContext) HttpContext httpContext)
{ {
HttpContext = httpContext; HttpContext = httpContext;
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
public bool ShouldCacheResponse { get; internal set; } public bool ShouldCacheResponse { get; internal set; }
public string StorageBaseKey { get; internal set; } public string BaseKey { get; internal set; }
public string StorageVaryKey { get; internal set; } public string StorageVaryKey { get; internal set; }
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
public CachedResponse CachedResponse { get; internal set; } public CachedResponse CachedResponse { get; internal set; }
public CachedVaryRules CachedVaryRules { get; internal set; } public CachedVaryByRules CachedVaryByRules { get; internal set; }
internal bool ResponseStarted { get; set; } internal bool ResponseStarted { get; set; }

View File

@ -6,8 +6,8 @@ using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.ResponseCaching namespace Microsoft.AspNetCore.ResponseCaching
{ {
// TODO: Temporary interface for endpoints to specify options for response caching // TODO: Temporary interface for endpoints to specify options for response caching
public class ResponseCachingFeature public class ResponseCacheFeature
{ {
public StringValues VaryParams { get; set; } public StringValues VaryByParams { get; set; }
} }
} }

View File

@ -12,15 +12,15 @@ using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.ResponseCaching namespace Microsoft.AspNetCore.ResponseCaching
{ {
public class CacheKeyProvider : ICacheKeyProvider public class ResponseCacheKeyProvider : IResponseCacheKeyProvider
{ {
// Use the record separator for delimiting components of the cache key to avoid possible collisions // Use the record separator for delimiting components of the cache key to avoid possible collisions
private static readonly char KeyDelimiter = '\x1e'; private static readonly char KeyDelimiter = '\x1e';
private readonly ObjectPool<StringBuilder> _builderPool; private readonly ObjectPool<StringBuilder> _builderPool;
private readonly ResponseCachingOptions _options; private readonly ResponseCacheOptions _options;
public CacheKeyProvider(ObjectPoolProvider poolProvider, IOptions<ResponseCachingOptions> options) public ResponseCacheKeyProvider(ObjectPoolProvider poolProvider, IOptions<ResponseCacheOptions> options)
{ {
if (poolProvider == null) if (poolProvider == null)
{ {
@ -35,18 +35,13 @@ namespace Microsoft.AspNetCore.ResponseCaching
_options = options.Value; _options = options.Value;
} }
public virtual IEnumerable<string> CreateLookupBaseKeys(ResponseCachingContext context) public virtual IEnumerable<string> CreateLookupVaryByKeys(ResponseCacheContext context)
{ {
return new string[] { CreateStorageBaseKey(context) }; return new string[] { CreateStorageVaryByKey(context) };
}
public virtual IEnumerable<string> CreateLookupVaryKeys(ResponseCachingContext context)
{
return new string[] { CreateStorageVaryKey(context) };
} }
// GET<delimiter>/PATH // GET<delimiter>/PATH
public virtual string CreateStorageBaseKey(ResponseCachingContext context) public virtual string CreateBaseKey(ResponseCacheContext context)
{ {
if (context == null) if (context == null)
{ {
@ -61,7 +56,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
builder builder
.Append(request.Method.ToUpperInvariant()) .Append(request.Method.ToUpperInvariant())
.Append(KeyDelimiter) .Append(KeyDelimiter)
.Append(_options.CaseSensitivePaths ? request.Path.Value : request.Path.Value.ToUpperInvariant()); .Append(_options.UseCaseSensitivePaths ? request.Path.Value : request.Path.Value.ToUpperInvariant());
return builder.ToString();; return builder.ToString();;
} }
@ -72,22 +67,22 @@ namespace Microsoft.AspNetCore.ResponseCaching
} }
// BaseKey<delimiter>H<delimiter>HeaderName=HeaderValue<delimiter>Q<delimiter>QueryName=QueryValue // BaseKey<delimiter>H<delimiter>HeaderName=HeaderValue<delimiter>Q<delimiter>QueryName=QueryValue
public virtual string CreateStorageVaryKey(ResponseCachingContext context) public virtual string CreateStorageVaryByKey(ResponseCacheContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
var varyRules = context.CachedVaryRules; var varyByRules = context.CachedVaryByRules;
if (varyRules == null) if (varyByRules == null)
{ {
throw new InvalidOperationException($"{nameof(CachedVaryRules)} must not be null on the {nameof(ResponseCachingContext)}"); throw new InvalidOperationException($"{nameof(CachedVaryByRules)} must not be null on the {nameof(ResponseCacheContext)}");
} }
if ((StringValues.IsNullOrEmpty(varyRules.Headers) && StringValues.IsNullOrEmpty(varyRules.Params))) if ((StringValues.IsNullOrEmpty(varyByRules.Headers) && StringValues.IsNullOrEmpty(varyByRules.Params)))
{ {
return varyRules.VaryKeyPrefix; return varyByRules.VaryByKeyPrefix;
} }
var request = context.HttpContext.Request; var request = context.HttpContext.Request;
@ -95,17 +90,17 @@ namespace Microsoft.AspNetCore.ResponseCaching
try try
{ {
// Prepend with the Guid of the CachedVaryRules // Prepend with the Guid of the CachedVaryByRules
builder.Append(varyRules.VaryKeyPrefix); builder.Append(varyByRules.VaryByKeyPrefix);
// Vary by headers // Vary by headers
if (varyRules?.Headers.Count > 0) if (varyByRules?.Headers.Count > 0)
{ {
// Append a group separator for the header segment of the cache key // Append a group separator for the header segment of the cache key
builder.Append(KeyDelimiter) builder.Append(KeyDelimiter)
.Append('H'); .Append('H');
foreach (var header in varyRules.Headers) foreach (var header in varyByRules.Headers)
{ {
builder.Append(KeyDelimiter) builder.Append(KeyDelimiter)
.Append(header) .Append(header)
@ -116,13 +111,13 @@ namespace Microsoft.AspNetCore.ResponseCaching
} }
// Vary by query params // Vary by query params
if (varyRules?.Params.Count > 0) if (varyByRules?.Params.Count > 0)
{ {
// Append a group separator for the query parameter segment of the cache key // Append a group separator for the query parameter segment of the cache key
builder.Append(KeyDelimiter) builder.Append(KeyDelimiter)
.Append('Q'); .Append('Q');
if (varyRules.Params.Count == 1 && string.Equals(varyRules.Params[0], "*", StringComparison.Ordinal)) if (varyByRules.Params.Count == 1 && string.Equals(varyByRules.Params[0], "*", StringComparison.Ordinal))
{ {
// Vary by all available query params // Vary by all available query params
foreach (var query in context.HttpContext.Request.Query.OrderBy(q => q.Key, StringComparer.OrdinalIgnoreCase)) foreach (var query in context.HttpContext.Request.Query.OrderBy(q => q.Key, StringComparer.OrdinalIgnoreCase))
@ -135,7 +130,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
} }
else else
{ {
foreach (var param in varyRules.Params) foreach (var param in varyByRules.Params)
{ {
builder.Append(KeyDelimiter) builder.Append(KeyDelimiter)
.Append(param) .Append(param)

View File

@ -16,63 +16,63 @@ using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.ResponseCaching namespace Microsoft.AspNetCore.ResponseCaching
{ {
public class ResponseCachingMiddleware public class ResponseCacheMiddleware
{ {
private static readonly TimeSpan DefaultExpirationTimeSpan = TimeSpan.FromSeconds(10); private static readonly TimeSpan DefaultExpirationTimeSpan = TimeSpan.FromSeconds(10);
private readonly RequestDelegate _next; private readonly RequestDelegate _next;
private readonly IResponseCache _cache; private readonly IResponseCacheStore _store;
private readonly ResponseCachingOptions _options; private readonly ResponseCacheOptions _options;
private readonly ICacheabilityValidator _cacheabilityValidator; private readonly IResponseCachePolicyProvider _policyProvider;
private readonly ICacheKeyProvider _cacheKeyProvider; private readonly IResponseCacheKeyProvider _keyProvider;
private readonly Func<object, Task> _onStartingCallback; private readonly Func<object, Task> _onStartingCallback;
public ResponseCachingMiddleware( public ResponseCacheMiddleware(
RequestDelegate next, RequestDelegate next,
IResponseCache cache, IResponseCacheStore store,
IOptions<ResponseCachingOptions> options, IOptions<ResponseCacheOptions> options,
ICacheabilityValidator cacheabilityValidator, IResponseCachePolicyProvider policyProvider,
ICacheKeyProvider cacheKeyProvider) IResponseCacheKeyProvider keyProvider)
{ {
if (next == null) if (next == null)
{ {
throw new ArgumentNullException(nameof(next)); throw new ArgumentNullException(nameof(next));
} }
if (cache == null) if (store == null)
{ {
throw new ArgumentNullException(nameof(cache)); throw new ArgumentNullException(nameof(store));
} }
if (options == null) if (options == null)
{ {
throw new ArgumentNullException(nameof(options)); throw new ArgumentNullException(nameof(options));
} }
if (cacheabilityValidator == null) if (policyProvider == null)
{ {
throw new ArgumentNullException(nameof(cacheabilityValidator)); throw new ArgumentNullException(nameof(policyProvider));
} }
if (cacheKeyProvider == null) if (keyProvider == null)
{ {
throw new ArgumentNullException(nameof(cacheKeyProvider)); throw new ArgumentNullException(nameof(keyProvider));
} }
_next = next; _next = next;
_cache = cache; _store = store;
_options = options.Value; _options = options.Value;
_cacheabilityValidator = cacheabilityValidator; _policyProvider = policyProvider;
_cacheKeyProvider = cacheKeyProvider; _keyProvider = keyProvider;
_onStartingCallback = state => _onStartingCallback = state =>
{ {
OnResponseStarting((ResponseCachingContext)state); OnResponseStarting((ResponseCacheContext)state);
return TaskCache.CompletedTask; return TaskCache.CompletedTask;
}; };
} }
public async Task Invoke(HttpContext httpContext) public async Task Invoke(HttpContext httpContext)
{ {
var context = new ResponseCachingContext(httpContext); var context = new ResponseCacheContext(httpContext);
// Should we attempt any caching logic? // Should we attempt any caching logic?
if (_cacheabilityValidator.IsRequestCacheable(context)) if (_policyProvider.IsRequestCacheable(context))
{ {
// Can this request be served from cache? // Can this request be served from cache?
if (await TryServeFromCacheAsync(context)) if (await TryServeFromCacheAsync(context))
@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
OnResponseStarting(context); OnResponseStarting(context);
// Finalize the cache entry // Finalize the cache entry
FinalizeCachingBody(context); FinalizeCacheBody(context);
} }
finally finally
{ {
@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
} }
} }
internal async Task<bool> TryServeCachedResponseAsync(ResponseCachingContext context, CachedResponse cachedResponse) internal async Task<bool> TryServeCachedResponseAsync(ResponseCacheContext context, CachedResponse cachedResponse)
{ {
context.CachedResponse = cachedResponse; context.CachedResponse = cachedResponse;
context.CachedResponseHeaders = new ResponseHeaders(cachedResponse.Headers); context.CachedResponseHeaders = new ResponseHeaders(cachedResponse.Headers);
@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
var cachedEntryAge = context.ResponseTime - context.CachedResponse.Created; var cachedEntryAge = context.ResponseTime - context.CachedResponse.Created;
context.CachedEntryAge = cachedEntryAge > TimeSpan.Zero ? cachedEntryAge : TimeSpan.Zero; context.CachedEntryAge = cachedEntryAge > TimeSpan.Zero ? cachedEntryAge : TimeSpan.Zero;
if (_cacheabilityValidator.IsCachedEntryFresh(context)) if (_policyProvider.IsCachedEntryFresh(context))
{ {
// Check conditional request rules // Check conditional request rules
if (ConditionalRequestSatisfied(context)) if (ConditionalRequestSatisfied(context))
@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
response.Headers[HeaderNames.Age] = context.CachedEntryAge.TotalSeconds.ToString("F0", CultureInfo.InvariantCulture); response.Headers[HeaderNames.Age] = context.CachedEntryAge.TotalSeconds.ToString("F0", CultureInfo.InvariantCulture);
var body = context.CachedResponse.Body ?? var body = context.CachedResponse.Body ??
((CachedResponseBody)_cache.Get(context.CachedResponse.BodyKeyPrefix))?.Body; ((CachedResponseBody)_store.Get(context.CachedResponse.BodyKeyPrefix))?.Body;
// If the body is not found, something went wrong. // If the body is not found, something went wrong.
if (body == null) if (body == null)
@ -166,32 +166,30 @@ namespace Microsoft.AspNetCore.ResponseCaching
return false; return false;
} }
internal async Task<bool> TryServeFromCacheAsync(ResponseCachingContext context) internal async Task<bool> TryServeFromCacheAsync(ResponseCacheContext context)
{ {
foreach (var baseKey in _cacheKeyProvider.CreateLookupBaseKeys(context)) context.BaseKey = _keyProvider.CreateBaseKey(context);
var cacheEntry = _store.Get(context.BaseKey);
if (cacheEntry is CachedVaryByRules)
{ {
var cacheEntry = _cache.Get(baseKey); // Request contains vary rules, recompute key(s) and try again
context.CachedVaryByRules = (CachedVaryByRules)cacheEntry;
if (cacheEntry is CachedVaryRules) foreach (var varyKey in _keyProvider.CreateLookupVaryByKeys(context))
{ {
// Request contains vary rules, recompute key(s) and try again cacheEntry = _store.Get(varyKey);
context.CachedVaryRules = (CachedVaryRules)cacheEntry;
foreach (var varyKey in _cacheKeyProvider.CreateLookupVaryKeys(context)) if (cacheEntry is CachedResponse && await TryServeCachedResponseAsync(context, (CachedResponse)cacheEntry))
{ {
cacheEntry = _cache.Get(varyKey); return true;
if (cacheEntry is CachedResponse && await TryServeCachedResponseAsync(context, (CachedResponse)cacheEntry))
{
return true;
}
} }
} }
}
if (cacheEntry is CachedResponse && await TryServeCachedResponseAsync(context, (CachedResponse)cacheEntry)) if (cacheEntry is CachedResponse && await TryServeCachedResponseAsync(context, (CachedResponse)cacheEntry))
{ {
return true; return true;
}
} }
@ -204,17 +202,17 @@ namespace Microsoft.AspNetCore.ResponseCaching
return false; return false;
} }
internal void FinalizeCachingHeaders(ResponseCachingContext context) internal void FinalizeCacheHeaders(ResponseCacheContext context)
{ {
if (_cacheabilityValidator.IsResponseCacheable(context)) if (_policyProvider.IsResponseCacheable(context))
{ {
context.ShouldCacheResponse = true; context.ShouldCacheResponse = true;
context.StorageBaseKey = _cacheKeyProvider.CreateStorageBaseKey(context); context.BaseKey = _keyProvider.CreateBaseKey(context);
// Create the cache entry now // Create the cache entry now
var response = context.HttpContext.Response; var response = context.HttpContext.Response;
var varyHeaderValue = response.Headers[HeaderNames.Vary]; var varyHeaderValue = response.Headers[HeaderNames.Vary];
var varyParamsValue = context.HttpContext.GetResponseCachingFeature()?.VaryParams ?? StringValues.Empty; var varyParamsValue = context.HttpContext.GetResponseCacheFeature()?.VaryByParams ?? StringValues.Empty;
context.CachedResponseValidFor = context.ResponseCacheControlHeaderValue.SharedMaxAge ?? context.CachedResponseValidFor = context.ResponseCacheControlHeaderValue.SharedMaxAge ??
context.ResponseCacheControlHeaderValue.MaxAge ?? context.ResponseCacheControlHeaderValue.MaxAge ??
(context.TypedResponseHeaders.Expires - context.ResponseTime) ?? (context.TypedResponseHeaders.Expires - context.ResponseTime) ??
@ -228,21 +226,21 @@ namespace Microsoft.AspNetCore.ResponseCaching
var normalizedVaryParamsValue = GetNormalizedStringValues(varyParamsValue); var normalizedVaryParamsValue = GetNormalizedStringValues(varyParamsValue);
// Update vary rules if they are different // Update vary rules if they are different
if (context.CachedVaryRules == null || if (context.CachedVaryByRules == null ||
!StringValues.Equals(context.CachedVaryRules.Params, normalizedVaryParamsValue) || !StringValues.Equals(context.CachedVaryByRules.Params, normalizedVaryParamsValue) ||
!StringValues.Equals(context.CachedVaryRules.Headers, normalizedVaryHeaderValue)) !StringValues.Equals(context.CachedVaryByRules.Headers, normalizedVaryHeaderValue))
{ {
context.CachedVaryRules = new CachedVaryRules context.CachedVaryByRules = new CachedVaryByRules
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Headers = normalizedVaryHeaderValue, Headers = normalizedVaryHeaderValue,
Params = normalizedVaryParamsValue Params = normalizedVaryParamsValue
}; };
_cache.Set(context.StorageBaseKey, context.CachedVaryRules, context.CachedResponseValidFor); _store.Set(context.BaseKey, context.CachedVaryByRules, context.CachedResponseValidFor);
} }
context.StorageVaryKey = _cacheKeyProvider.CreateStorageVaryKey(context); context.StorageVaryKey = _keyProvider.CreateStorageVaryByKey(context);
} }
// Ensure date header is set // Ensure date header is set
@ -273,7 +271,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
} }
} }
internal void FinalizeCachingBody(ResponseCachingContext context) internal void FinalizeCacheBody(ResponseCacheContext context)
{ {
if (context.ShouldCacheResponse && if (context.ShouldCacheResponse &&
context.ResponseCacheStream.BufferingEnabled && context.ResponseCacheStream.BufferingEnabled &&
@ -283,36 +281,36 @@ namespace Microsoft.AspNetCore.ResponseCaching
if (context.ResponseCacheStream.BufferedStream.Length >= _options.MinimumSplitBodySize) if (context.ResponseCacheStream.BufferedStream.Length >= _options.MinimumSplitBodySize)
{ {
// Store response and response body separately // Store response and response body separately
_cache.Set(context.StorageVaryKey ?? context.StorageBaseKey, context.CachedResponse, context.CachedResponseValidFor); _store.Set(context.StorageVaryKey ?? context.BaseKey, context.CachedResponse, context.CachedResponseValidFor);
var cachedResponseBody = new CachedResponseBody() var cachedResponseBody = new CachedResponseBody()
{ {
Body = context.ResponseCacheStream.BufferedStream.ToArray() Body = context.ResponseCacheStream.BufferedStream.ToArray()
}; };
_cache.Set(context.CachedResponse.BodyKeyPrefix, cachedResponseBody, context.CachedResponseValidFor); _store.Set(context.CachedResponse.BodyKeyPrefix, cachedResponseBody, context.CachedResponseValidFor);
} }
else else
{ {
// Store response and response body together // Store response and response body together
context.CachedResponse.Body = context.ResponseCacheStream.BufferedStream.ToArray(); context.CachedResponse.Body = context.ResponseCacheStream.BufferedStream.ToArray();
_cache.Set(context.StorageVaryKey ?? context.StorageBaseKey, context.CachedResponse, context.CachedResponseValidFor); _store.Set(context.StorageVaryKey ?? context.BaseKey, context.CachedResponse, context.CachedResponseValidFor);
} }
} }
} }
internal void OnResponseStarting(ResponseCachingContext context) internal void OnResponseStarting(ResponseCacheContext context)
{ {
if (!context.ResponseStarted) if (!context.ResponseStarted)
{ {
context.ResponseStarted = true; context.ResponseStarted = true;
context.ResponseTime = _options.SystemClock.UtcNow; context.ResponseTime = _options.SystemClock.UtcNow;
FinalizeCachingHeaders(context); FinalizeCacheHeaders(context);
} }
} }
internal void ShimResponseStream(ResponseCachingContext context) internal void ShimResponseStream(ResponseCacheContext context)
{ {
// TODO: Consider caching large responses on disk and serving them from there. // TODO: Consider caching large responses on disk and serving them from there.
@ -329,10 +327,10 @@ namespace Microsoft.AspNetCore.ResponseCaching
} }
// TODO: Move this temporary interface with endpoint to HttpAbstractions // TODO: Move this temporary interface with endpoint to HttpAbstractions
context.HttpContext.AddResponseCachingFeature(); context.HttpContext.AddResponseCacheFeature();
} }
internal static void UnshimResponseStream(ResponseCachingContext context) internal static void UnshimResponseStream(ResponseCacheContext context)
{ {
// Unshim response stream // Unshim response stream
context.HttpContext.Response.Body = context.OriginalResponseStream; context.HttpContext.Response.Body = context.OriginalResponseStream;
@ -341,10 +339,10 @@ namespace Microsoft.AspNetCore.ResponseCaching
context.HttpContext.Features.Set(context.OriginalSendFileFeature); context.HttpContext.Features.Set(context.OriginalSendFileFeature);
// TODO: Move this temporary interface with endpoint to HttpAbstractions // TODO: Move this temporary interface with endpoint to HttpAbstractions
context.HttpContext.RemoveResponseCachingFeature(); context.HttpContext.RemoveResponseCacheFeature();
} }
internal static bool ConditionalRequestSatisfied(ResponseCachingContext context) internal static bool ConditionalRequestSatisfied(ResponseCacheContext context)
{ {
var cachedResponseHeaders = context.CachedResponseHeaders; var cachedResponseHeaders = context.CachedResponseHeaders;
var ifNoneMatchHeader = context.TypedRequestHeaders.IfNoneMatch; var ifNoneMatchHeader = context.TypedRequestHeaders.IfNoneMatch;

View File

@ -6,7 +6,7 @@ using Microsoft.AspNetCore.ResponseCaching.Internal;
namespace Microsoft.AspNetCore.Builder namespace Microsoft.AspNetCore.Builder
{ {
public class ResponseCachingOptions public class ResponseCacheOptions
{ {
/// <summary> /// <summary>
/// The largest cacheable size for the response body in bytes. The default is set to 1 MB. /// The largest cacheable size for the response body in bytes. The default is set to 1 MB.
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Builder
/// <summary> /// <summary>
/// <c>true</c> if request paths are case-sensitive; otherwise <c>false</c>. The default is to treat paths as case-insensitive. /// <c>true</c> if request paths are case-sensitive; otherwise <c>false</c>. The default is to treat paths as case-insensitive.
/// </summary> /// </summary>
public bool CaseSensitivePaths { get; set; } = false; public bool UseCaseSensitivePaths { get; set; } = false;
/// <summary> /// <summary>
/// The smallest size in bytes for which the headers and body of the response will be stored separately. The default is set to 70 KB. /// The smallest size in bytes for which the headers and body of the response will be stored separately. The default is set to 70 KB.

View File

@ -3,17 +3,16 @@
using System; using System;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Headers;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.ResponseCaching namespace Microsoft.AspNetCore.ResponseCaching
{ {
public class CacheabilityValidator : ICacheabilityValidator public class ResponseCachePolicyProvider : IResponseCachePolicyProvider
{ {
private static readonly CacheControlHeaderValue EmptyCacheControl = new CacheControlHeaderValue(); private static readonly CacheControlHeaderValue EmptyCacheControl = new CacheControlHeaderValue();
public virtual bool IsRequestCacheable(ResponseCachingContext context) public virtual bool IsRequestCacheable(ResponseCacheContext context)
{ {
// Verify the method // Verify the method
// TODO: RFC lists POST as a cacheable method when explicit freshness information is provided, but this is not widely implemented. Will revisit. // TODO: RFC lists POST as a cacheable method when explicit freshness information is provided, but this is not widely implemented. Will revisit.
@ -57,7 +56,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
return true; return true;
} }
public virtual bool IsResponseCacheable(ResponseCachingContext context) public virtual bool IsResponseCacheable(ResponseCacheContext context)
{ {
// Only cache pages explicitly marked with public // Only cache pages explicitly marked with public
// TODO: Consider caching responses that are not marked as public but otherwise cacheable? // TODO: Consider caching responses that are not marked as public but otherwise cacheable?
@ -150,7 +149,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
return true; return true;
} }
public virtual bool IsCachedEntryFresh(ResponseCachingContext context) public virtual bool IsCachedEntryFresh(ResponseCacheContext context)
{ {
var age = context.CachedEntryAge; var age = context.CachedEntryAge;
var cachedControlHeaders = context.CachedResponseHeaders.CacheControl ?? EmptyCacheControl; var cachedControlHeaders = context.CachedResponseHeaders.CacheControl ?? EmptyCacheControl;

View File

@ -77,67 +77,67 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
} }
[Fact] [Fact]
public void RoundTrip_CachedVaryRule_EmptyRules_Succeeds() public void RoundTrip_CachedVaryByRule_EmptyRules_Succeeds()
{ {
var cachedVaryRule = new CachedVaryRules() var cachedVaryByRule = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString VaryByKeyPrefix = FastGuid.NewGuid().IdString
}; };
AssertCachedVaryRuleEqual(cachedVaryRule, (CachedVaryRules)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedVaryRule))); AssertCachedVaryByRuleEqual(cachedVaryByRule, (CachedVaryByRules)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedVaryByRule)));
} }
[Fact] [Fact]
public void RoundTrip_CachedVaryRule_HeadersOnly_Succeeds() public void RoundTrip_CachedVaryByRule_HeadersOnly_Succeeds()
{ {
var headers = new[] { "headerA", "headerB" }; var headers = new[] { "headerA", "headerB" };
var cachedVaryRule = new CachedVaryRules() var cachedVaryByRule = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Headers = headers Headers = headers
}; };
AssertCachedVaryRuleEqual(cachedVaryRule, (CachedVaryRules)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedVaryRule))); AssertCachedVaryByRuleEqual(cachedVaryByRule, (CachedVaryByRules)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedVaryByRule)));
} }
[Fact] [Fact]
public void RoundTrip_CachedVaryRule_ParamsOnly_Succeeds() public void RoundTrip_CachedVaryByRule_ParamsOnly_Succeeds()
{ {
var param = new[] { "paramA", "paramB" }; var param = new[] { "paramA", "paramB" };
var cachedVaryRule = new CachedVaryRules() var cachedVaryByRule = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Params = param Params = param
}; };
AssertCachedVaryRuleEqual(cachedVaryRule, (CachedVaryRules)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedVaryRule))); AssertCachedVaryByRuleEqual(cachedVaryByRule, (CachedVaryByRules)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedVaryByRule)));
} }
[Fact] [Fact]
public void RoundTrip_CachedVaryRule_HeadersAndParams_Succeeds() public void RoundTrip_CachedVaryByRule_HeadersAndParams_Succeeds()
{ {
var headers = new[] { "headerA", "headerB" }; var headers = new[] { "headerA", "headerB" };
var param = new[] { "paramA", "paramB" }; var param = new[] { "paramA", "paramB" };
var cachedVaryRule = new CachedVaryRules() var cachedVaryByRule = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Headers = headers, Headers = headers,
Params = param Params = param
}; };
AssertCachedVaryRuleEqual(cachedVaryRule, (CachedVaryRules)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedVaryRule))); AssertCachedVaryByRuleEqual(cachedVaryByRule, (CachedVaryByRules)CacheEntrySerializer.Deserialize(CacheEntrySerializer.Serialize(cachedVaryByRule)));
} }
[Fact] [Fact]
public void Deserialize_InvalidEntries_ReturnsNull() public void Deserialize_InvalidEntries_ReturnsNull()
{ {
var headers = new[] { "headerA", "headerB" }; var headers = new[] { "headerA", "headerB" };
var cachedVaryRule = new CachedVaryRules() var cachedVaryByRule = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Headers = headers Headers = headers
}; };
var serializedEntry = CacheEntrySerializer.Serialize(cachedVaryRule); var serializedEntry = CacheEntrySerializer.Serialize(cachedVaryByRule);
Array.Reverse(serializedEntry); Array.Reverse(serializedEntry);
Assert.Null(CacheEntrySerializer.Deserialize(serializedEntry)); Assert.Null(CacheEntrySerializer.Deserialize(serializedEntry));
@ -170,11 +170,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
} }
} }
private static void AssertCachedVaryRuleEqual(CachedVaryRules expected, CachedVaryRules actual) private static void AssertCachedVaryByRuleEqual(CachedVaryByRules expected, CachedVaryByRules actual)
{ {
Assert.NotNull(actual); Assert.NotNull(actual);
Assert.NotNull(expected); Assert.NotNull(expected);
Assert.Equal(expected.VaryKeyPrefix, actual.VaryKeyPrefix); Assert.Equal(expected.VaryByKeyPrefix, actual.VaryByKeyPrefix);
Assert.Equal(expected.Headers, actual.Headers); Assert.Equal(expected.Headers, actual.Headers);
Assert.Equal(expected.Params, actual.Params); Assert.Equal(expected.Params, actual.Params);
} }

View File

@ -11,15 +11,15 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
public class HttpContextInternalExtensionTests public class HttpContextInternalExtensionTests
{ {
[Fact] [Fact]
public void AddingSecondResponseCachingFeature_Throws() public void AddingSecondResponseCacheFeature_Throws()
{ {
var httpContext = new DefaultHttpContext(); var httpContext = new DefaultHttpContext();
// Should not throw // Should not throw
httpContext.AddResponseCachingFeature(); httpContext.AddResponseCacheFeature();
// Should throw // Should throw
Assert.ThrowsAny<InvalidOperationException>(() => httpContext.AddResponseCachingFeature()); Assert.ThrowsAny<InvalidOperationException>(() => httpContext.AddResponseCacheFeature());
} }
} }
} }

View File

@ -9,12 +9,12 @@ using Xunit;
namespace Microsoft.AspNetCore.ResponseCaching.Tests namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
public class DefaultKeyProviderTests public class ResponseCacheKeyProviderTests
{ {
private static readonly char KeyDelimiter = '\x1e'; private static readonly char KeyDelimiter = '\x1e';
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageBaseKey_IncludesOnlyNormalizedMethodAndPath() public void ResponseCacheKeyProvider_CreateStorageBaseKey_IncludesOnlyNormalizedMethodAndPath()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(); var cacheKeyProvider = TestUtils.CreateTestKeyProvider();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -25,142 +25,142 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.HttpContext.Request.PathBase = "/pathBase"; context.HttpContext.Request.PathBase = "/pathBase";
context.HttpContext.Request.QueryString = new QueryString("?query.Key=a&query.Value=b"); context.HttpContext.Request.QueryString = new QueryString("?query.Key=a&query.Value=b");
Assert.Equal($"HEAD{KeyDelimiter}/PATH/SUBPATH", cacheKeyProvider.CreateStorageBaseKey(context)); Assert.Equal($"HEAD{KeyDelimiter}/PATH/SUBPATH", cacheKeyProvider.CreateBaseKey(context));
} }
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageBaseKey_CaseInsensitivePath_NormalizesPath() public void ResponseCacheKeyProvider_CreateStorageBaseKey_CaseInsensitivePath_NormalizesPath()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(new ResponseCachingOptions() var cacheKeyProvider = TestUtils.CreateTestKeyProvider(new ResponseCacheOptions()
{ {
CaseSensitivePaths = false UseCaseSensitivePaths = false
}); });
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Method = "GET"; context.HttpContext.Request.Method = "GET";
context.HttpContext.Request.Path = "/Path"; context.HttpContext.Request.Path = "/Path";
Assert.Equal($"GET{KeyDelimiter}/PATH", cacheKeyProvider.CreateStorageBaseKey(context)); Assert.Equal($"GET{KeyDelimiter}/PATH", cacheKeyProvider.CreateBaseKey(context));
} }
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageBaseKey_CaseSensitivePath_PreservesPathCase() public void ResponseCacheKeyProvider_CreateStorageBaseKey_CaseSensitivePath_PreservesPathCase()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(new ResponseCachingOptions() var cacheKeyProvider = TestUtils.CreateTestKeyProvider(new ResponseCacheOptions()
{ {
CaseSensitivePaths = true UseCaseSensitivePaths = true
}); });
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Method = "GET"; context.HttpContext.Request.Method = "GET";
context.HttpContext.Request.Path = "/Path"; context.HttpContext.Request.Path = "/Path";
Assert.Equal($"GET{KeyDelimiter}/Path", cacheKeyProvider.CreateStorageBaseKey(context)); Assert.Equal($"GET{KeyDelimiter}/Path", cacheKeyProvider.CreateBaseKey(context));
} }
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageVaryKey_Throws_IfVaryRulesIsNull() public void ResponseCacheKeyProvider_CreateStorageVaryByKey_Throws_IfVaryByRulesIsNull()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(); var cacheKeyProvider = TestUtils.CreateTestKeyProvider();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
Assert.Throws<InvalidOperationException>(() => cacheKeyProvider.CreateStorageVaryKey(context)); Assert.Throws<InvalidOperationException>(() => cacheKeyProvider.CreateStorageVaryByKey(context));
} }
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageVaryKey_ReturnsCachedVaryGuid_IfVaryRulesIsEmpty() public void ResponseCacheKeyProvider_CreateStorageVaryKey_ReturnsCachedVaryByGuid_IfVaryByRulesIsEmpty()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(); var cacheKeyProvider = TestUtils.CreateTestKeyProvider();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.CachedVaryRules = new CachedVaryRules() context.CachedVaryByRules = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString VaryByKeyPrefix = FastGuid.NewGuid().IdString
}; };
Assert.Equal($"{context.CachedVaryRules.VaryKeyPrefix}", cacheKeyProvider.CreateStorageVaryKey(context)); Assert.Equal($"{context.CachedVaryByRules.VaryByKeyPrefix}", cacheKeyProvider.CreateStorageVaryByKey(context));
} }
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageVaryKey_IncludesListedHeadersOnly() public void ResponseCacheKeyProvider_CreateStorageVaryKey_IncludesListedHeadersOnly()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(); var cacheKeyProvider = TestUtils.CreateTestKeyProvider();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Headers["HeaderA"] = "ValueA"; context.HttpContext.Request.Headers["HeaderA"] = "ValueA";
context.HttpContext.Request.Headers["HeaderB"] = "ValueB"; context.HttpContext.Request.Headers["HeaderB"] = "ValueB";
context.CachedVaryRules = new CachedVaryRules() context.CachedVaryByRules = new CachedVaryByRules()
{ {
Headers = new string[] { "HeaderA", "HeaderC" } Headers = new string[] { "HeaderA", "HeaderC" }
}; };
Assert.Equal($"{context.CachedVaryRules.VaryKeyPrefix}{KeyDelimiter}H{KeyDelimiter}HeaderA=ValueA{KeyDelimiter}HeaderC=", Assert.Equal($"{context.CachedVaryByRules.VaryByKeyPrefix}{KeyDelimiter}H{KeyDelimiter}HeaderA=ValueA{KeyDelimiter}HeaderC=",
cacheKeyProvider.CreateStorageVaryKey(context)); cacheKeyProvider.CreateStorageVaryByKey(context));
} }
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageVaryKey_IncludesListedParamsOnly() public void ResponseCacheKeyProvider_CreateStorageVaryKey_IncludesListedParamsOnly()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(); var cacheKeyProvider = TestUtils.CreateTestKeyProvider();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.QueryString = new QueryString("?ParamA=ValueA&ParamB=ValueB"); context.HttpContext.Request.QueryString = new QueryString("?ParamA=ValueA&ParamB=ValueB");
context.CachedVaryRules = new CachedVaryRules() context.CachedVaryByRules = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Params = new string[] { "ParamA", "ParamC" } Params = new string[] { "ParamA", "ParamC" }
}; };
Assert.Equal($"{context.CachedVaryRules.VaryKeyPrefix}{KeyDelimiter}Q{KeyDelimiter}ParamA=ValueA{KeyDelimiter}ParamC=", Assert.Equal($"{context.CachedVaryByRules.VaryByKeyPrefix}{KeyDelimiter}Q{KeyDelimiter}ParamA=ValueA{KeyDelimiter}ParamC=",
cacheKeyProvider.CreateStorageVaryKey(context)); cacheKeyProvider.CreateStorageVaryByKey(context));
} }
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageVaryKey_IncludesParams_ParamNameCaseInsensitive_UseParamCasing() public void ResponseCacheKeyProvider_CreateStorageVaryKey_IncludesParams_ParamNameCaseInsensitive_UseParamCasing()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(); var cacheKeyProvider = TestUtils.CreateTestKeyProvider();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.QueryString = new QueryString("?parama=ValueA&paramB=ValueB"); context.HttpContext.Request.QueryString = new QueryString("?parama=ValueA&paramB=ValueB");
context.CachedVaryRules = new CachedVaryRules() context.CachedVaryByRules = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Params = new string[] { "ParamA", "ParamC" } Params = new string[] { "ParamA", "ParamC" }
}; };
Assert.Equal($"{context.CachedVaryRules.VaryKeyPrefix}{KeyDelimiter}Q{KeyDelimiter}ParamA=ValueA{KeyDelimiter}ParamC=", Assert.Equal($"{context.CachedVaryByRules.VaryByKeyPrefix}{KeyDelimiter}Q{KeyDelimiter}ParamA=ValueA{KeyDelimiter}ParamC=",
cacheKeyProvider.CreateStorageVaryKey(context)); cacheKeyProvider.CreateStorageVaryByKey(context));
} }
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageVaryKey_IncludesAllQueryParamsGivenAsterisk() public void ResponseCacheKeyProvider_CreateStorageVaryKey_IncludesAllQueryParamsGivenAsterisk()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(); var cacheKeyProvider = TestUtils.CreateTestKeyProvider();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.QueryString = new QueryString("?ParamA=ValueA&ParamB=ValueB"); context.HttpContext.Request.QueryString = new QueryString("?ParamA=ValueA&ParamB=ValueB");
context.CachedVaryRules = new CachedVaryRules() context.CachedVaryByRules = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Params = new string[] { "*" } Params = new string[] { "*" }
}; };
// To support case insensitivity, all param keys are converted to upper case. // To support case insensitivity, all param keys are converted to upper case.
// Explicit params uses the casing specified in the setting. // Explicit params uses the casing specified in the setting.
Assert.Equal($"{context.CachedVaryRules.VaryKeyPrefix}{KeyDelimiter}Q{KeyDelimiter}PARAMA=ValueA{KeyDelimiter}PARAMB=ValueB", Assert.Equal($"{context.CachedVaryByRules.VaryByKeyPrefix}{KeyDelimiter}Q{KeyDelimiter}PARAMA=ValueA{KeyDelimiter}PARAMB=ValueB",
cacheKeyProvider.CreateStorageVaryKey(context)); cacheKeyProvider.CreateStorageVaryByKey(context));
} }
[Fact] [Fact]
public void DefaultKeyProvider_CreateStorageVaryKey_IncludesListedHeadersAndParams() public void ResponseCacheKeyProvider_CreateStorageVaryKey_IncludesListedHeadersAndParams()
{ {
var cacheKeyProvider = TestUtils.CreateTestKeyProvider(); var cacheKeyProvider = TestUtils.CreateTestKeyProvider();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Headers["HeaderA"] = "ValueA"; context.HttpContext.Request.Headers["HeaderA"] = "ValueA";
context.HttpContext.Request.Headers["HeaderB"] = "ValueB"; context.HttpContext.Request.Headers["HeaderB"] = "ValueB";
context.HttpContext.Request.QueryString = new QueryString("?ParamA=ValueA&ParamB=ValueB"); context.HttpContext.Request.QueryString = new QueryString("?ParamA=ValueA&ParamB=ValueB");
context.CachedVaryRules = new CachedVaryRules() context.CachedVaryByRules = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Headers = new string[] { "HeaderA", "HeaderC" }, Headers = new string[] { "HeaderA", "HeaderC" },
Params = new string[] { "ParamA", "ParamC" } Params = new string[] { "ParamA", "ParamC" }
}; };
Assert.Equal($"{context.CachedVaryRules.VaryKeyPrefix}{KeyDelimiter}H{KeyDelimiter}HeaderA=ValueA{KeyDelimiter}HeaderC={KeyDelimiter}Q{KeyDelimiter}ParamA=ValueA{KeyDelimiter}ParamC=", Assert.Equal($"{context.CachedVaryByRules.VaryByKeyPrefix}{KeyDelimiter}H{KeyDelimiter}HeaderA=ValueA{KeyDelimiter}HeaderC={KeyDelimiter}Q{KeyDelimiter}ParamA=ValueA{KeyDelimiter}ParamC=",
cacheKeyProvider.CreateStorageVaryKey(context)); cacheKeyProvider.CreateStorageVaryByKey(context));
} }
} }
} }

View File

@ -14,13 +14,13 @@ using Xunit;
namespace Microsoft.AspNetCore.ResponseCaching.Tests namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
public class ResponseCachingMiddlewareTests public class ResponseCacheMiddlewareTests
{ {
[Fact] [Fact]
public async Task TryServeFromCacheAsync_OnlyIfCached_Serves504() public async Task TryServeFromCacheAsync_OnlyIfCached_Serves504()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(responseCache: cache, cacheKeyProvider: new TestKeyProvider()); var middleware = TestUtils.CreateTestMiddleware(store: store, keyProvider: new TestResponseCacheKeyProvider());
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue() context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
{ {
@ -34,23 +34,23 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async Task TryServeFromCacheAsync_CachedResponseNotFound_Fails() public async Task TryServeFromCacheAsync_CachedResponseNotFound_Fails()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(responseCache: cache, cacheKeyProvider: new TestKeyProvider(new[] { "BaseKey", "BaseKey2" })); var middleware = TestUtils.CreateTestMiddleware(store: store, keyProvider: new TestResponseCacheKeyProvider("BaseKey"));
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
Assert.False(await middleware.TryServeFromCacheAsync(context)); Assert.False(await middleware.TryServeFromCacheAsync(context));
Assert.Equal(2, cache.GetCount); Assert.Equal(1, store.GetCount);
} }
[Fact] [Fact]
public async Task TryServeFromCacheAsync_CachedResponseFound_Succeeds() public async Task TryServeFromCacheAsync_CachedResponseFound_Succeeds()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(responseCache: cache, cacheKeyProvider: new TestKeyProvider(new[] { "BaseKey", "BaseKey2" })); var middleware = TestUtils.CreateTestMiddleware(store: store, keyProvider: new TestResponseCacheKeyProvider("BaseKey"));
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
cache.Set( store.Set(
"BaseKey2", "BaseKey",
new CachedResponse() new CachedResponse()
{ {
Body = new byte[0] Body = new byte[0]
@ -58,38 +58,38 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
TimeSpan.Zero); TimeSpan.Zero);
Assert.True(await middleware.TryServeFromCacheAsync(context)); Assert.True(await middleware.TryServeFromCacheAsync(context));
Assert.Equal(2, cache.GetCount); Assert.Equal(1, store.GetCount);
} }
[Fact] [Fact]
public async Task TryServeFromCacheAsync_VaryRuleFound_CachedResponseNotFound_Fails() public async Task TryServeFromCacheAsync_VaryByRuleFound_CachedResponseNotFound_Fails()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(responseCache: cache, cacheKeyProvider: new TestKeyProvider(new[] { "BaseKey", "BaseKey2" })); var middleware = TestUtils.CreateTestMiddleware(store: store, keyProvider: new TestResponseCacheKeyProvider("BaseKey"));
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
cache.Set( store.Set(
"BaseKey2", "BaseKey",
new CachedVaryRules(), new CachedVaryByRules(),
TimeSpan.Zero); TimeSpan.Zero);
Assert.False(await middleware.TryServeFromCacheAsync(context)); Assert.False(await middleware.TryServeFromCacheAsync(context));
Assert.Equal(2, cache.GetCount); Assert.Equal(1, store.GetCount);
} }
[Fact] [Fact]
public async Task TryServeFromCacheAsync_VaryRuleFound_CachedResponseFound_Succeeds() public async Task TryServeFromCacheAsync_VaryByRuleFound_CachedResponseFound_Succeeds()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(responseCache: cache, cacheKeyProvider: new TestKeyProvider(new[] { "BaseKey", "BaseKey2" }, new[] { "VaryKey", "VaryKey2" })); var middleware = TestUtils.CreateTestMiddleware(store: store, keyProvider: new TestResponseCacheKeyProvider("BaseKey", new[] { "VaryKey", "VaryKey2" }));
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
cache.Set( store.Set(
"BaseKey2", "BaseKey",
new CachedVaryRules(), new CachedVaryByRules(),
TimeSpan.Zero); TimeSpan.Zero);
cache.Set( store.Set(
"BaseKey2VaryKey2", "BaseKeyVaryKey2",
new CachedResponse() new CachedResponse()
{ {
Body = new byte[0] Body = new byte[0]
@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
TimeSpan.Zero); TimeSpan.Zero);
Assert.True(await middleware.TryServeFromCacheAsync(context)); Assert.True(await middleware.TryServeFromCacheAsync(context));
Assert.Equal(6, cache.GetCount); Assert.Equal(3, store.GetCount);
} }
[Fact] [Fact]
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary()); context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary());
Assert.False(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.False(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
} }
[Fact] [Fact]
@ -120,15 +120,15 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
// Verify modifications in the past succeeds // Verify modifications in the past succeeds
context.CachedResponseHeaders.Date = utcNow - TimeSpan.FromSeconds(10); context.CachedResponseHeaders.Date = utcNow - TimeSpan.FromSeconds(10);
Assert.True(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.True(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
// Verify modifications at present succeeds // Verify modifications at present succeeds
context.CachedResponseHeaders.Date = utcNow; context.CachedResponseHeaders.Date = utcNow;
Assert.True(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.True(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
// Verify modifications in the future fails // Verify modifications in the future fails
context.CachedResponseHeaders.Date = utcNow + TimeSpan.FromSeconds(10); context.CachedResponseHeaders.Date = utcNow + TimeSpan.FromSeconds(10);
Assert.False(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.False(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
} }
[Fact] [Fact]
@ -143,17 +143,17 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
// Verify modifications in the past succeeds // Verify modifications in the past succeeds
context.CachedResponseHeaders.Date = utcNow + TimeSpan.FromSeconds(10); context.CachedResponseHeaders.Date = utcNow + TimeSpan.FromSeconds(10);
context.CachedResponseHeaders.LastModified = utcNow - TimeSpan.FromSeconds(10); context.CachedResponseHeaders.LastModified = utcNow - TimeSpan.FromSeconds(10);
Assert.True(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.True(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
// Verify modifications at present // Verify modifications at present
context.CachedResponseHeaders.Date = utcNow + TimeSpan.FromSeconds(10); context.CachedResponseHeaders.Date = utcNow + TimeSpan.FromSeconds(10);
context.CachedResponseHeaders.LastModified = utcNow; context.CachedResponseHeaders.LastModified = utcNow;
Assert.True(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.True(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
// Verify modifications in the future fails // Verify modifications in the future fails
context.CachedResponseHeaders.Date = utcNow - TimeSpan.FromSeconds(10); context.CachedResponseHeaders.Date = utcNow - TimeSpan.FromSeconds(10);
context.CachedResponseHeaders.LastModified = utcNow + TimeSpan.FromSeconds(10); context.CachedResponseHeaders.LastModified = utcNow + TimeSpan.FromSeconds(10);
Assert.False(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.False(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
} }
[Fact] [Fact]
@ -168,7 +168,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.CachedResponseHeaders.LastModified = utcNow + TimeSpan.FromSeconds(10); context.CachedResponseHeaders.LastModified = utcNow + TimeSpan.FromSeconds(10);
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { EntityTagHeaderValue.Any }); context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { EntityTagHeaderValue.Any });
Assert.True(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.True(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
} }
[Fact] [Fact]
@ -183,7 +183,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.CachedResponseHeaders.LastModified = utcNow - TimeSpan.FromSeconds(10); context.CachedResponseHeaders.LastModified = utcNow - TimeSpan.FromSeconds(10);
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }); context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") });
Assert.False(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.False(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
} }
[Fact] [Fact]
@ -194,7 +194,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }); context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") });
Assert.False(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.False(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
} }
[Fact] [Fact]
@ -208,7 +208,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }); context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") });
Assert.True(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.True(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
} }
[Fact] [Fact]
@ -222,27 +222,27 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }); context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") });
Assert.False(ResponseCachingMiddleware.ConditionalRequestSatisfied(context)); Assert.False(ResponseCacheMiddleware.ConditionalRequestSatisfied(context));
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_DoNotUpdateShouldCacheResponse_IfResponseIsNotCacheable() public void FinalizeCacheHeaders_DoNotUpdateShouldCacheResponse_IfResponseIsNotCacheable()
{ {
var middleware = TestUtils.CreateTestMiddleware(cacheabilityValidator: new CacheabilityValidator()); var middleware = TestUtils.CreateTestMiddleware(policyProvider: new ResponseCachePolicyProvider());
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
Assert.False(context.ShouldCacheResponse); Assert.False(context.ShouldCacheResponse);
middleware.ShimResponseStream(context); middleware.ShimResponseStream(context);
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.False(context.ShouldCacheResponse); Assert.False(context.ShouldCacheResponse);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_UpdateShouldCacheResponse_IfResponseIsCacheable() public void FinalizeCacheHeaders_UpdateShouldCacheResponse_IfResponseIsCacheable()
{ {
var middleware = TestUtils.CreateTestMiddleware(cacheabilityValidator: new CacheabilityValidator()); var middleware = TestUtils.CreateTestMiddleware(policyProvider: new ResponseCachePolicyProvider());
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue() context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
{ {
@ -251,24 +251,24 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Assert.False(context.ShouldCacheResponse); Assert.False(context.ShouldCacheResponse);
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.True(context.ShouldCacheResponse); Assert.True(context.ShouldCacheResponse);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_DefaultResponseValidity_Is10Seconds() public void FinalizeCacheHeaders_DefaultResponseValidity_Is10Seconds()
{ {
var middleware = TestUtils.CreateTestMiddleware(); var middleware = TestUtils.CreateTestMiddleware();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.Equal(TimeSpan.FromSeconds(10), context.CachedResponseValidFor); Assert.Equal(TimeSpan.FromSeconds(10), context.CachedResponseValidFor);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_ResponseValidity_UseExpiryIfAvailable() public void FinalizeCacheHeaders_ResponseValidity_UseExpiryIfAvailable()
{ {
var utcNow = DateTimeOffset.MinValue; var utcNow = DateTimeOffset.MinValue;
var middleware = TestUtils.CreateTestMiddleware(); var middleware = TestUtils.CreateTestMiddleware();
@ -277,13 +277,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.ResponseTime = utcNow; context.ResponseTime = utcNow;
context.TypedResponseHeaders.Expires = utcNow + TimeSpan.FromSeconds(11); context.TypedResponseHeaders.Expires = utcNow + TimeSpan.FromSeconds(11);
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.Equal(TimeSpan.FromSeconds(11), context.CachedResponseValidFor); Assert.Equal(TimeSpan.FromSeconds(11), context.CachedResponseValidFor);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_ResponseValidity_UseMaxAgeIfAvailable() public void FinalizeCacheHeaders_ResponseValidity_UseMaxAgeIfAvailable()
{ {
var middleware = TestUtils.CreateTestMiddleware(); var middleware = TestUtils.CreateTestMiddleware();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -295,13 +295,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.ResponseTime = DateTimeOffset.UtcNow; context.ResponseTime = DateTimeOffset.UtcNow;
context.TypedResponseHeaders.Expires = context.ResponseTime + TimeSpan.FromSeconds(11); context.TypedResponseHeaders.Expires = context.ResponseTime + TimeSpan.FromSeconds(11);
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.Equal(TimeSpan.FromSeconds(12), context.CachedResponseValidFor); Assert.Equal(TimeSpan.FromSeconds(12), context.CachedResponseValidFor);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_ResponseValidity_UseSharedMaxAgeIfAvailable() public void FinalizeCacheHeaders_ResponseValidity_UseSharedMaxAgeIfAvailable()
{ {
var middleware = TestUtils.CreateTestMiddleware(); var middleware = TestUtils.CreateTestMiddleware();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -314,60 +314,60 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.ResponseTime = DateTimeOffset.UtcNow; context.ResponseTime = DateTimeOffset.UtcNow;
context.TypedResponseHeaders.Expires = context.ResponseTime + TimeSpan.FromSeconds(11); context.TypedResponseHeaders.Expires = context.ResponseTime + TimeSpan.FromSeconds(11);
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.Equal(TimeSpan.FromSeconds(13), context.CachedResponseValidFor); Assert.Equal(TimeSpan.FromSeconds(13), context.CachedResponseValidFor);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_UpdateCachedVaryRules_IfNotEquivalentToPrevious() public void FinalizeCacheHeaders_UpdateCachedVaryByRules_IfNotEquivalentToPrevious()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(cache); var middleware = TestUtils.CreateTestMiddleware(store);
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Response.Headers[HeaderNames.Vary] = new StringValues(new[] { "headerA", "HEADERB", "HEADERc" }); context.HttpContext.Response.Headers[HeaderNames.Vary] = new StringValues(new[] { "headerA", "HEADERB", "HEADERc" });
context.HttpContext.AddResponseCachingFeature(); context.HttpContext.AddResponseCacheFeature();
context.HttpContext.GetResponseCachingFeature().VaryParams = new StringValues(new[] { "paramB", "PARAMAA" }); context.HttpContext.GetResponseCacheFeature().VaryByParams = new StringValues(new[] { "paramB", "PARAMAA" });
var cachedVaryRules = new CachedVaryRules() var cachedVaryByRules = new CachedVaryByRules()
{ {
Headers = new StringValues(new[] { "HeaderA", "HeaderB" }), Headers = new StringValues(new[] { "HeaderA", "HeaderB" }),
Params = new StringValues(new[] { "ParamA", "ParamB" }) Params = new StringValues(new[] { "ParamA", "ParamB" })
}; };
context.CachedVaryRules = cachedVaryRules; context.CachedVaryByRules = cachedVaryByRules;
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.Equal(1, cache.SetCount); Assert.Equal(1, store.SetCount);
Assert.NotSame(cachedVaryRules, context.CachedVaryRules); Assert.NotSame(cachedVaryByRules, context.CachedVaryByRules);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_DoNotUpdateCachedVaryRules_IfEquivalentToPrevious() public void FinalizeCacheHeaders_DoNotUpdateCachedVaryByRules_IfEquivalentToPrevious()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(cache); var middleware = TestUtils.CreateTestMiddleware(store);
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Response.Headers[HeaderNames.Vary] = new StringValues(new[] { "headerA", "HEADERB" }); context.HttpContext.Response.Headers[HeaderNames.Vary] = new StringValues(new[] { "headerA", "HEADERB" });
context.HttpContext.AddResponseCachingFeature(); context.HttpContext.AddResponseCacheFeature();
context.HttpContext.GetResponseCachingFeature().VaryParams = new StringValues(new[] { "paramB", "PARAMA" }); context.HttpContext.GetResponseCacheFeature().VaryByParams = new StringValues(new[] { "paramB", "PARAMA" });
var cachedVaryRules = new CachedVaryRules() var cachedVaryByRules = new CachedVaryByRules()
{ {
VaryKeyPrefix = FastGuid.NewGuid().IdString, VaryByKeyPrefix = FastGuid.NewGuid().IdString,
Headers = new StringValues(new[] { "HEADERA", "HEADERB" }), Headers = new StringValues(new[] { "HEADERA", "HEADERB" }),
Params = new StringValues(new[] { "PARAMA", "PARAMB" }) Params = new StringValues(new[] { "PARAMA", "PARAMB" })
}; };
context.CachedVaryRules = cachedVaryRules; context.CachedVaryByRules = cachedVaryByRules;
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.Equal(0, cache.SetCount); Assert.Equal(0, store.SetCount);
Assert.Same(cachedVaryRules, context.CachedVaryRules); Assert.Same(cachedVaryByRules, context.CachedVaryByRules);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_DoNotAddDate_IfSpecified() public void FinalizeCacheHeaders_DoNotAddDate_IfSpecified()
{ {
var utcNow = DateTimeOffset.MinValue; var utcNow = DateTimeOffset.MinValue;
var middleware = TestUtils.CreateTestMiddleware(); var middleware = TestUtils.CreateTestMiddleware();
@ -376,13 +376,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Assert.Null(context.TypedResponseHeaders.Date); Assert.Null(context.TypedResponseHeaders.Date);
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.Equal(utcNow, context.TypedResponseHeaders.Date); Assert.Equal(utcNow, context.TypedResponseHeaders.Date);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_AddsDate_IfNoneSpecified() public void FinalizeCacheHeaders_AddsDate_IfNoneSpecified()
{ {
var utcNow = DateTimeOffset.MinValue; var utcNow = DateTimeOffset.MinValue;
var middleware = TestUtils.CreateTestMiddleware(); var middleware = TestUtils.CreateTestMiddleware();
@ -392,29 +392,29 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Assert.Equal(utcNow, context.TypedResponseHeaders.Date); Assert.Equal(utcNow, context.TypedResponseHeaders.Date);
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.Equal(utcNow, context.TypedResponseHeaders.Date); Assert.Equal(utcNow, context.TypedResponseHeaders.Date);
} }
[Fact] [Fact]
public void FinalizeCachingHeaders_StoresCachedResponse_InState() public void FinalizeCacheHeaders_StoresCachedResponse_InState()
{ {
var middleware = TestUtils.CreateTestMiddleware(); var middleware = TestUtils.CreateTestMiddleware();
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
Assert.Null(context.CachedResponse); Assert.Null(context.CachedResponse);
middleware.FinalizeCachingHeaders(context); middleware.FinalizeCacheHeaders(context);
Assert.NotNull(context.CachedResponse); Assert.NotNull(context.CachedResponse);
} }
[Fact] [Fact]
public async Task FinalizeCachingBody_StoreResponseBodySeparately_IfLargerThanLimit() public async Task FinalizeCacheBody_StoreResponseBodySeparately_IfLargerThanLimit()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(cache); var middleware = TestUtils.CreateTestMiddleware(store);
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
middleware.ShimResponseStream(context); middleware.ShimResponseStream(context);
@ -425,19 +425,19 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
BodyKeyPrefix = FastGuid.NewGuid().IdString BodyKeyPrefix = FastGuid.NewGuid().IdString
}; };
context.StorageBaseKey = "BaseKey"; context.BaseKey = "BaseKey";
context.CachedResponseValidFor = TimeSpan.FromSeconds(10); context.CachedResponseValidFor = TimeSpan.FromSeconds(10);
middleware.FinalizeCachingBody(context); middleware.FinalizeCacheBody(context);
Assert.Equal(2, cache.SetCount); Assert.Equal(2, store.SetCount);
} }
[Fact] [Fact]
public async Task FinalizeCachingBody_StoreResponseBodyInCachedResponse_IfSmallerThanLimit() public async Task FinalizeCacheBody_StoreResponseBodyInCachedResponse_IfSmallerThanLimit()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(cache); var middleware = TestUtils.CreateTestMiddleware(store);
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
middleware.ShimResponseStream(context); middleware.ShimResponseStream(context);
@ -448,19 +448,19 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
BodyKeyPrefix = FastGuid.NewGuid().IdString BodyKeyPrefix = FastGuid.NewGuid().IdString
}; };
context.StorageBaseKey = "BaseKey"; context.BaseKey = "BaseKey";
context.CachedResponseValidFor = TimeSpan.FromSeconds(10); context.CachedResponseValidFor = TimeSpan.FromSeconds(10);
middleware.FinalizeCachingBody(context); middleware.FinalizeCacheBody(context);
Assert.Equal(1, cache.SetCount); Assert.Equal(1, store.SetCount);
} }
[Fact] [Fact]
public async Task FinalizeCachingBody_StoreResponseBodySeparately_LimitIsConfigurable() public async Task FinalizeCacheBody_StoreResponseBodySeparately_LimitIsConfigurable()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(cache, new ResponseCachingOptions() var middleware = TestUtils.CreateTestMiddleware(store, new ResponseCacheOptions()
{ {
MinimumSplitBodySize = 2048 MinimumSplitBodySize = 2048
}); });
@ -474,19 +474,19 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
BodyKeyPrefix = FastGuid.NewGuid().IdString BodyKeyPrefix = FastGuid.NewGuid().IdString
}; };
context.StorageBaseKey = "BaseKey"; context.BaseKey = "BaseKey";
context.CachedResponseValidFor = TimeSpan.FromSeconds(10); context.CachedResponseValidFor = TimeSpan.FromSeconds(10);
middleware.FinalizeCachingBody(context); middleware.FinalizeCacheBody(context);
Assert.Equal(1, cache.SetCount); Assert.Equal(1, store.SetCount);
} }
[Fact] [Fact]
public async Task FinalizeCachingBody_Cache_IfContentLengthMatches() public async Task FinalizeCacheBody_Cache_IfContentLengthMatches()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(cache); var middleware = TestUtils.CreateTestMiddleware(store);
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
middleware.ShimResponseStream(context); middleware.ShimResponseStream(context);
@ -498,19 +498,19 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
BodyKeyPrefix = FastGuid.NewGuid().IdString BodyKeyPrefix = FastGuid.NewGuid().IdString
}; };
context.StorageBaseKey = "BaseKey"; context.BaseKey = "BaseKey";
context.CachedResponseValidFor = TimeSpan.FromSeconds(10); context.CachedResponseValidFor = TimeSpan.FromSeconds(10);
middleware.FinalizeCachingBody(context); middleware.FinalizeCacheBody(context);
Assert.Equal(1, cache.SetCount); Assert.Equal(1, store.SetCount);
} }
[Fact] [Fact]
public async Task FinalizeCachingBody_DoNotCache_IfContentLengthMismatches() public async Task FinalizeCacheBody_DoNotCache_IfContentLengthMismatches()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(cache); var middleware = TestUtils.CreateTestMiddleware(store);
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
middleware.ShimResponseStream(context); middleware.ShimResponseStream(context);
@ -522,19 +522,19 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
BodyKeyPrefix = FastGuid.NewGuid().IdString BodyKeyPrefix = FastGuid.NewGuid().IdString
}; };
context.StorageBaseKey = "BaseKey"; context.BaseKey = "BaseKey";
context.CachedResponseValidFor = TimeSpan.FromSeconds(10); context.CachedResponseValidFor = TimeSpan.FromSeconds(10);
middleware.FinalizeCachingBody(context); middleware.FinalizeCacheBody(context);
Assert.Equal(0, cache.SetCount); Assert.Equal(0, store.SetCount);
} }
[Fact] [Fact]
public async Task FinalizeCachingBody_Cache_IfContentLengthAbsent() public async Task FinalizeCacheBody_Cache_IfContentLengthAbsent()
{ {
var cache = new TestResponseCache(); var store = new TestResponseCacheStore();
var middleware = TestUtils.CreateTestMiddleware(cache); var middleware = TestUtils.CreateTestMiddleware(store);
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
middleware.ShimResponseStream(context); middleware.ShimResponseStream(context);
@ -545,12 +545,12 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
BodyKeyPrefix = FastGuid.NewGuid().IdString BodyKeyPrefix = FastGuid.NewGuid().IdString
}; };
context.StorageBaseKey = "BaseKey"; context.BaseKey = "BaseKey";
context.CachedResponseValidFor = TimeSpan.FromSeconds(10); context.CachedResponseValidFor = TimeSpan.FromSeconds(10);
middleware.FinalizeCachingBody(context); middleware.FinalizeCacheBody(context);
Assert.Equal(1, cache.SetCount); Assert.Equal(1, store.SetCount);
} }
[Fact] [Fact]
@ -559,7 +559,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
var uppercaseStrings = new StringValues(new[] { "STRINGA", "STRINGB" }); var uppercaseStrings = new StringValues(new[] { "STRINGA", "STRINGB" });
var lowercaseStrings = new StringValues(new[] { "stringA", "stringB" }); var lowercaseStrings = new StringValues(new[] { "stringA", "stringB" });
var normalizedStrings = ResponseCachingMiddleware.GetNormalizedStringValues(lowercaseStrings); var normalizedStrings = ResponseCacheMiddleware.GetNormalizedStringValues(lowercaseStrings);
Assert.Equal(uppercaseStrings, normalizedStrings); Assert.Equal(uppercaseStrings, normalizedStrings);
} }
@ -570,9 +570,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
var orderedStrings = new StringValues(new[] { "STRINGA", "STRINGB" }); var orderedStrings = new StringValues(new[] { "STRINGA", "STRINGB" });
var reverseOrderStrings = new StringValues(new[] { "STRINGB", "STRINGA" }); var reverseOrderStrings = new StringValues(new[] { "STRINGB", "STRINGA" });
var normalizedStrings = ResponseCachingMiddleware.GetNormalizedStringValues(reverseOrderStrings); var normalizedStrings = ResponseCacheMiddleware.GetNormalizedStringValues(reverseOrderStrings);
Assert.Equal(orderedStrings, normalizedStrings); Assert.Equal(orderedStrings, normalizedStrings);
} }
} }
} }

View File

@ -9,17 +9,17 @@ using Xunit;
namespace Microsoft.AspNetCore.ResponseCaching.Tests namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
public class CacheabilityValidatorTests public class ResponseCachePolicyProviderTests
{ {
[Theory] [Theory]
[InlineData("GET")] [InlineData("GET")]
[InlineData("HEAD")] [InlineData("HEAD")]
public void RequestIsCacheable_CacheableMethods_Allowed(string method) public void IsRequestCacheable_CacheableMethods_Allowed(string method)
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Method = method; context.HttpContext.Request.Method = method;
Assert.True(new CacheabilityValidator().IsRequestCacheable(context)); Assert.True(new ResponseCachePolicyProvider().IsRequestCacheable(context));
} }
[Theory] [Theory]
@ -31,26 +31,26 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[InlineData("CONNECT")] [InlineData("CONNECT")]
[InlineData("")] [InlineData("")]
[InlineData(null)] [InlineData(null)]
public void RequestIsCacheable_UncacheableMethods_NotAllowed(string method) public void IsRequestCacheable_UncacheableMethods_NotAllowed(string method)
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Method = method; context.HttpContext.Request.Method = method;
Assert.False(new CacheabilityValidator().IsRequestCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsRequestCacheable(context));
} }
[Fact] [Fact]
public void RequestIsCacheable_AuthorizationHeaders_NotAllowed() public void IsRequestCacheable_AuthorizationHeaders_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Method = "GET"; context.HttpContext.Request.Method = "GET";
context.HttpContext.Request.Headers[HeaderNames.Authorization] = "Basic plaintextUN:plaintextPW"; context.HttpContext.Request.Headers[HeaderNames.Authorization] = "Basic plaintextUN:plaintextPW";
Assert.False(new CacheabilityValidator().IsRequestCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsRequestCacheable(context));
} }
[Fact] [Fact]
public void RequestIsCacheable_NoCache_NotAllowed() public void IsRequestCacheable_NoCache_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Method = "GET"; context.HttpContext.Request.Method = "GET";
@ -59,11 +59,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
NoCache = true NoCache = true
}; };
Assert.False(new CacheabilityValidator().IsRequestCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsRequestCacheable(context));
} }
[Fact] [Fact]
public void RequestIsCacheable_NoStore_Allowed() public void IsRequestCacheable_NoStore_Allowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Method = "GET"; context.HttpContext.Request.Method = "GET";
@ -72,40 +72,40 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
NoStore = true NoStore = true
}; };
Assert.True(new CacheabilityValidator().IsRequestCacheable(context)); Assert.True(new ResponseCachePolicyProvider().IsRequestCacheable(context));
} }
[Fact] [Fact]
public void RequestIsCacheable_LegacyDirectives_NotAllowed() public void IsRequestCacheable_LegacyDirectives_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Method = "GET"; context.HttpContext.Request.Method = "GET";
context.HttpContext.Request.Headers[HeaderNames.Pragma] = "no-cache"; context.HttpContext.Request.Headers[HeaderNames.Pragma] = "no-cache";
Assert.False(new CacheabilityValidator().IsRequestCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsRequestCacheable(context));
} }
[Fact] [Fact]
public void RequestIsCacheable_LegacyDirectives_OverridenByCacheControl() public void IsRequestCacheable_LegacyDirectives_OverridenByCacheControl()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Request.Method = "GET"; context.HttpContext.Request.Method = "GET";
context.HttpContext.Request.Headers[HeaderNames.Pragma] = "no-cache"; context.HttpContext.Request.Headers[HeaderNames.Pragma] = "no-cache";
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = "max-age=10"; context.HttpContext.Request.Headers[HeaderNames.CacheControl] = "max-age=10";
Assert.True(new CacheabilityValidator().IsRequestCacheable(context)); Assert.True(new ResponseCachePolicyProvider().IsRequestCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_NoPublic_NotAllowed() public void IsResponseCacheable_NoPublic_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_Public_Allowed() public void IsResponseCacheable_Public_Allowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue() context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
@ -113,11 +113,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Public = true Public = true
}; };
Assert.True(new CacheabilityValidator().IsResponseCacheable(context)); Assert.True(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_NoCache_NotAllowed() public void IsResponseCacheable_NoCache_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue() context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
@ -126,11 +126,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
NoCache = true NoCache = true
}; };
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_RequestNoStore_NotAllowed() public void IsResponseCacheable_RequestNoStore_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue() context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
@ -142,11 +142,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Public = true Public = true
}; };
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_ResponseNoStore_NotAllowed() public void IsResponseCacheable_ResponseNoStore_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue() context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
@ -155,11 +155,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
NoStore = true NoStore = true
}; };
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_SetCookieHeader_NotAllowed() public void IsResponseCacheable_SetCookieHeader_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue() context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
@ -168,11 +168,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
}; };
context.HttpContext.Response.Headers[HeaderNames.SetCookie] = "cookieName=cookieValue"; context.HttpContext.Response.Headers[HeaderNames.SetCookie] = "cookieName=cookieValue";
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_VaryHeaderByStar_NotAllowed() public void IsResponseCacheable_VaryHeaderByStar_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue() context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
@ -181,11 +181,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
}; };
context.HttpContext.Response.Headers[HeaderNames.Vary] = "*"; context.HttpContext.Response.Headers[HeaderNames.Vary] = "*";
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_Private_NotAllowed() public void IsResponseCacheable_Private_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue() context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
@ -194,12 +194,12 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Private = true Private = true
}; };
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Theory] [Theory]
[InlineData(StatusCodes.Status200OK)] [InlineData(StatusCodes.Status200OK)]
public void ResponseIsCacheable_SuccessStatusCodes_Allowed(int statusCode) public void IsResponseCacheable_SuccessStatusCodes_Allowed(int statusCode)
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Response.StatusCode = statusCode; context.HttpContext.Response.StatusCode = statusCode;
@ -208,7 +208,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Public = true Public = true
}; };
Assert.True(new CacheabilityValidator().IsResponseCacheable(context)); Assert.True(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Theory] [Theory]
@ -260,7 +260,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[InlineData(StatusCodes.Status505HttpVersionNotsupported)] [InlineData(StatusCodes.Status505HttpVersionNotsupported)]
[InlineData(StatusCodes.Status506VariantAlsoNegotiates)] [InlineData(StatusCodes.Status506VariantAlsoNegotiates)]
[InlineData(StatusCodes.Status507InsufficientStorage)] [InlineData(StatusCodes.Status507InsufficientStorage)]
public void ResponseIsCacheable_NonSuccessStatusCodes_NotAllowed(int statusCode) public void IsResponseCacheable_NonSuccessStatusCodes_NotAllowed(int statusCode)
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Response.StatusCode = statusCode; context.HttpContext.Response.StatusCode = statusCode;
@ -269,11 +269,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Public = true Public = true
}; };
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_NoExpiryRequirements_IsAllowed() public void IsResponseCacheable_NoExpiryRequirements_IsAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK; context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
@ -286,11 +286,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.TypedResponseHeaders.Date = utcNow; context.TypedResponseHeaders.Date = utcNow;
context.ResponseTime = DateTimeOffset.MaxValue; context.ResponseTime = DateTimeOffset.MaxValue;
Assert.True(new CacheabilityValidator().IsResponseCacheable(context)); Assert.True(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_PastExpiry_NotAllowed() public void IsResponseCacheable_PastExpiry_NotAllowed()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK; context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
@ -304,11 +304,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.TypedResponseHeaders.Date = utcNow; context.TypedResponseHeaders.Date = utcNow;
context.ResponseTime = DateTimeOffset.MaxValue; context.ResponseTime = DateTimeOffset.MaxValue;
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_MaxAgeOverridesExpiry_ToAllowed() public void IsResponseCacheable_MaxAgeOverridesExpiry_ToAllowed()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -322,11 +322,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.TypedResponseHeaders.Date = utcNow; context.TypedResponseHeaders.Date = utcNow;
context.ResponseTime = utcNow + TimeSpan.FromSeconds(9); context.ResponseTime = utcNow + TimeSpan.FromSeconds(9);
Assert.True(new CacheabilityValidator().IsResponseCacheable(context)); Assert.True(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_MaxAgeOverridesExpiry_ToNotAllowed() public void IsResponseCacheable_MaxAgeOverridesExpiry_ToNotAllowed()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -340,11 +340,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.TypedResponseHeaders.Date = utcNow; context.TypedResponseHeaders.Date = utcNow;
context.ResponseTime = utcNow + TimeSpan.FromSeconds(11); context.ResponseTime = utcNow + TimeSpan.FromSeconds(11);
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_SharedMaxAgeOverridesMaxAge_ToAllowed() public void IsResponseCacheable_SharedMaxAgeOverridesMaxAge_ToAllowed()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -358,11 +358,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.TypedResponseHeaders.Date = utcNow; context.TypedResponseHeaders.Date = utcNow;
context.ResponseTime = utcNow + TimeSpan.FromSeconds(11); context.ResponseTime = utcNow + TimeSpan.FromSeconds(11);
Assert.True(new CacheabilityValidator().IsResponseCacheable(context)); Assert.True(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void ResponseIsCacheable_SharedMaxAgeOverridesMaxAge_ToNotFresh() public void IsResponseCacheable_SharedMaxAgeOverridesMaxAge_ToNotFresh()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -376,22 +376,22 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
context.TypedResponseHeaders.Date = utcNow; context.TypedResponseHeaders.Date = utcNow;
context.ResponseTime = utcNow + TimeSpan.FromSeconds(6); context.ResponseTime = utcNow + TimeSpan.FromSeconds(6);
Assert.False(new CacheabilityValidator().IsResponseCacheable(context)); Assert.False(new ResponseCachePolicyProvider().IsResponseCacheable(context));
} }
[Fact] [Fact]
public void EntryIsFresh_NoCachedCacheControl_FallsbackToEmptyCacheControl() public void IsCachedEntryFresh_NoCachedCacheControl_FallsbackToEmptyCacheControl()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.ResponseTime = DateTimeOffset.MaxValue; context.ResponseTime = DateTimeOffset.MaxValue;
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary()); context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary());
Assert.True(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.True(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_NoExpiryRequirements_IsFresh() public void IsCachedEntryFresh_NoExpiryRequirements_IsFresh()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -404,11 +404,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
} }
}; };
Assert.True(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.True(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_PastExpiry_IsNotFresh() public void IsCachedEntryFresh_PastExpiry_IsNotFresh()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.ResponseTime = DateTimeOffset.MaxValue; context.ResponseTime = DateTimeOffset.MaxValue;
@ -421,11 +421,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Expires = DateTimeOffset.UtcNow Expires = DateTimeOffset.UtcNow
}; };
Assert.False(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.False(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_MaxAgeOverridesExpiry_ToFresh() public void IsCachedEntryFresh_MaxAgeOverridesExpiry_ToFresh()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -441,11 +441,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Expires = utcNow Expires = utcNow
}; };
Assert.True(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.True(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_MaxAgeOverridesExpiry_ToNotFresh() public void IsCachedEntryFresh_MaxAgeOverridesExpiry_ToNotFresh()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -461,11 +461,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Expires = utcNow Expires = utcNow
}; };
Assert.False(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.False(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_SharedMaxAgeOverridesMaxAge_ToFresh() public void IsCachedEntryFresh_SharedMaxAgeOverridesMaxAge_ToFresh()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -482,11 +482,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Expires = utcNow Expires = utcNow
}; };
Assert.True(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.True(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_SharedMaxAgeOverridesMaxAge_ToNotFresh() public void IsCachedEntryFresh_SharedMaxAgeOverridesMaxAge_ToNotFresh()
{ {
var utcNow = DateTimeOffset.UtcNow; var utcNow = DateTimeOffset.UtcNow;
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
@ -503,11 +503,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
Expires = utcNow Expires = utcNow
}; };
Assert.False(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.False(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_MinFreshReducesFreshness_ToNotFresh() public void IsCachedEntryFresh_MinFreshReducesFreshness_ToNotFresh()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue() context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
@ -524,11 +524,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
}; };
context.CachedEntryAge = TimeSpan.FromSeconds(3); context.CachedEntryAge = TimeSpan.FromSeconds(3);
Assert.False(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.False(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_RequestMaxAgeRestrictAge_ToNotFresh() public void IsCachedEntryFresh_RequestMaxAgeRestrictAge_ToNotFresh()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue() context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
@ -544,11 +544,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
}; };
context.CachedEntryAge = TimeSpan.FromSeconds(6); context.CachedEntryAge = TimeSpan.FromSeconds(6);
Assert.False(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.False(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_MaxStaleOverridesFreshness_ToFresh() public void IsCachedEntryFresh_MaxStaleOverridesFreshness_ToFresh()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue() context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
@ -566,11 +566,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
}; };
context.CachedEntryAge = TimeSpan.FromSeconds(6); context.CachedEntryAge = TimeSpan.FromSeconds(6);
Assert.True(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.True(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_MustRevalidateOverridesRequestMaxStale_ToNotFresh() public void IsCachedEntryFresh_MustRevalidateOverridesRequestMaxStale_ToNotFresh()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue() context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
@ -589,11 +589,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
}; };
context.CachedEntryAge = TimeSpan.FromSeconds(6); context.CachedEntryAge = TimeSpan.FromSeconds(6);
Assert.False(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.False(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
[Fact] [Fact]
public void EntryIsFresh_IgnoresRequestVerificationWhenSpecified() public void IsCachedEntryFresh_IgnoresRequestVerificationWhenSpecified()
{ {
var context = TestUtils.CreateTestContext(); var context = TestUtils.CreateTestContext();
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue() context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
@ -611,7 +611,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
}; };
context.CachedEntryAge = TimeSpan.FromSeconds(3); context.CachedEntryAge = TimeSpan.FromSeconds(3);
Assert.True(new CacheabilityValidator().IsCachedEntryFresh(context)); Assert.True(new ResponseCachePolicyProvider().IsCachedEntryFresh(context));
} }
} }
} }

View File

@ -14,12 +14,12 @@ using Xunit;
namespace Microsoft.AspNetCore.ResponseCaching.Tests namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
public class ResponseCachingTests public class ResponseCacheTests
{ {
[Fact] [Fact]
public async void ServesCachedContent_IfAvailable() public async void ServesCachedContent_IfAvailable()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(); var builder = TestUtils.CreateBuilderWithResponseCache();
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
{ {
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfNotAvailable() public async void ServesFreshContent_IfNotAvailable()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(); var builder = TestUtils.CreateBuilderWithResponseCache();
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
{ {
@ -49,10 +49,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfVaryHeader_Matches() public async void ServesCachedContent_IfVaryHeader_Matches()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.Response.Headers[HeaderNames.Vary] = HeaderNames.From; context.Response.Headers[HeaderNames.Vary] = HeaderNames.From;
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -69,10 +69,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfVaryHeader_Mismatches() public async void ServesFreshContent_IfVaryHeader_Mismatches()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.Response.Headers[HeaderNames.Vary] = HeaderNames.From; context.Response.Headers[HeaderNames.Vary] = HeaderNames.From;
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -90,10 +90,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfVaryParams_Matches() public async void ServesCachedContent_IfVaryParams_Matches()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.GetResponseCachingFeature().VaryParams = "param"; context.GetResponseCacheFeature().VaryByParams = "param";
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -109,10 +109,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfVaryParamsExplicit_Matches_ParamNameCaseInsensitive() public async void ServesCachedContent_IfVaryParamsExplicit_Matches_ParamNameCaseInsensitive()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.GetResponseCachingFeature().VaryParams = new[] { "ParamA", "paramb" }; context.GetResponseCacheFeature().VaryByParams = new[] { "ParamA", "paramb" };
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -128,10 +128,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfVaryParamsStar_Matches_ParamNameCaseInsensitive() public async void ServesCachedContent_IfVaryParamsStar_Matches_ParamNameCaseInsensitive()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.GetResponseCachingFeature().VaryParams = new[] { "*" }; context.GetResponseCacheFeature().VaryByParams = new[] { "*" };
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -147,10 +147,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfVaryParamsExplicit_Matches_OrderInsensitive() public async void ServesCachedContent_IfVaryParamsExplicit_Matches_OrderInsensitive()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.GetResponseCachingFeature().VaryParams = new[] { "ParamB", "ParamA" }; context.GetResponseCacheFeature().VaryByParams = new[] { "ParamB", "ParamA" };
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -166,10 +166,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfVaryParamsStar_Matches_OrderInsensitive() public async void ServesCachedContent_IfVaryParamsStar_Matches_OrderInsensitive()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.GetResponseCachingFeature().VaryParams = new[] { "*" }; context.GetResponseCacheFeature().VaryByParams = new[] { "*" };
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -185,10 +185,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfVaryParams_Mismatches() public async void ServesFreshContent_IfVaryParams_Mismatches()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.GetResponseCachingFeature().VaryParams = "param"; context.GetResponseCacheFeature().VaryByParams = "param";
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -204,10 +204,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfVaryParamsExplicit_Mismatch_ParamValueCaseSensitive() public async void ServesFreshContent_IfVaryParamsExplicit_Mismatch_ParamValueCaseSensitive()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.GetResponseCachingFeature().VaryParams = new[] { "ParamA", "ParamB" }; context.GetResponseCacheFeature().VaryByParams = new[] { "ParamA", "ParamB" };
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -223,10 +223,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfVaryParamsStar_Mismatch_ParamValueCaseSensitive() public async void ServesFreshContent_IfVaryParamsStar_Mismatch_ParamValueCaseSensitive()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.GetResponseCachingFeature().VaryParams = new[] { "*" }; context.GetResponseCacheFeature().VaryByParams = new[] { "*" };
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -242,7 +242,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfRequestRequirements_NotMet() public async void ServesFreshContent_IfRequestRequirements_NotMet()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(); var builder = TestUtils.CreateBuilderWithResponseCache();
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
{ {
@ -261,7 +261,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void Serves504_IfOnlyIfCachedHeader_IsSpecified() public async void Serves504_IfOnlyIfCachedHeader_IsSpecified()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(); var builder = TestUtils.CreateBuilderWithResponseCache();
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
{ {
@ -281,10 +281,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfSetCookie_IsSpecified() public async void ServesFreshContent_IfSetCookie_IsSpecified()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
var headers = context.Response.Headers[HeaderNames.SetCookie] = "cookieName=cookieValue"; var headers = context.Response.Headers[HeaderNames.SetCookie] = "cookieName=cookieValue";
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -300,7 +300,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfIHttpSendFileFeature_NotUsed() public async void ServesCachedContent_IfIHttpSendFileFeature_NotUsed()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(app => var builder = TestUtils.CreateBuilderWithResponseCache(app =>
{ {
app.Use(async (context, next) => app.Use(async (context, next) =>
{ {
@ -322,7 +322,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfIHttpSendFileFeature_Used() public async void ServesFreshContent_IfIHttpSendFileFeature_Used()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching( var builder = TestUtils.CreateBuilderWithResponseCache(
app => app =>
{ {
app.Use(async (context, next) => app.Use(async (context, next) =>
@ -334,7 +334,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
requestDelegate: async (context) => requestDelegate: async (context) =>
{ {
await context.Features.Get<IHttpSendFileFeature>().SendFileAsync("dummy", 0, 0, CancellationToken.None); await context.Features.Get<IHttpSendFileFeature>().SendFileAsync("dummy", 0, 0, CancellationToken.None);
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -350,7 +350,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfSubsequentRequest_ContainsNoStore() public async void ServesCachedContent_IfSubsequentRequest_ContainsNoStore()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(); var builder = TestUtils.CreateBuilderWithResponseCache();
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
{ {
@ -369,7 +369,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfInitialRequestContains_NoStore() public async void ServesFreshContent_IfInitialRequestContains_NoStore()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(); var builder = TestUtils.CreateBuilderWithResponseCache();
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
{ {
@ -388,7 +388,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void Serves304_IfIfModifiedSince_Satisfied() public async void Serves304_IfIfModifiedSince_Satisfied()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(); var builder = TestUtils.CreateBuilderWithResponseCache();
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
{ {
@ -405,7 +405,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfIfModifiedSince_NotSatisfied() public async void ServesCachedContent_IfIfModifiedSince_NotSatisfied()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(); var builder = TestUtils.CreateBuilderWithResponseCache();
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
{ {
@ -421,10 +421,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void Serves304_IfIfNoneMatch_Satisfied() public async void Serves304_IfIfNoneMatch_Satisfied()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
var headers = context.Response.GetTypedHeaders().ETag = new EntityTagHeaderValue("\"E1\""); var headers = context.Response.GetTypedHeaders().ETag = new EntityTagHeaderValue("\"E1\"");
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -442,10 +442,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfIfNoneMatch_NotSatisfied() public async void ServesCachedContent_IfIfNoneMatch_NotSatisfied()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
var headers = context.Response.GetTypedHeaders().ETag = new EntityTagHeaderValue("\"E1\""); var headers = context.Response.GetTypedHeaders().ETag = new EntityTagHeaderValue("\"E1\"");
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))
@ -462,7 +462,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_IfBodySize_IsCacheable() public async void ServesCachedContent_IfBodySize_IsCacheable()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(options: new ResponseCachingOptions() var builder = TestUtils.CreateBuilderWithResponseCache(options: new ResponseCacheOptions()
{ {
MaximumCachedBodySize = 100 MaximumCachedBodySize = 100
}); });
@ -480,7 +480,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesFreshContent_IfBodySize_IsNotCacheable() public async void ServesFreshContent_IfBodySize_IsNotCacheable()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(options: new ResponseCachingOptions() var builder = TestUtils.CreateBuilderWithResponseCache(options: new ResponseCacheOptions()
{ {
MaximumCachedBodySize = 1 MaximumCachedBodySize = 1
}); });
@ -498,10 +498,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
[Fact] [Fact]
public async void ServesCachedContent_WithoutReplacingCachedVaryBy_OnCacheMiss() public async void ServesCachedContent_WithoutReplacingCachedVaryBy_OnCacheMiss()
{ {
var builder = TestUtils.CreateBuilderWithResponseCaching(requestDelegate: async (context) => var builder = TestUtils.CreateBuilderWithResponseCache(requestDelegate: async (context) =>
{ {
context.Response.Headers[HeaderNames.Vary] = HeaderNames.From; context.Response.Headers[HeaderNames.Vary] = HeaderNames.From;
await TestUtils.DefaultRequestDelegate(context); await TestUtils.TestRequestDelegate(context);
}); });
using (var server = new TestServer(builder)) using (var server = new TestServer(builder))

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
internal class TestUtils internal class TestUtils
{ {
internal static RequestDelegate DefaultRequestDelegate = async (context) => internal static RequestDelegate TestRequestDelegate = async (context) =>
{ {
var uniqueId = Guid.NewGuid().ToString(); var uniqueId = Guid.NewGuid().ToString();
var headers = context.Response.GetTypedHeaders(); var headers = context.Response.GetTypedHeaders();
@ -34,19 +34,19 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
await context.Response.WriteAsync(uniqueId); await context.Response.WriteAsync(uniqueId);
}; };
internal static ICacheKeyProvider CreateTestKeyProvider() internal static IResponseCacheKeyProvider CreateTestKeyProvider()
{ {
return CreateTestKeyProvider(new ResponseCachingOptions()); return CreateTestKeyProvider(new ResponseCacheOptions());
} }
internal static ICacheKeyProvider CreateTestKeyProvider(ResponseCachingOptions options) internal static IResponseCacheKeyProvider CreateTestKeyProvider(ResponseCacheOptions options)
{ {
return new CacheKeyProvider(new DefaultObjectPoolProvider(), Options.Create(options)); return new ResponseCacheKeyProvider(new DefaultObjectPoolProvider(), Options.Create(options));
} }
internal static IWebHostBuilder CreateBuilderWithResponseCaching( internal static IWebHostBuilder CreateBuilderWithResponseCache(
Action<IApplicationBuilder> configureDelegate = null, Action<IApplicationBuilder> configureDelegate = null,
ResponseCachingOptions options = null, ResponseCacheOptions options = null,
RequestDelegate requestDelegate = null) RequestDelegate requestDelegate = null)
{ {
if (configureDelegate == null) if (configureDelegate == null)
@ -55,11 +55,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
} }
if (options == null) if (options == null)
{ {
options = new ResponseCachingOptions(); options = new ResponseCacheOptions();
} }
if (requestDelegate == null) if (requestDelegate == null)
{ {
requestDelegate = DefaultRequestDelegate; requestDelegate = TestRequestDelegate;
} }
return new WebHostBuilder() return new WebHostBuilder()
@ -70,45 +70,45 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
.Configure(app => .Configure(app =>
{ {
configureDelegate(app); configureDelegate(app);
app.UseResponseCaching(options); app.UseResponseCache(options);
app.Run(requestDelegate); app.Run(requestDelegate);
}); });
} }
internal static ResponseCachingMiddleware CreateTestMiddleware( internal static ResponseCacheMiddleware CreateTestMiddleware(
IResponseCache responseCache = null, IResponseCacheStore store = null,
ResponseCachingOptions options = null, ResponseCacheOptions options = null,
ICacheKeyProvider cacheKeyProvider = null, IResponseCacheKeyProvider keyProvider = null,
ICacheabilityValidator cacheabilityValidator = null) IResponseCachePolicyProvider policyProvider = null)
{ {
if (responseCache == null) if (store == null)
{ {
responseCache = new TestResponseCache(); store = new TestResponseCacheStore();
} }
if (options == null) if (options == null)
{ {
options = new ResponseCachingOptions(); options = new ResponseCacheOptions();
} }
if (cacheKeyProvider == null) if (keyProvider == null)
{ {
cacheKeyProvider = new CacheKeyProvider(new DefaultObjectPoolProvider(), Options.Create(options)); keyProvider = new ResponseCacheKeyProvider(new DefaultObjectPoolProvider(), Options.Create(options));
} }
if (cacheabilityValidator == null) if (policyProvider == null)
{ {
cacheabilityValidator = new TestCacheabilityValidator(); policyProvider = new TestResponseCachePolicyProvider();
} }
return new ResponseCachingMiddleware( return new ResponseCacheMiddleware(
httpContext => TaskCache.CompletedTask, httpContext => TaskCache.CompletedTask,
responseCache, store,
Options.Create(options), Options.Create(options),
cacheabilityValidator, policyProvider,
cacheKeyProvider); keyProvider);
} }
internal static ResponseCachingContext CreateTestContext() internal static ResponseCacheContext CreateTestContext()
{ {
return new ResponseCachingContext(new DefaultHttpContext()); return new ResponseCacheContext(new DefaultHttpContext());
} }
} }
@ -120,58 +120,49 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
} }
} }
internal class TestCacheabilityValidator : ICacheabilityValidator internal class TestResponseCachePolicyProvider : IResponseCachePolicyProvider
{ {
public bool IsCachedEntryFresh(ResponseCachingContext context) => true; public bool IsCachedEntryFresh(ResponseCacheContext context) => true;
public bool IsRequestCacheable(ResponseCachingContext context) => true; public bool IsRequestCacheable(ResponseCacheContext context) => true;
public bool IsResponseCacheable(ResponseCachingContext context) => true; public bool IsResponseCacheable(ResponseCacheContext context) => true;
} }
internal class TestKeyProvider : ICacheKeyProvider internal class TestResponseCacheKeyProvider : IResponseCacheKeyProvider
{ {
private readonly StringValues _baseKey; private readonly string _baseKey;
private readonly StringValues _varyKey; private readonly StringValues _varyKey;
public TestKeyProvider(StringValues? lookupBaseKey = null, StringValues? lookupVaryKey = null) public TestResponseCacheKeyProvider(string lookupBaseKey = null, StringValues? lookupVaryKey = null)
{ {
if (lookupBaseKey.HasValue) _baseKey = lookupBaseKey;
{
_baseKey = lookupBaseKey.Value;
}
if (lookupVaryKey.HasValue) if (lookupVaryKey.HasValue)
{ {
_varyKey = lookupVaryKey.Value; _varyKey = lookupVaryKey.Value;
} }
} }
public IEnumerable<string> CreateLookupBaseKeys(ResponseCachingContext context) => _baseKey; public IEnumerable<string> CreateLookupVaryByKeys(ResponseCacheContext context)
public IEnumerable<string> CreateLookupVaryKeys(ResponseCachingContext context)
{ {
foreach (var baseKey in _baseKey) foreach (var varyKey in _varyKey)
{ {
foreach (var varyKey in _varyKey) yield return _baseKey + varyKey;
{
yield return baseKey + varyKey;
}
} }
} }
public string CreateStorageBaseKey(ResponseCachingContext context) public string CreateBaseKey(ResponseCacheContext context)
{ {
throw new NotImplementedException(); return _baseKey;
} }
public string CreateStorageVaryKey(ResponseCachingContext context) public string CreateStorageVaryByKey(ResponseCacheContext context)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
internal class TestResponseCache : IResponseCache internal class TestResponseCacheStore : IResponseCacheStore
{ {
private readonly IDictionary<string, object> _storage = new Dictionary<string, object>(); private readonly IDictionary<string, object> _storage = new Dictionary<string, object>();
public int GetCount { get; private set; } public int GetCount { get; private set; }
@ -200,12 +191,4 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
_storage[key] = entry; _storage[key] = entry;
} }
} }
internal class TestHttpSendFileFeature : IHttpSendFileFeature
{
public Task SendFileAsync(string path, long offset, long? count, CancellationToken cancellation)
{
return TaskCache.CompletedTask;
}
}
} }