Customize key prefix instead of suffix
This commit is contained in:
parent
52f219b16e
commit
3b0f01a8ec
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue