Customize key prefix instead of suffix

This commit is contained in:
John Luo 2016-08-31 17:52:05 -07:00
parent 52f219b16e
commit 3b0f01a8ec
6 changed files with 37 additions and 41 deletions

View File

@ -5,13 +5,13 @@ using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.ResponseCaching namespace Microsoft.AspNetCore.ResponseCaching
{ {
public interface IResponseCachingCacheKeySuffixProvider public interface IResponseCachingCacheKeyModifier
{ {
/// <summary> /// <summary>
/// Create a key segment that is appended to the default cache key. /// Create a key segment that is prepended to the default cache key.
/// </summary> /// </summary>
/// <param name="httpContext">The <see cref="HttpContext"/>.</param> /// <param name="httpContext">The <see cref="HttpContext"/>.</param>
/// <returns>The key segment that will be appended to the default cache key.</returns> /// <returns>The key segment that will be prepended to the default cache key.</returns>
string CreateCustomKeySuffix(HttpContext httpContext); string CreatKeyPrefix(HttpContext httpContext);
} }
} }

View File

@ -5,8 +5,8 @@ using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.ResponseCaching.Internal namespace Microsoft.AspNetCore.ResponseCaching.Internal
{ {
internal class NoopCacheKeySuffixProvider : IResponseCachingCacheKeySuffixProvider internal class NoopCacheKeyModifier : IResponseCachingCacheKeyModifier
{ {
public string CreateCustomKeySuffix(HttpContext httpContext) => null; public string CreatKeyPrefix(HttpContext httpContext) => null;
} }
} }

View File

@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
private readonly ISystemClock _clock; private readonly ISystemClock _clock;
private readonly ObjectPool<StringBuilder> _builderPool; private readonly ObjectPool<StringBuilder> _builderPool;
private readonly IResponseCachingCacheabilityValidator _cacheabilityValidator; private readonly IResponseCachingCacheabilityValidator _cacheabilityValidator;
private readonly IResponseCachingCacheKeySuffixProvider _cacheKeySuffixProvider; private readonly IResponseCachingCacheKeyModifier _cacheKeyModifier;
private string _cacheKey; private string _cacheKey;
private ResponseType? _responseType; private ResponseType? _responseType;
@ -46,8 +46,8 @@ namespace Microsoft.AspNetCore.ResponseCaching
IResponseCache cache, IResponseCache cache,
ObjectPool<StringBuilder> builderPool, ObjectPool<StringBuilder> builderPool,
IResponseCachingCacheabilityValidator cacheabilityValidator, IResponseCachingCacheabilityValidator cacheabilityValidator,
IResponseCachingCacheKeySuffixProvider cacheKeySuffixProvider) IResponseCachingCacheKeyModifier cacheKeyModifier)
: this(httpContext, cache, new SystemClock(), builderPool, cacheabilityValidator, cacheKeySuffixProvider) : this(httpContext, cache, new SystemClock(), builderPool, cacheabilityValidator, cacheKeyModifier)
{ {
} }
@ -58,14 +58,14 @@ namespace Microsoft.AspNetCore.ResponseCaching
ISystemClock clock, ISystemClock clock,
ObjectPool<StringBuilder> builderPool, ObjectPool<StringBuilder> builderPool,
IResponseCachingCacheabilityValidator cacheabilityValidator, IResponseCachingCacheabilityValidator cacheabilityValidator,
IResponseCachingCacheKeySuffixProvider cacheKeySuffixProvider) IResponseCachingCacheKeyModifier cacheKeyModifier)
{ {
_httpContext = httpContext; _httpContext = httpContext;
_cache = cache; _cache = cache;
_clock = clock; _clock = clock;
_builderPool = builderPool; _builderPool = builderPool;
_cacheabilityValidator = cacheabilityValidator; _cacheabilityValidator = cacheabilityValidator;
_cacheKeySuffixProvider = cacheKeySuffixProvider; _cacheKeyModifier = cacheKeyModifier;
} }
internal bool CacheResponse internal bool CacheResponse
@ -153,6 +153,14 @@ namespace Microsoft.AspNetCore.ResponseCaching
try try
{ {
// Prepend custom cache key prefix
var customKeyPrefix = _cacheKeyModifier.CreatKeyPrefix(_httpContext);
if (!string.IsNullOrEmpty(customKeyPrefix))
{
builder.Append(customKeyPrefix)
.Append(KeyDelimiter);
}
// Default key // Default key
builder builder
.Append(request.Method.ToUpperInvariant()) .Append(request.Method.ToUpperInvariant())
@ -225,18 +233,6 @@ namespace Microsoft.AspNetCore.ResponseCaching
} }
} }
// Append custom cache key segment
var customKey = _cacheKeySuffixProvider.CreateCustomKeySuffix(_httpContext);
if (!string.IsNullOrEmpty(customKey))
{
// Append a group separator for the custom segment of the cache key
builder.Append(KeyDelimiter)
.Append('C');
builder.Append(KeyDelimiter)
.Append(customKey);
}
return builder.ToString(); return builder.ToString();
} }
finally finally

View File

@ -22,14 +22,14 @@ namespace Microsoft.AspNetCore.ResponseCaching
private readonly IResponseCache _cache; private readonly IResponseCache _cache;
private readonly ObjectPool<StringBuilder> _builderPool; private readonly ObjectPool<StringBuilder> _builderPool;
private readonly IResponseCachingCacheabilityValidator _cacheabilityValidator; private readonly IResponseCachingCacheabilityValidator _cacheabilityValidator;
private readonly IResponseCachingCacheKeySuffixProvider _cacheKeySuffixProvider; private readonly IResponseCachingCacheKeyModifier _cacheKeyModifier;
public ResponseCachingMiddleware( public ResponseCachingMiddleware(
RequestDelegate next, RequestDelegate next,
IResponseCache cache, IResponseCache cache,
ObjectPoolProvider poolProvider, ObjectPoolProvider poolProvider,
IResponseCachingCacheabilityValidator cacheabilityValidator, IResponseCachingCacheabilityValidator cacheabilityValidator,
IResponseCachingCacheKeySuffixProvider cacheKeySuffixProvider) IResponseCachingCacheKeyModifier cacheKeyModifier)
{ {
if (next == null) if (next == null)
{ {
@ -47,16 +47,16 @@ namespace Microsoft.AspNetCore.ResponseCaching
{ {
throw new ArgumentNullException(nameof(cacheabilityValidator)); throw new ArgumentNullException(nameof(cacheabilityValidator));
} }
if (cacheKeySuffixProvider == null) if (cacheKeyModifier == null)
{ {
throw new ArgumentNullException(nameof(cacheKeySuffixProvider)); throw new ArgumentNullException(nameof(cacheKeyModifier));
} }
_next = next; _next = next;
_cache = cache; _cache = cache;
_builderPool = poolProvider.CreateStringBuilderPool(); _builderPool = poolProvider.CreateStringBuilderPool();
_cacheabilityValidator = cacheabilityValidator; _cacheabilityValidator = cacheabilityValidator;
_cacheKeySuffixProvider = cacheKeySuffixProvider; _cacheKeyModifier = cacheKeyModifier;
} }
public async Task Invoke(HttpContext context) public async Task Invoke(HttpContext context)
@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
_cache, _cache,
_builderPool, _builderPool,
_cacheabilityValidator, _cacheabilityValidator,
_cacheKeySuffixProvider); _cacheKeyModifier);
// Should we attempt any caching logic? // Should we attempt any caching logic?
if (cachingContext.RequestIsCacheable()) if (cachingContext.RequestIsCacheable())

View File

@ -40,7 +40,7 @@ namespace Microsoft.Extensions.DependencyInjection
private static IServiceCollection AddResponseCachingServices(this IServiceCollection services) private static IServiceCollection AddResponseCachingServices(this IServiceCollection services)
{ {
services.TryAdd(ServiceDescriptor.Singleton<IResponseCachingCacheKeySuffixProvider, NoopCacheKeySuffixProvider>()); services.TryAdd(ServiceDescriptor.Singleton<IResponseCachingCacheKeyModifier, NoopCacheKeyModifier>());
services.TryAdd(ServiceDescriptor.Singleton<IResponseCachingCacheabilityValidator, NoopCacheabilityValidator>()); services.TryAdd(ServiceDescriptor.Singleton<IResponseCachingCacheabilityValidator, NoopCacheabilityValidator>());
return services; return services;

View File

@ -258,22 +258,22 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
})); }));
} }
private class CustomizeKeySuffixProvider : IResponseCachingCacheKeySuffixProvider private class KeyModifier : IResponseCachingCacheKeyModifier
{ {
public string CreateCustomKeySuffix(HttpContext httpContext) => "CustomizedKey"; public string CreatKeyPrefix(HttpContext httpContext) => "CustomizedKeyPrefix";
} }
[Fact] [Fact]
public void CreateCacheKey_OptionalCacheKey_AppendedToDefaultKey() public void CreateCacheKey_CacheKeyModifier_AddsPrefix()
{ {
var httpContext = new DefaultHttpContext(); var httpContext = new DefaultHttpContext();
httpContext.Request.Method = "GET"; httpContext.Request.Method = "GET";
httpContext.Request.Path = "/"; httpContext.Request.Path = "/";
httpContext.Request.Headers["HeaderA"] = "ValueA"; httpContext.Request.Headers["HeaderA"] = "ValueA";
httpContext.Request.Headers["HeaderB"] = "ValueB"; httpContext.Request.Headers["HeaderB"] = "ValueB";
var responseCachingContext = CreateTestContext(httpContext, new CustomizeKeySuffixProvider()); var responseCachingContext = CreateTestContext(httpContext, new KeyModifier());
Assert.Equal($"GET{KeyDelimiter}/{KeyDelimiter}H{KeyDelimiter}HeaderA=ValueA{KeyDelimiter}HeaderC=null{KeyDelimiter}C{KeyDelimiter}CustomizedKey", responseCachingContext.CreateCacheKey(new CachedVaryBy() Assert.Equal($"CustomizedKeyPrefix{KeyDelimiter}GET{KeyDelimiter}/{KeyDelimiter}H{KeyDelimiter}HeaderA=ValueA{KeyDelimiter}HeaderC=null", responseCachingContext.CreateCacheKey(new CachedVaryBy()
{ {
Headers = new string[] { "HeaderA", "HeaderC" } Headers = new string[] { "HeaderA", "HeaderC" }
})); }));
@ -831,15 +831,15 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
return CreateTestContext( return CreateTestContext(
httpContext, httpContext,
new NoopCacheKeySuffixProvider(), new NoopCacheKeyModifier(),
new NoopCacheabilityValidator()); new NoopCacheabilityValidator());
} }
private static ResponseCachingContext CreateTestContext(HttpContext httpContext, IResponseCachingCacheKeySuffixProvider cacheKeySuffixProvider) private static ResponseCachingContext CreateTestContext(HttpContext httpContext, IResponseCachingCacheKeyModifier cacheKeyModifier)
{ {
return CreateTestContext( return CreateTestContext(
httpContext, httpContext,
cacheKeySuffixProvider, cacheKeyModifier,
new NoopCacheabilityValidator()); new NoopCacheabilityValidator());
} }
@ -847,13 +847,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
{ {
return CreateTestContext( return CreateTestContext(
httpContext, httpContext,
new NoopCacheKeySuffixProvider(), new NoopCacheKeyModifier(),
cacheabilityValidator); cacheabilityValidator);
} }
private static ResponseCachingContext CreateTestContext( private static ResponseCachingContext CreateTestContext(
HttpContext httpContext, HttpContext httpContext,
IResponseCachingCacheKeySuffixProvider cacheKeySuffixProvider, IResponseCachingCacheKeyModifier cacheKeyModifier,
IResponseCachingCacheabilityValidator cacheabilityValidator) IResponseCachingCacheabilityValidator cacheabilityValidator)
{ {
return new ResponseCachingContext( return new ResponseCachingContext(
@ -862,7 +862,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
new SystemClock(), new SystemClock(),
new DefaultObjectPool<StringBuilder>(new StringBuilderPooledObjectPolicy()), new DefaultObjectPool<StringBuilder>(new StringBuilderPooledObjectPolicy()),
cacheabilityValidator, cacheabilityValidator,
cacheKeySuffixProvider); cacheKeyModifier);
} }
private class TestResponseCache : IResponseCache private class TestResponseCache : IResponseCache