Skip to content
This repository was archived by the owner on Nov 22, 2018. It is now read-only.

Commit 411681e

Browse files
committed
Add options to configure case sensitivity of request paths
1 parent 0f711ce commit 411681e

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingContext.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ internal class ResponseCachingContext
4444

4545
// Internal for testing
4646
internal ResponseCachingContext(
47-
HttpContext httpContext,
47+
HttpContext httpContext,
4848
IResponseCache cache,
4949
ResponseCachingOptions options,
5050
ObjectPool<StringBuilder> builderPool,
@@ -149,11 +149,11 @@ internal string CreateCacheKey(CachedVaryBy varyBy)
149149
.Append(KeyDelimiter);
150150
}
151151

152-
// Default key
152+
// Default key
153153
builder
154154
.Append(request.Method.ToUpperInvariant())
155155
.Append(KeyDelimiter)
156-
.Append(request.Path.Value.ToUpperInvariant());
156+
.Append(_options.CaseSensitivePaths ? request.Path.Value : request.Path.Value.ToUpperInvariant());
157157

158158
// Vary by headers
159159
if (varyBy?.Headers.Count > 0)
@@ -337,7 +337,7 @@ internal bool ResponseIsCacheable()
337337
}
338338

339339
// TODO: public MAY override the cacheability checks for private and status codes
340-
340+
341341
// Check private
342342
if (ResponseCacheControl.Private)
343343
{
@@ -365,7 +365,7 @@ internal bool ResponseIsCacheable()
365365
internal bool EntryIsFresh(ResponseHeaders responseHeaders, TimeSpan age, bool verifyAgainstRequest)
366366
{
367367
var responseCacheControl = responseHeaders.CacheControl ?? EmptyCacheControl;
368-
368+
369369
// Add min-fresh requirements
370370
if (verifyAgainstRequest)
371371
{

src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingOptions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ namespace Microsoft.AspNetCore.Builder
99
public class ResponseCachingOptions
1010
{
1111
/// <summary>
12-
/// The largest cacheable size for the response body in bytes.
12+
/// The largest cacheable size for the response body in bytes. The default is set to 1 MB.
1313
/// </summary>
1414
public long MaximumCachedBodySize { get; set; } = 1024 * 1024;
1515

16+
/// <summary>
17+
/// <c>true</c> if request paths are case-sensitive; otherwise <c>false</c>. The default is to treat paths as case-insensitive.
18+
/// </summary>
19+
public bool CaseSensitivePaths { get; set; } = false;
20+
1621
/// <summary>
1722
/// For testing purposes only.
1823
/// </summary>

test/Microsoft.AspNetCore.ResponseCaching.Tests/ResponseCachingContextTests.cs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,34 @@ public void CreateCacheKey_CacheKeyModifier_AddsPrefix()
280280
}));
281281
}
282282

283+
[Fact]
284+
public void CreateCacheKey_CaseInsensitivePath_NormalizesPath()
285+
{
286+
var httpContext = new DefaultHttpContext();
287+
httpContext.Request.Method = "GET";
288+
httpContext.Request.Path = "/Path";
289+
var context = CreateTestContext(httpContext, new ResponseCachingOptions()
290+
{
291+
CaseSensitivePaths = false
292+
});
293+
294+
Assert.Equal($"GET{KeyDelimiter}/PATH", context.CreateCacheKey());
295+
}
296+
297+
[Fact]
298+
public void CreateCacheKey_CaseSensitivePath_PreservesPathCase()
299+
{
300+
var httpContext = new DefaultHttpContext();
301+
httpContext.Request.Method = "GET";
302+
httpContext.Request.Path = "/Path";
303+
var context = CreateTestContext(httpContext, new ResponseCachingOptions()
304+
{
305+
CaseSensitivePaths = true
306+
});
307+
308+
Assert.Equal($"GET{KeyDelimiter}/Path", context.CreateCacheKey());
309+
}
310+
283311
[Fact]
284312
public void ResponseIsCacheable_NoPublic_NotAllowed()
285313
{
@@ -832,6 +860,16 @@ private static ResponseCachingContext CreateTestContext(HttpContext httpContext)
832860
{
833861
return CreateTestContext(
834862
httpContext,
863+
new ResponseCachingOptions(),
864+
new NoopCacheKeyModifier(),
865+
new NoopCacheabilityValidator());
866+
}
867+
868+
private static ResponseCachingContext CreateTestContext(HttpContext httpContext, ResponseCachingOptions options)
869+
{
870+
return CreateTestContext(
871+
httpContext,
872+
options,
835873
new NoopCacheKeyModifier(),
836874
new NoopCacheabilityValidator());
837875
}
@@ -840,6 +878,7 @@ private static ResponseCachingContext CreateTestContext(HttpContext httpContext,
840878
{
841879
return CreateTestContext(
842880
httpContext,
881+
new ResponseCachingOptions(),
843882
cacheKeyModifier,
844883
new NoopCacheabilityValidator());
845884
}
@@ -848,19 +887,21 @@ private static ResponseCachingContext CreateTestContext(HttpContext httpContext,
848887
{
849888
return CreateTestContext(
850889
httpContext,
890+
new ResponseCachingOptions(),
851891
new NoopCacheKeyModifier(),
852892
cacheabilityValidator);
853893
}
854894

855895
private static ResponseCachingContext CreateTestContext(
856896
HttpContext httpContext,
897+
ResponseCachingOptions options,
857898
IResponseCachingCacheKeyModifier cacheKeyModifier,
858899
IResponseCachingCacheabilityValidator cacheabilityValidator)
859900
{
860901
return new ResponseCachingContext(
861902
httpContext,
862903
new TestResponseCache(),
863-
new ResponseCachingOptions(),
904+
options,
864905
new DefaultObjectPool<StringBuilder>(new StringBuilderPooledObjectPolicy()),
865906
cacheabilityValidator,
866907
cacheKeyModifier);

0 commit comments

Comments
 (0)