Improve header parsing performance
This commit is contained in:
parent
e823118e51
commit
9c94a7764b
|
|
@ -0,0 +1,21 @@
|
||||||
|
// 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.Internal
|
||||||
|
{
|
||||||
|
internal class CacheControlValues
|
||||||
|
{
|
||||||
|
public const string MaxAgeString = "max-age";
|
||||||
|
public const string MaxStaleString = "max-stale";
|
||||||
|
public const string MinFreshString = "min-fresh";
|
||||||
|
public const string MustRevalidateString = "must-revalidate";
|
||||||
|
public const string NoCacheString = "no-cache";
|
||||||
|
public const string NoStoreString = "no-store";
|
||||||
|
public const string NoTransformString = "no-transform";
|
||||||
|
public const string OnlyIfCachedString = "only-if-cached";
|
||||||
|
public const string PrivateString = "private";
|
||||||
|
public const string ProxyRevalidateString = "proxy-revalidate";
|
||||||
|
public const string PublicString = "public";
|
||||||
|
public const string SharedMaxAgeString = "s-maxage";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
// 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;
|
||||||
|
using System.Globalization;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
|
{
|
||||||
|
internal static class HttpHeaderParsingHelpers
|
||||||
|
{
|
||||||
|
private static readonly string[] DateFormats = new string[] {
|
||||||
|
// "r", // RFC 1123, required output format but too strict for input
|
||||||
|
"ddd, d MMM yyyy H:m:s 'GMT'", // RFC 1123 (r, except it allows both 1 and 01 for date and time)
|
||||||
|
"ddd, d MMM yyyy H:m:s", // RFC 1123, no zone - assume GMT
|
||||||
|
"d MMM yyyy H:m:s 'GMT'", // RFC 1123, no day-of-week
|
||||||
|
"d MMM yyyy H:m:s", // RFC 1123, no day-of-week, no zone
|
||||||
|
"ddd, d MMM yy H:m:s 'GMT'", // RFC 1123, short year
|
||||||
|
"ddd, d MMM yy H:m:s", // RFC 1123, short year, no zone
|
||||||
|
"d MMM yy H:m:s 'GMT'", // RFC 1123, no day-of-week, short year
|
||||||
|
"d MMM yy H:m:s", // RFC 1123, no day-of-week, short year, no zone
|
||||||
|
|
||||||
|
"dddd, d'-'MMM'-'yy H:m:s 'GMT'", // RFC 850
|
||||||
|
"dddd, d'-'MMM'-'yy H:m:s", // RFC 850 no zone
|
||||||
|
"ddd MMM d H:m:s yyyy", // ANSI C's asctime() format
|
||||||
|
|
||||||
|
"ddd, d MMM yyyy H:m:s zzz", // RFC 5322
|
||||||
|
"ddd, d MMM yyyy H:m:s", // RFC 5322 no zone
|
||||||
|
"d MMM yyyy H:m:s zzz", // RFC 5322 no day-of-week
|
||||||
|
"d MMM yyyy H:m:s", // RFC 5322 no day-of-week, no zone
|
||||||
|
};
|
||||||
|
|
||||||
|
// Try the various date formats in the order listed above.
|
||||||
|
// We should accept a wide verity of common formats, but only output RFC 1123 style dates.
|
||||||
|
internal static bool TryParseHeaderDate(string input, out DateTimeOffset result) => DateTimeOffset.TryParseExact(input, DateFormats, DateTimeFormatInfo.InvariantInfo,
|
||||||
|
DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal, out result);
|
||||||
|
|
||||||
|
// Try to get the value of a specific header from a list of headers
|
||||||
|
// e.g. "header1=10, header2=30"
|
||||||
|
internal static bool TryParseHeaderTimeSpan(StringValues headers, string headerName, out TimeSpan? value)
|
||||||
|
{
|
||||||
|
foreach (var header in headers)
|
||||||
|
{
|
||||||
|
var index = header.IndexOf(headerName, StringComparison.OrdinalIgnoreCase);
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
index += headerName.Length;
|
||||||
|
int seconds;
|
||||||
|
if (!TryParseHeaderInt(index, header, out seconds))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
value = TimeSpan.FromSeconds(seconds);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool HeaderContains(StringValues headers, string headerName)
|
||||||
|
{
|
||||||
|
foreach (var header in headers)
|
||||||
|
{
|
||||||
|
var index = header.IndexOf(headerName, StringComparison.OrdinalIgnoreCase);
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryParseHeaderInt(int startIndex, string header, out int value)
|
||||||
|
{
|
||||||
|
var found = false;
|
||||||
|
while (startIndex != header.Length)
|
||||||
|
{
|
||||||
|
var c = header[startIndex];
|
||||||
|
if (c == '=')
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
else if (c != ' ')
|
||||||
|
{
|
||||||
|
--startIndex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++startIndex;
|
||||||
|
}
|
||||||
|
if (found && startIndex != header.Length)
|
||||||
|
{
|
||||||
|
var endIndex = startIndex + 1;
|
||||||
|
while (endIndex < header.Length)
|
||||||
|
{
|
||||||
|
var c = header[endIndex];
|
||||||
|
if ((c >= '0') && (c <= '9'))
|
||||||
|
{
|
||||||
|
endIndex++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var length = endIndex - (startIndex + 1);
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
value = int.Parse(header.Substring(startIndex + 1, length), NumberStyles.None, NumberFormatInfo.InvariantInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,6 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using Microsoft.AspNetCore.Http.Headers;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
|
|
@ -13,16 +12,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
{
|
{
|
||||||
public class ResponseCachingContext
|
public class ResponseCachingContext
|
||||||
{
|
{
|
||||||
private static readonly CacheControlHeaderValue EmptyCacheControl = new CacheControlHeaderValue();
|
|
||||||
|
|
||||||
private RequestHeaders _requestHeaders;
|
|
||||||
private ResponseHeaders _responseHeaders;
|
|
||||||
private CacheControlHeaderValue _requestCacheControl;
|
|
||||||
private CacheControlHeaderValue _responseCacheControl;
|
|
||||||
private DateTimeOffset? _responseDate;
|
private DateTimeOffset? _responseDate;
|
||||||
private bool _parsedResponseDate;
|
private bool _parsedResponseDate;
|
||||||
private DateTimeOffset? _responseExpires;
|
private DateTimeOffset? _responseExpires;
|
||||||
private bool _parsedResponseExpires;
|
private bool _parsedResponseExpires;
|
||||||
|
private TimeSpan? _responseSharedMaxAge;
|
||||||
|
private bool _parsedResponseSharedMaxAge;
|
||||||
|
private TimeSpan? _responseMaxAge;
|
||||||
|
private bool _parsedResponseMaxAge;
|
||||||
|
|
||||||
internal ResponseCachingContext(HttpContext httpContext, ILogger logger)
|
internal ResponseCachingContext(HttpContext httpContext, ILogger logger)
|
||||||
{
|
{
|
||||||
|
|
@ -58,55 +55,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
|
|
||||||
internal IHttpSendFileFeature OriginalSendFileFeature { get; set; }
|
internal IHttpSendFileFeature OriginalSendFileFeature { get; set; }
|
||||||
|
|
||||||
internal ResponseHeaders CachedResponseHeaders { get; set; }
|
internal IHeaderDictionary CachedResponseHeaders { get; set; }
|
||||||
|
|
||||||
internal RequestHeaders TypedRequestHeaders
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_requestHeaders == null)
|
|
||||||
{
|
|
||||||
_requestHeaders = HttpContext.Request.GetTypedHeaders();
|
|
||||||
}
|
|
||||||
return _requestHeaders;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal ResponseHeaders TypedResponseHeaders
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_responseHeaders == null)
|
|
||||||
{
|
|
||||||
_responseHeaders = HttpContext.Response.GetTypedHeaders();
|
|
||||||
}
|
|
||||||
return _responseHeaders;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal CacheControlHeaderValue RequestCacheControlHeaderValue
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_requestCacheControl == null)
|
|
||||||
{
|
|
||||||
_requestCacheControl = TypedRequestHeaders.CacheControl ?? EmptyCacheControl;
|
|
||||||
}
|
|
||||||
return _requestCacheControl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal CacheControlHeaderValue ResponseCacheControlHeaderValue
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_responseCacheControl == null)
|
|
||||||
{
|
|
||||||
_responseCacheControl = TypedResponseHeaders.CacheControl ?? EmptyCacheControl;
|
|
||||||
}
|
|
||||||
return _responseCacheControl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal DateTimeOffset? ResponseDate
|
internal DateTimeOffset? ResponseDate
|
||||||
{
|
{
|
||||||
|
|
@ -115,7 +64,15 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
if (!_parsedResponseDate)
|
if (!_parsedResponseDate)
|
||||||
{
|
{
|
||||||
_parsedResponseDate = true;
|
_parsedResponseDate = true;
|
||||||
_responseDate = TypedResponseHeaders.Date;
|
DateTimeOffset date;
|
||||||
|
if (HttpHeaderParsingHelpers.TryParseHeaderDate(HttpContext.Response.Headers[HeaderNames.Date], out date))
|
||||||
|
{
|
||||||
|
_responseDate = date;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_responseDate = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return _responseDate;
|
return _responseDate;
|
||||||
}
|
}
|
||||||
|
|
@ -134,10 +91,44 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
if (!_parsedResponseExpires)
|
if (!_parsedResponseExpires)
|
||||||
{
|
{
|
||||||
_parsedResponseExpires = true;
|
_parsedResponseExpires = true;
|
||||||
_responseExpires = TypedResponseHeaders.Expires;
|
DateTimeOffset expires;
|
||||||
|
if (HttpHeaderParsingHelpers.TryParseHeaderDate(HttpContext.Response.Headers[HeaderNames.Expires], out expires))
|
||||||
|
{
|
||||||
|
_responseExpires = expires;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_responseExpires = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return _responseExpires;
|
return _responseExpires;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal TimeSpan? ResponseSharedMaxAge
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!_parsedResponseSharedMaxAge)
|
||||||
|
{
|
||||||
|
_parsedResponseSharedMaxAge = true;
|
||||||
|
HttpHeaderParsingHelpers.TryParseHeaderTimeSpan(HttpContext.Response.Headers[HeaderNames.CacheControl], CacheControlValues.SharedMaxAgeString, out _responseSharedMaxAge);
|
||||||
|
}
|
||||||
|
return _responseSharedMaxAge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal TimeSpan? ResponseMaxAge
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!_parsedResponseMaxAge)
|
||||||
|
{
|
||||||
|
_parsedResponseMaxAge = true;
|
||||||
|
HttpHeaderParsingHelpers.TryParseHeaderTimeSpan(HttpContext.Response.Headers[HeaderNames.CacheControl], CacheControlValues.MaxAgeString, out _responseMaxAge);
|
||||||
|
}
|
||||||
|
return _responseMaxAge;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
{
|
{
|
||||||
public class ResponseCachingPolicyProvider : IResponseCachingPolicyProvider
|
public class ResponseCachingPolicyProvider : IResponseCachingPolicyProvider
|
||||||
{
|
{
|
||||||
private static readonly CacheControlHeaderValue EmptyCacheControl = new CacheControlHeaderValue();
|
|
||||||
|
|
||||||
public virtual bool IsRequestCacheable(ResponseCachingContext context)
|
public virtual bool IsRequestCacheable(ResponseCachingContext context)
|
||||||
{
|
{
|
||||||
// Verify the method
|
// Verify the method
|
||||||
|
|
@ -32,7 +30,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
// Verify request cache-control parameters
|
// Verify request cache-control parameters
|
||||||
if (!StringValues.IsNullOrEmpty(request.Headers[HeaderNames.CacheControl]))
|
if (!StringValues.IsNullOrEmpty(request.Headers[HeaderNames.CacheControl]))
|
||||||
{
|
{
|
||||||
if (context.RequestCacheControlHeaderValue.NoCache)
|
if (HttpHeaderParsingHelpers.HeaderContains(request.Headers[HeaderNames.CacheControl], CacheControlValues.NoCacheString))
|
||||||
{
|
{
|
||||||
context.Logger.LogRequestWithNoCacheNotCacheable();
|
context.Logger.LogRequestWithNoCacheNotCacheable();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -42,13 +40,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
{
|
{
|
||||||
// Support for legacy HTTP 1.0 cache directive
|
// Support for legacy HTTP 1.0 cache directive
|
||||||
var pragmaHeaderValues = request.Headers[HeaderNames.Pragma];
|
var pragmaHeaderValues = request.Headers[HeaderNames.Pragma];
|
||||||
foreach (var directive in pragmaHeaderValues)
|
if (HttpHeaderParsingHelpers.HeaderContains(request.Headers[HeaderNames.Pragma], CacheControlValues.NoCacheString))
|
||||||
{
|
{
|
||||||
if (string.Equals("no-cache", directive, StringComparison.OrdinalIgnoreCase))
|
context.Logger.LogRequestWithPragmaNoCacheNotCacheable();
|
||||||
{
|
return false;
|
||||||
context.Logger.LogRequestWithPragmaNoCacheNotCacheable();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,22 +52,30 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
|
|
||||||
public virtual bool IsResponseCacheable(ResponseCachingContext context)
|
public virtual bool IsResponseCacheable(ResponseCachingContext context)
|
||||||
{
|
{
|
||||||
|
var responseCacheControlHeader = context.HttpContext.Response.Headers[HeaderNames.CacheControl];
|
||||||
|
|
||||||
// Only cache pages explicitly marked with public
|
// Only cache pages explicitly marked with public
|
||||||
if (!context.ResponseCacheControlHeaderValue.Public)
|
if (!HttpHeaderParsingHelpers.HeaderContains(responseCacheControlHeader, CacheControlValues.PublicString))
|
||||||
{
|
{
|
||||||
context.Logger.LogResponseWithoutPublicNotCacheable();
|
context.Logger.LogResponseWithoutPublicNotCacheable();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check no-store
|
// Check no-store
|
||||||
if (context.RequestCacheControlHeaderValue.NoStore || context.ResponseCacheControlHeaderValue.NoStore)
|
if (HttpHeaderParsingHelpers.HeaderContains(context.HttpContext.Request.Headers[HeaderNames.CacheControl], CacheControlValues.NoStoreString))
|
||||||
|
{
|
||||||
|
context.Logger.LogResponseWithNoStoreNotCacheable();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HttpHeaderParsingHelpers.HeaderContains(responseCacheControlHeader, CacheControlValues.NoStoreString))
|
||||||
{
|
{
|
||||||
context.Logger.LogResponseWithNoStoreNotCacheable();
|
context.Logger.LogResponseWithNoStoreNotCacheable();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check no-cache
|
// Check no-cache
|
||||||
if (context.ResponseCacheControlHeaderValue.NoCache)
|
if (HttpHeaderParsingHelpers.HeaderContains(responseCacheControlHeader, CacheControlValues.NoCacheString))
|
||||||
{
|
{
|
||||||
context.Logger.LogResponseWithNoCacheNotCacheable();
|
context.Logger.LogResponseWithNoCacheNotCacheable();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -96,7 +99,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check private
|
// Check private
|
||||||
if (context.ResponseCacheControlHeaderValue.Private)
|
if (HttpHeaderParsingHelpers.HeaderContains(responseCacheControlHeader, CacheControlValues.PrivateString))
|
||||||
{
|
{
|
||||||
context.Logger.LogResponseWithPrivateNotCacheable();
|
context.Logger.LogResponseWithPrivateNotCacheable();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -112,8 +115,8 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
// Check response freshness
|
// Check response freshness
|
||||||
if (!context.ResponseDate.HasValue)
|
if (!context.ResponseDate.HasValue)
|
||||||
{
|
{
|
||||||
if (!context.ResponseCacheControlHeaderValue.SharedMaxAge.HasValue &&
|
if (!context.ResponseSharedMaxAge.HasValue &&
|
||||||
!context.ResponseCacheControlHeaderValue.MaxAge.HasValue &&
|
!context.ResponseMaxAge.HasValue &&
|
||||||
context.ResponseTime.Value >= context.ResponseExpires)
|
context.ResponseTime.Value >= context.ResponseExpires)
|
||||||
{
|
{
|
||||||
context.Logger.LogExpirationExpiresExceeded(context.ResponseTime.Value, context.ResponseExpires.Value);
|
context.Logger.LogExpirationExpiresExceeded(context.ResponseTime.Value, context.ResponseExpires.Value);
|
||||||
|
|
@ -125,22 +128,20 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
var age = context.ResponseTime.Value - context.ResponseDate.Value;
|
var age = context.ResponseTime.Value - context.ResponseDate.Value;
|
||||||
|
|
||||||
// Validate shared max age
|
// Validate shared max age
|
||||||
var sharedMaxAge = context.ResponseCacheControlHeaderValue.SharedMaxAge;
|
if (age >= context.ResponseSharedMaxAge)
|
||||||
if (age >= sharedMaxAge)
|
|
||||||
{
|
{
|
||||||
context.Logger.LogExpirationSharedMaxAgeExceeded(age, sharedMaxAge.Value);
|
context.Logger.LogExpirationSharedMaxAgeExceeded(age, context.ResponseSharedMaxAge.Value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (!sharedMaxAge.HasValue)
|
else if (!context.ResponseSharedMaxAge.HasValue)
|
||||||
{
|
{
|
||||||
// Validate max age
|
// Validate max age
|
||||||
var maxAge = context.ResponseCacheControlHeaderValue.MaxAge;
|
if (age >= context.ResponseMaxAge)
|
||||||
if (age >= maxAge)
|
|
||||||
{
|
{
|
||||||
context.Logger.LogExpirationMaxAgeExceeded(age, maxAge.Value);
|
context.Logger.LogExpirationMaxAgeExceeded(age, context.ResponseMaxAge.Value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (!maxAge.HasValue)
|
else if (!context.ResponseMaxAge.HasValue)
|
||||||
{
|
{
|
||||||
// Validate expiration
|
// Validate expiration
|
||||||
if (context.ResponseTime.Value >= context.ResponseExpires)
|
if (context.ResponseTime.Value >= context.ResponseExpires)
|
||||||
|
|
@ -158,44 +159,53 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
public virtual bool IsCachedEntryFresh(ResponseCachingContext context)
|
public virtual bool IsCachedEntryFresh(ResponseCachingContext context)
|
||||||
{
|
{
|
||||||
var age = context.CachedEntryAge.Value;
|
var age = context.CachedEntryAge.Value;
|
||||||
var cachedControlHeaders = context.CachedResponseHeaders.CacheControl ?? EmptyCacheControl;
|
var cachedControlHeaders = context.CachedResponseHeaders[HeaderNames.CacheControl];
|
||||||
|
var requestCacheControlHeaders = context.HttpContext.Request.Headers[HeaderNames.CacheControl];
|
||||||
|
|
||||||
// Add min-fresh requirements
|
// Add min-fresh requirements
|
||||||
var minFresh = context.RequestCacheControlHeaderValue.MinFresh;
|
TimeSpan? minFresh;
|
||||||
if (minFresh.HasValue)
|
if (HttpHeaderParsingHelpers.TryParseHeaderTimeSpan(requestCacheControlHeaders, CacheControlValues.MinFreshString, out minFresh))
|
||||||
{
|
{
|
||||||
age += minFresh.Value;
|
age += minFresh.Value;
|
||||||
context.Logger.LogExpirationMinFreshAdded(minFresh.Value);
|
context.Logger.LogExpirationMinFreshAdded(minFresh.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate shared max age, this overrides any max age settings for shared caches
|
// Validate shared max age, this overrides any max age settings for shared caches
|
||||||
var sharedMaxAge = cachedControlHeaders.SharedMaxAge;
|
TimeSpan? cachedSharedMaxAge;
|
||||||
if (age >= sharedMaxAge)
|
HttpHeaderParsingHelpers.TryParseHeaderTimeSpan(cachedControlHeaders, CacheControlValues.SharedMaxAgeString, out cachedSharedMaxAge);
|
||||||
|
|
||||||
|
if (age >= cachedSharedMaxAge)
|
||||||
{
|
{
|
||||||
// shared max age implies must revalidate
|
// shared max age implies must revalidate
|
||||||
context.Logger.LogExpirationSharedMaxAgeExceeded(age, sharedMaxAge.Value);
|
context.Logger.LogExpirationSharedMaxAgeExceeded(age, cachedSharedMaxAge.Value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (!sharedMaxAge.HasValue)
|
else if (!cachedSharedMaxAge.HasValue)
|
||||||
{
|
{
|
||||||
var cachedMaxAge = cachedControlHeaders.MaxAge;
|
TimeSpan? requestMaxAge;
|
||||||
var requestMaxAge = context.RequestCacheControlHeaderValue.MaxAge;
|
HttpHeaderParsingHelpers.TryParseHeaderTimeSpan(requestCacheControlHeaders, CacheControlValues.MaxAgeString, out requestMaxAge);
|
||||||
|
|
||||||
|
TimeSpan? cachedMaxAge;
|
||||||
|
HttpHeaderParsingHelpers.TryParseHeaderTimeSpan(cachedControlHeaders, CacheControlValues.MaxAgeString, out cachedMaxAge);
|
||||||
|
|
||||||
var lowestMaxAge = cachedMaxAge < requestMaxAge ? cachedMaxAge : requestMaxAge ?? cachedMaxAge;
|
var lowestMaxAge = cachedMaxAge < requestMaxAge ? cachedMaxAge : requestMaxAge ?? cachedMaxAge;
|
||||||
// Validate max age
|
// Validate max age
|
||||||
if (age >= lowestMaxAge)
|
if (age >= lowestMaxAge)
|
||||||
{
|
{
|
||||||
// Must revalidate
|
// Must revalidate
|
||||||
if (cachedControlHeaders.MustRevalidate)
|
if (HttpHeaderParsingHelpers.HeaderContains(cachedControlHeaders, CacheControlValues.MustRevalidateString))
|
||||||
{
|
{
|
||||||
context.Logger.LogExpirationMustRevalidate(age, lowestMaxAge.Value);
|
context.Logger.LogExpirationMustRevalidate(age, lowestMaxAge.Value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimeSpan? requestMaxStale;
|
||||||
|
HttpHeaderParsingHelpers.TryParseHeaderTimeSpan(requestCacheControlHeaders, CacheControlValues.MaxStaleString, out requestMaxStale);
|
||||||
|
|
||||||
// Request allows stale values
|
// Request allows stale values
|
||||||
var maxStaleLimit = context.RequestCacheControlHeaderValue.MaxStaleLimit;
|
if (requestMaxStale.HasValue && age - lowestMaxAge < requestMaxStale)
|
||||||
if (maxStaleLimit.HasValue && age - lowestMaxAge < maxStaleLimit)
|
|
||||||
{
|
{
|
||||||
context.Logger.LogExpirationMaxStaleSatisfied(age, lowestMaxAge.Value, maxStaleLimit.Value);
|
context.Logger.LogExpirationMaxStaleSatisfied(age, lowestMaxAge.Value, requestMaxStale.Value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,11 +215,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Internal
|
||||||
else if (!cachedMaxAge.HasValue && !requestMaxAge.HasValue)
|
else if (!cachedMaxAge.HasValue && !requestMaxAge.HasValue)
|
||||||
{
|
{
|
||||||
// Validate expiration
|
// Validate expiration
|
||||||
var responseTime = context.ResponseTime.Value;
|
DateTimeOffset expires;
|
||||||
var expires = context.CachedResponseHeaders.Expires;
|
if (HttpHeaderParsingHelpers.TryParseHeaderDate(context.CachedResponseHeaders[HeaderNames.Expires], out expires) &&
|
||||||
if (responseTime >= expires)
|
context.ResponseTime.Value >= expires)
|
||||||
{
|
{
|
||||||
context.Logger.LogExpirationExpiresExceeded(responseTime, expires.Value);
|
context.Logger.LogExpirationExpiresExceeded(context.ResponseTime.Value, expires);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
|
||||||
}
|
}
|
||||||
|
|
||||||
context.CachedResponse = cachedResponse;
|
context.CachedResponse = cachedResponse;
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(cachedResponse.Headers);
|
context.CachedResponseHeaders = cachedResponse.Headers;
|
||||||
context.ResponseTime = _options.SystemClock.UtcNow;
|
context.ResponseTime = _options.SystemClock.UtcNow;
|
||||||
var cachedEntryAge = context.ResponseTime.Value - context.CachedResponse.Created;
|
var cachedEntryAge = context.ResponseTime.Value - context.CachedResponse.Created;
|
||||||
context.CachedEntryAge = cachedEntryAge > TimeSpan.Zero ? cachedEntryAge : TimeSpan.Zero;
|
context.CachedEntryAge = cachedEntryAge > TimeSpan.Zero ? cachedEntryAge : TimeSpan.Zero;
|
||||||
|
|
@ -198,7 +198,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.RequestCacheControlHeaderValue.OnlyIfCached)
|
if (HttpHeaderParsingHelpers.HeaderContains(context.HttpContext.Request.Headers[HeaderNames.CacheControl], CacheControlValues.OnlyIfCachedString))
|
||||||
{
|
{
|
||||||
_logger.LogGatewayTimeoutServed();
|
_logger.LogGatewayTimeoutServed();
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status504GatewayTimeout;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status504GatewayTimeout;
|
||||||
|
|
@ -219,8 +219,8 @@ namespace Microsoft.AspNetCore.ResponseCaching
|
||||||
var response = context.HttpContext.Response;
|
var response = context.HttpContext.Response;
|
||||||
var varyHeaders = new StringValues(response.Headers.GetCommaSeparatedValues(HeaderNames.Vary));
|
var varyHeaders = new StringValues(response.Headers.GetCommaSeparatedValues(HeaderNames.Vary));
|
||||||
var varyQueryKeys = new StringValues(context.HttpContext.Features.Get<IResponseCachingFeature>()?.VaryByQueryKeys);
|
var varyQueryKeys = new StringValues(context.HttpContext.Features.Get<IResponseCachingFeature>()?.VaryByQueryKeys);
|
||||||
context.CachedResponseValidFor = context.ResponseCacheControlHeaderValue.SharedMaxAge ??
|
context.CachedResponseValidFor = context.ResponseSharedMaxAge ??
|
||||||
context.ResponseCacheControlHeaderValue.MaxAge ??
|
context.ResponseMaxAge ??
|
||||||
(context.ResponseExpires - context.ResponseTime.Value) ??
|
(context.ResponseExpires - context.ResponseTime.Value) ??
|
||||||
DefaultExpirationTimeSpan;
|
DefaultExpirationTimeSpan;
|
||||||
|
|
||||||
|
|
@ -256,7 +256,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
|
||||||
{
|
{
|
||||||
context.ResponseDate = context.ResponseTime.Value;
|
context.ResponseDate = context.ResponseTime.Value;
|
||||||
// Setting the date on the raw response headers.
|
// Setting the date on the raw response headers.
|
||||||
context.TypedResponseHeaders.Date = context.ResponseDate;
|
context.HttpContext.Response.Headers[HeaderNames.Date] = HeaderUtilities.FormatDate(context.ResponseDate.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the response on the state
|
// Store the response on the state
|
||||||
|
|
@ -266,7 +266,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
|
||||||
StatusCode = context.HttpContext.Response.StatusCode
|
StatusCode = context.HttpContext.Response.StatusCode
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var header in context.TypedResponseHeaders.Headers)
|
foreach (var header in context.HttpContext.Response.Headers)
|
||||||
{
|
{
|
||||||
if (!string.Equals(header.Key, HeaderNames.Age, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(header.Key, HeaderNames.Age, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
|
@ -282,7 +282,7 @@ namespace Microsoft.AspNetCore.ResponseCaching
|
||||||
|
|
||||||
internal async Task FinalizeCacheBodyAsync(ResponseCachingContext context)
|
internal async Task FinalizeCacheBodyAsync(ResponseCachingContext context)
|
||||||
{
|
{
|
||||||
var contentLength = context.TypedResponseHeaders.ContentLength;
|
var contentLength = context.HttpContext.Response.ContentLength;
|
||||||
if (context.ShouldCacheResponse && context.ResponseCachingStream.BufferingEnabled)
|
if (context.ShouldCacheResponse && context.ResponseCachingStream.BufferingEnabled)
|
||||||
{
|
{
|
||||||
var bufferStream = context.ResponseCachingStream.GetBufferStream();
|
var bufferStream = context.ResponseCachingStream.GetBufferStream();
|
||||||
|
|
@ -355,37 +355,51 @@ namespace Microsoft.AspNetCore.ResponseCaching
|
||||||
internal static bool ContentIsNotModified(ResponseCachingContext context)
|
internal static bool ContentIsNotModified(ResponseCachingContext context)
|
||||||
{
|
{
|
||||||
var cachedResponseHeaders = context.CachedResponseHeaders;
|
var cachedResponseHeaders = context.CachedResponseHeaders;
|
||||||
var ifNoneMatchHeader = context.TypedRequestHeaders.IfNoneMatch;
|
var ifNoneMatchHeader = context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch];
|
||||||
|
|
||||||
if (ifNoneMatchHeader != null)
|
if (!StringValues.IsNullOrEmpty(ifNoneMatchHeader))
|
||||||
{
|
{
|
||||||
if (ifNoneMatchHeader.Count == 1 && ifNoneMatchHeader[0].Equals(EntityTagHeaderValue.Any))
|
if (ifNoneMatchHeader.Count == 1 && ifNoneMatchHeader[0].Equals(EntityTagHeaderValue.Any.Tag))
|
||||||
{
|
{
|
||||||
context.Logger.LogNotModifiedIfNoneMatchStar();
|
context.Logger.LogNotModifiedIfNoneMatchStar();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cachedResponseHeaders.ETag != null)
|
if (!StringValues.IsNullOrEmpty(cachedResponseHeaders[HeaderNames.ETag]))
|
||||||
{
|
{
|
||||||
foreach (var tag in ifNoneMatchHeader)
|
EntityTagHeaderValue eTag;
|
||||||
|
if (EntityTagHeaderValue.TryParse(cachedResponseHeaders[HeaderNames.ETag], out eTag))
|
||||||
{
|
{
|
||||||
if (cachedResponseHeaders.ETag.Compare(tag, useStrongComparison: false))
|
foreach (var tag in ifNoneMatchHeader)
|
||||||
{
|
{
|
||||||
context.Logger.LogNotModifiedIfNoneMatchMatched(tag);
|
EntityTagHeaderValue requestETag;
|
||||||
return true;
|
if (EntityTagHeaderValue.TryParse(tag, out requestETag) &&
|
||||||
|
eTag.Compare(requestETag, useStrongComparison: false))
|
||||||
|
{
|
||||||
|
context.Logger.LogNotModifiedIfNoneMatchMatched(requestETag);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var ifUnmodifiedSince = context.TypedRequestHeaders.IfUnmodifiedSince;
|
var ifUnmodifiedSince = context.HttpContext.Request.Headers[HeaderNames.IfUnmodifiedSince];
|
||||||
if (ifUnmodifiedSince != null)
|
if (!StringValues.IsNullOrEmpty(ifUnmodifiedSince))
|
||||||
{
|
{
|
||||||
var lastModified = cachedResponseHeaders.LastModified ?? cachedResponseHeaders.Date;
|
DateTimeOffset modified;
|
||||||
if (lastModified <= ifUnmodifiedSince)
|
if (!HttpHeaderParsingHelpers.TryParseHeaderDate(cachedResponseHeaders[HeaderNames.LastModified], out modified) &&
|
||||||
|
!HttpHeaderParsingHelpers.TryParseHeaderDate(cachedResponseHeaders[HeaderNames.Date], out modified))
|
||||||
{
|
{
|
||||||
context.Logger.LogNotModifiedIfUnmodifiedSinceSatisfied(lastModified.Value, ifUnmodifiedSince.Value);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTimeOffset unmodifiedSince;
|
||||||
|
if (HttpHeaderParsingHelpers.TryParseHeaderDate(ifUnmodifiedSince, out unmodifiedSince) &&
|
||||||
|
modified <= unmodifiedSince)
|
||||||
|
{
|
||||||
|
context.Logger.LogNotModifiedIfUnmodifiedSinceSatisfied(modified, unmodifiedSince);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
// 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;
|
||||||
|
using Microsoft.AspNetCore.ResponseCaching.Internal;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
|
{
|
||||||
|
public class ParsingHelpersTests
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData("h=1", "h", 1)]
|
||||||
|
[InlineData("header1=3, header2=10", "header1", 3)]
|
||||||
|
[InlineData("header1 =45, header2=80", "header1", 45)]
|
||||||
|
[InlineData("header1= 89 , header2=22", "header1", 89)]
|
||||||
|
[InlineData("header1= 89 , header2= 42", "header2", 42)]
|
||||||
|
void TryGetHeaderValue_Succeeds(string headerValue, string headerName, int expectedValue)
|
||||||
|
{
|
||||||
|
TimeSpan? value;
|
||||||
|
Assert.True(HttpHeaderParsingHelpers.TryParseHeaderTimeSpan(new StringValues(headerValue), headerName, out value));
|
||||||
|
Assert.Equal(TimeSpan.FromSeconds(expectedValue), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("h=", "h")]
|
||||||
|
[InlineData("header1=, header2=10", "header1")]
|
||||||
|
[InlineData("header1 , header2=80", "header1")]
|
||||||
|
[InlineData("h=10", "header")]
|
||||||
|
[InlineData("", "")]
|
||||||
|
[InlineData(null, null)]
|
||||||
|
void TryGetHeaderValue_Fails(string headerValue, string headerName)
|
||||||
|
{
|
||||||
|
TimeSpan? value;
|
||||||
|
Assert.False(HttpHeaderParsingHelpers.TryParseHeaderTimeSpan(new StringValues(headerValue), headerName, out value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,10 +23,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var middleware = TestUtils.CreateTestMiddleware(testSink: sink, cache: cache, keyProvider: new TestResponseCachingKeyProvider());
|
var middleware = TestUtils.CreateTestMiddleware(testSink: sink, cache: cache, keyProvider: new TestResponseCachingKeyProvider());
|
||||||
var context = TestUtils.CreateTestContext();
|
var context = TestUtils.CreateTestContext();
|
||||||
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
OnlyIfCached = true
|
OnlyIfCached = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.True(await middleware.TryServeFromCacheAsync(context));
|
Assert.True(await middleware.TryServeFromCacheAsync(context));
|
||||||
Assert.Equal(StatusCodes.Status504GatewayTimeout, context.HttpContext.Response.StatusCode);
|
Assert.Equal(StatusCodes.Status504GatewayTimeout, context.HttpContext.Response.StatusCode);
|
||||||
|
|
@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary());
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
|
||||||
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -161,22 +161,22 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var utcNow = DateTimeOffset.UtcNow;
|
var utcNow = DateTimeOffset.UtcNow;
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary());
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
|
||||||
context.TypedRequestHeaders.IfUnmodifiedSince = utcNow;
|
context.HttpContext.Request.Headers[HeaderNames.IfUnmodifiedSince] = HeaderUtilities.FormatDate(utcNow);
|
||||||
|
|
||||||
// Verify modifications in the past succeeds
|
// Verify modifications in the past succeeds
|
||||||
context.CachedResponseHeaders.Date = utcNow - TimeSpan.FromSeconds(10);
|
context.CachedResponseHeaders[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow - TimeSpan.FromSeconds(10));
|
||||||
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
Assert.Equal(1, sink.Writes.Count);
|
Assert.Equal(1, sink.Writes.Count);
|
||||||
|
|
||||||
// Verify modifications at present succeeds
|
// Verify modifications at present succeeds
|
||||||
context.CachedResponseHeaders.Date = utcNow;
|
context.CachedResponseHeaders[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow);
|
||||||
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
Assert.Equal(2, sink.Writes.Count);
|
Assert.Equal(2, sink.Writes.Count);
|
||||||
|
|
||||||
// Verify modifications in the future fails
|
// Verify modifications in the future fails
|
||||||
context.CachedResponseHeaders.Date = utcNow + TimeSpan.FromSeconds(10);
|
context.CachedResponseHeaders[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(10));
|
||||||
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
|
|
||||||
// Verify logging
|
// Verify logging
|
||||||
|
|
@ -192,25 +192,25 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var utcNow = DateTimeOffset.UtcNow;
|
var utcNow = DateTimeOffset.UtcNow;
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary());
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
|
||||||
context.TypedRequestHeaders.IfUnmodifiedSince = utcNow;
|
context.HttpContext.Request.Headers[HeaderNames.IfUnmodifiedSince] = HeaderUtilities.FormatDate(utcNow);
|
||||||
|
|
||||||
// Verify modifications in the past succeeds
|
// Verify modifications in the past succeeds
|
||||||
context.CachedResponseHeaders.Date = utcNow + TimeSpan.FromSeconds(10);
|
context.CachedResponseHeaders[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(10));
|
||||||
context.CachedResponseHeaders.LastModified = utcNow - TimeSpan.FromSeconds(10);
|
context.CachedResponseHeaders[HeaderNames.LastModified] = HeaderUtilities.FormatDate(utcNow - TimeSpan.FromSeconds(10));
|
||||||
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
Assert.Equal(1, sink.Writes.Count);
|
Assert.Equal(1, sink.Writes.Count);
|
||||||
|
|
||||||
// Verify modifications at present
|
// Verify modifications at present
|
||||||
context.CachedResponseHeaders.Date = utcNow + TimeSpan.FromSeconds(10);
|
context.CachedResponseHeaders[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(10));
|
||||||
context.CachedResponseHeaders.LastModified = utcNow;
|
context.CachedResponseHeaders[HeaderNames.LastModified] = HeaderUtilities.FormatDate(utcNow);
|
||||||
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
Assert.Equal(2, sink.Writes.Count);
|
Assert.Equal(2, sink.Writes.Count);
|
||||||
|
|
||||||
// Verify modifications in the future fails
|
// Verify modifications in the future fails
|
||||||
context.CachedResponseHeaders.Date = utcNow - TimeSpan.FromSeconds(10);
|
context.CachedResponseHeaders[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow - TimeSpan.FromSeconds(10));
|
||||||
context.CachedResponseHeaders.LastModified = utcNow + TimeSpan.FromSeconds(10);
|
context.CachedResponseHeaders[HeaderNames.LastModified] = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(10));
|
||||||
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
|
|
||||||
// Verify logging
|
// Verify logging
|
||||||
|
|
@ -226,13 +226,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var utcNow = DateTimeOffset.UtcNow;
|
var utcNow = DateTimeOffset.UtcNow;
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary());
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
|
||||||
// This would fail the IfUnmodifiedSince checks
|
// This would fail the IfUnmodifiedSince checks
|
||||||
context.TypedRequestHeaders.IfUnmodifiedSince = utcNow;
|
context.HttpContext.Request.Headers[HeaderNames.IfUnmodifiedSince] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.CachedResponseHeaders.LastModified = utcNow + TimeSpan.FromSeconds(10);
|
context.CachedResponseHeaders[HeaderNames.LastModified] = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(10));
|
||||||
|
|
||||||
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { EntityTagHeaderValue.Any });
|
context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = EntityTagHeaderValue.Any.ToString();
|
||||||
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
sink.Writes,
|
sink.Writes,
|
||||||
|
|
@ -245,13 +245,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var utcNow = DateTimeOffset.UtcNow;
|
var utcNow = DateTimeOffset.UtcNow;
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary());
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
|
||||||
// This would pass the IfUnmodifiedSince checks
|
// This would pass the IfUnmodifiedSince checks
|
||||||
context.TypedRequestHeaders.IfUnmodifiedSince = utcNow;
|
context.HttpContext.Request.Headers[HeaderNames.IfUnmodifiedSince] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.CachedResponseHeaders.LastModified = utcNow - TimeSpan.FromSeconds(10);
|
context.CachedResponseHeaders[HeaderNames.LastModified] = HeaderUtilities.FormatDate(utcNow - TimeSpan.FromSeconds(10));
|
||||||
|
|
||||||
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") });
|
context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }).ToString();
|
||||||
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
}
|
}
|
||||||
|
|
@ -261,9 +261,9 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary());
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
|
||||||
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") });
|
context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }).ToString();
|
||||||
|
|
||||||
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -289,12 +289,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
{
|
context.CachedResponseHeaders[HeaderNames.ETag] = responseETag.ToString();
|
||||||
ETag = responseETag
|
|
||||||
};
|
|
||||||
|
|
||||||
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { requestETag });
|
context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = requestETag.ToString();
|
||||||
|
|
||||||
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -307,12 +305,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
{
|
context.HttpContext.Response.Headers[HeaderNames.ETag] = new EntityTagHeaderValue("\"E2\"").ToString();
|
||||||
ETag = new EntityTagHeaderValue("\"E2\"")
|
|
||||||
};
|
|
||||||
|
|
||||||
context.TypedRequestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") });
|
context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }).ToString();
|
||||||
|
|
||||||
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -340,10 +336,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var middleware = TestUtils.CreateTestMiddleware(testSink: sink, policyProvider: new ResponseCachingPolicyProvider());
|
var middleware = TestUtils.CreateTestMiddleware(testSink: sink, policyProvider: new ResponseCachingPolicyProvider());
|
||||||
var context = TestUtils.CreateTestContext();
|
var context = TestUtils.CreateTestContext();
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true
|
Public = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.False(context.ShouldCacheResponse);
|
Assert.False(context.ShouldCacheResponse);
|
||||||
|
|
||||||
|
|
@ -375,7 +371,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var context = TestUtils.CreateTestContext();
|
var context = TestUtils.CreateTestContext();
|
||||||
|
|
||||||
context.ResponseTime = utcNow;
|
context.ResponseTime = utcNow;
|
||||||
context.TypedResponseHeaders.Expires = utcNow + TimeSpan.FromSeconds(11);
|
context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(11));
|
||||||
|
|
||||||
await middleware.FinalizeCacheHeadersAsync(context);
|
await middleware.FinalizeCacheHeadersAsync(context);
|
||||||
|
|
||||||
|
|
@ -389,12 +385,12 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var middleware = TestUtils.CreateTestMiddleware(testSink: sink);
|
var middleware = TestUtils.CreateTestMiddleware(testSink: sink);
|
||||||
var context = TestUtils.CreateTestContext();
|
var context = TestUtils.CreateTestContext();
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
MaxAge = TimeSpan.FromSeconds(12)
|
MaxAge = TimeSpan.FromSeconds(12)
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
context.TypedResponseHeaders.Expires = context.ResponseTime + TimeSpan.FromSeconds(11);
|
context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(context.ResponseTime.Value + TimeSpan.FromSeconds(11));
|
||||||
|
|
||||||
await middleware.FinalizeCacheHeadersAsync(context);
|
await middleware.FinalizeCacheHeadersAsync(context);
|
||||||
|
|
||||||
|
|
@ -408,13 +404,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var middleware = TestUtils.CreateTestMiddleware(testSink: sink);
|
var middleware = TestUtils.CreateTestMiddleware(testSink: sink);
|
||||||
var context = TestUtils.CreateTestContext();
|
var context = TestUtils.CreateTestContext();
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
MaxAge = TimeSpan.FromSeconds(12),
|
MaxAge = TimeSpan.FromSeconds(12),
|
||||||
SharedMaxAge = TimeSpan.FromSeconds(13)
|
SharedMaxAge = TimeSpan.FromSeconds(13)
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
context.TypedResponseHeaders.Expires = context.ResponseTime + TimeSpan.FromSeconds(11);
|
context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(context.ResponseTime.Value + TimeSpan.FromSeconds(11));
|
||||||
|
|
||||||
await middleware.FinalizeCacheHeadersAsync(context);
|
await middleware.FinalizeCacheHeadersAsync(context);
|
||||||
|
|
||||||
|
|
@ -538,11 +534,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var context = TestUtils.CreateTestContext();
|
var context = TestUtils.CreateTestContext();
|
||||||
context.ResponseTime = utcNow;
|
context.ResponseTime = utcNow;
|
||||||
|
|
||||||
Assert.Null(context.TypedResponseHeaders.Date);
|
Assert.True(StringValues.IsNullOrEmpty(context.HttpContext.Response.Headers[HeaderNames.Date]));
|
||||||
|
|
||||||
await middleware.FinalizeCacheHeadersAsync(context);
|
await middleware.FinalizeCacheHeadersAsync(context);
|
||||||
|
|
||||||
Assert.Equal(utcNow, context.TypedResponseHeaders.Date);
|
Assert.Equal(HeaderUtilities.FormatDate(utcNow), context.HttpContext.Response.Headers[HeaderNames.Date]);
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -553,14 +549,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var middleware = TestUtils.CreateTestMiddleware(testSink: sink);
|
var middleware = TestUtils.CreateTestMiddleware(testSink: sink);
|
||||||
var context = TestUtils.CreateTestContext();
|
var context = TestUtils.CreateTestContext();
|
||||||
context.TypedResponseHeaders.Date = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.ResponseTime = utcNow + TimeSpan.FromSeconds(10);
|
context.ResponseTime = utcNow + TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
Assert.Equal(utcNow, context.TypedResponseHeaders.Date);
|
Assert.Equal(HeaderUtilities.FormatDate(utcNow), context.HttpContext.Response.Headers[HeaderNames.Date]);
|
||||||
|
|
||||||
await middleware.FinalizeCacheHeadersAsync(context);
|
await middleware.FinalizeCacheHeadersAsync(context);
|
||||||
|
|
||||||
Assert.Equal(utcNow, context.TypedResponseHeaders.Date);
|
Assert.Equal(HeaderUtilities.FormatDate(utcNow), context.HttpContext.Response.Headers[HeaderNames.Date]);
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,10 +88,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Request.Method = HttpMethods.Get;
|
context.HttpContext.Request.Method = HttpMethods.Get;
|
||||||
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
NoCache = true
|
NoCache = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsRequestCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsRequestCacheable(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -105,10 +105,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Request.Method = HttpMethods.Get;
|
context.HttpContext.Request.Method = HttpMethods.Get;
|
||||||
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
NoStore = true
|
NoStore = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsRequestCacheable(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsRequestCacheable(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -158,10 +158,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true
|
Public = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -172,11 +172,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true,
|
Public = true,
|
||||||
NoCache = true
|
NoCache = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -189,14 +189,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
NoStore = true
|
NoStore = true
|
||||||
};
|
}.ToString();
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true
|
Public = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -209,11 +209,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true,
|
Public = true,
|
||||||
NoStore = true
|
NoStore = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -226,10 +226,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true
|
Public = true
|
||||||
};
|
}.ToString();
|
||||||
context.HttpContext.Response.Headers[HeaderNames.SetCookie] = "cookieName=cookieValue";
|
context.HttpContext.Response.Headers[HeaderNames.SetCookie] = "cookieName=cookieValue";
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
|
|
@ -243,10 +243,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true
|
Public = true
|
||||||
};
|
}.ToString();
|
||||||
context.HttpContext.Response.Headers[HeaderNames.Vary] = "*";
|
context.HttpContext.Response.Headers[HeaderNames.Vary] = "*";
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
|
|
@ -260,11 +260,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true,
|
Public = true,
|
||||||
Private = true
|
Private = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -279,10 +279,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Response.StatusCode = statusCode;
|
context.HttpContext.Response.StatusCode = statusCode;
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true
|
Public = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -342,10 +342,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Response.StatusCode = statusCode;
|
context.HttpContext.Response.StatusCode = statusCode;
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true
|
Public = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -359,13 +359,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true
|
Public = true
|
||||||
};
|
}.ToString();
|
||||||
|
|
||||||
var utcNow = DateTimeOffset.UtcNow;
|
var utcNow = DateTimeOffset.UtcNow;
|
||||||
context.TypedResponseHeaders.Date = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.ResponseTime = DateTimeOffset.MaxValue;
|
context.ResponseTime = DateTimeOffset.MaxValue;
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
|
|
@ -378,14 +378,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true
|
Public = true
|
||||||
};
|
}.ToString();
|
||||||
var utcNow = DateTimeOffset.UtcNow;
|
var utcNow = DateTimeOffset.UtcNow;
|
||||||
context.TypedResponseHeaders.Expires = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow);
|
||||||
|
|
||||||
context.TypedResponseHeaders.Date = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.ResponseTime = utcNow;
|
context.ResponseTime = utcNow;
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
|
|
@ -401,13 +401,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true,
|
Public = true,
|
||||||
MaxAge = TimeSpan.FromSeconds(10)
|
MaxAge = TimeSpan.FromSeconds(10)
|
||||||
};
|
}.ToString();
|
||||||
context.TypedResponseHeaders.Expires = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.TypedResponseHeaders.Date = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.ResponseTime = utcNow + TimeSpan.FromSeconds(9);
|
context.ResponseTime = utcNow + TimeSpan.FromSeconds(9);
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
|
|
@ -421,13 +421,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true,
|
Public = true,
|
||||||
MaxAge = TimeSpan.FromSeconds(10)
|
MaxAge = TimeSpan.FromSeconds(10)
|
||||||
};
|
}.ToString();
|
||||||
context.TypedResponseHeaders.Expires = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.TypedResponseHeaders.Date = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.ResponseTime = utcNow + TimeSpan.FromSeconds(10);
|
context.ResponseTime = utcNow + TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
|
|
@ -443,13 +443,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true,
|
Public = true,
|
||||||
MaxAge = TimeSpan.FromSeconds(10),
|
MaxAge = TimeSpan.FromSeconds(10),
|
||||||
SharedMaxAge = TimeSpan.FromSeconds(15)
|
SharedMaxAge = TimeSpan.FromSeconds(15)
|
||||||
};
|
}.ToString();
|
||||||
context.TypedResponseHeaders.Date = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.ResponseTime = utcNow + TimeSpan.FromSeconds(11);
|
context.ResponseTime = utcNow + TimeSpan.FromSeconds(11);
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
|
|
@ -463,13 +463,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
||||||
context.TypedResponseHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
Public = true,
|
Public = true,
|
||||||
MaxAge = TimeSpan.FromSeconds(10),
|
MaxAge = TimeSpan.FromSeconds(10),
|
||||||
SharedMaxAge = TimeSpan.FromSeconds(5)
|
SharedMaxAge = TimeSpan.FromSeconds(5)
|
||||||
};
|
}.ToString();
|
||||||
context.TypedResponseHeaders.Date = utcNow;
|
context.HttpContext.Response.Headers[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow);
|
||||||
context.ResponseTime = utcNow + TimeSpan.FromSeconds(5);
|
context.ResponseTime = utcNow + TimeSpan.FromSeconds(5);
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
|
||||||
|
|
@ -486,7 +486,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.ResponseTime = DateTimeOffset.MaxValue;
|
context.ResponseTime = DateTimeOffset.MaxValue;
|
||||||
context.CachedEntryAge = TimeSpan.MaxValue;
|
context.CachedEntryAge = TimeSpan.MaxValue;
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary());
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -500,13 +500,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.ResponseTime = DateTimeOffset.MaxValue;
|
context.ResponseTime = DateTimeOffset.MaxValue;
|
||||||
context.CachedEntryAge = TimeSpan.MaxValue;
|
context.CachedEntryAge = TimeSpan.MaxValue;
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
Public = true
|
||||||
{
|
}.ToString();
|
||||||
Public = true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -520,14 +518,12 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.ResponseTime = utcNow;
|
context.ResponseTime = utcNow;
|
||||||
context.CachedEntryAge = TimeSpan.Zero;
|
context.CachedEntryAge = TimeSpan.Zero;
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
Public = true
|
||||||
{
|
}.ToString();
|
||||||
Public = true
|
context.CachedResponseHeaders[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow);
|
||||||
},
|
|
||||||
Expires = utcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -543,15 +539,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedEntryAge = TimeSpan.FromSeconds(9);
|
context.CachedEntryAge = TimeSpan.FromSeconds(9);
|
||||||
context.ResponseTime = utcNow + context.CachedEntryAge;
|
context.ResponseTime = utcNow + context.CachedEntryAge;
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
Public = true,
|
||||||
{
|
MaxAge = TimeSpan.FromSeconds(10)
|
||||||
Public = true,
|
}.ToString();
|
||||||
MaxAge = TimeSpan.FromSeconds(10)
|
context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow);
|
||||||
},
|
|
||||||
Expires = utcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -565,15 +559,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedEntryAge = TimeSpan.FromSeconds(10);
|
context.CachedEntryAge = TimeSpan.FromSeconds(10);
|
||||||
context.ResponseTime = utcNow + context.CachedEntryAge;
|
context.ResponseTime = utcNow + context.CachedEntryAge;
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
Public = true,
|
||||||
{
|
MaxAge = TimeSpan.FromSeconds(10)
|
||||||
Public = true,
|
}.ToString();
|
||||||
MaxAge = TimeSpan.FromSeconds(10)
|
context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow);
|
||||||
},
|
|
||||||
Expires = utcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -589,16 +581,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedEntryAge = TimeSpan.FromSeconds(11);
|
context.CachedEntryAge = TimeSpan.FromSeconds(11);
|
||||||
context.ResponseTime = utcNow + context.CachedEntryAge;
|
context.ResponseTime = utcNow + context.CachedEntryAge;
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
Public = true,
|
||||||
{
|
MaxAge = TimeSpan.FromSeconds(10),
|
||||||
Public = true,
|
SharedMaxAge = TimeSpan.FromSeconds(15)
|
||||||
MaxAge = TimeSpan.FromSeconds(10),
|
}.ToString();
|
||||||
SharedMaxAge = TimeSpan.FromSeconds(15)
|
context.CachedResponseHeaders[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow);
|
||||||
},
|
|
||||||
Expires = utcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
Assert.Empty(sink.Writes);
|
Assert.Empty(sink.Writes);
|
||||||
|
|
@ -612,16 +602,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.CachedEntryAge = TimeSpan.FromSeconds(5);
|
context.CachedEntryAge = TimeSpan.FromSeconds(5);
|
||||||
context.ResponseTime = utcNow + context.CachedEntryAge;
|
context.ResponseTime = utcNow + context.CachedEntryAge;
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
Public = true,
|
||||||
{
|
MaxAge = TimeSpan.FromSeconds(10),
|
||||||
Public = true,
|
SharedMaxAge = TimeSpan.FromSeconds(5)
|
||||||
MaxAge = TimeSpan.FromSeconds(10),
|
}.ToString();
|
||||||
SharedMaxAge = TimeSpan.FromSeconds(5)
|
context.CachedResponseHeaders[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow);
|
||||||
},
|
|
||||||
Expires = utcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
TestUtils.AssertLoggedMessages(
|
TestUtils.AssertLoggedMessages(
|
||||||
|
|
@ -634,18 +622,16 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
MinFresh = TimeSpan.FromSeconds(2)
|
MinFresh = TimeSpan.FromSeconds(2)
|
||||||
};
|
}.ToString();
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
MaxAge = TimeSpan.FromSeconds(10),
|
||||||
{
|
SharedMaxAge = TimeSpan.FromSeconds(5)
|
||||||
MaxAge = TimeSpan.FromSeconds(10),
|
}.ToString();
|
||||||
SharedMaxAge = TimeSpan.FromSeconds(5)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
context.CachedEntryAge = TimeSpan.FromSeconds(3);
|
context.CachedEntryAge = TimeSpan.FromSeconds(3);
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
|
|
@ -660,17 +646,15 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
MaxAge = TimeSpan.FromSeconds(5)
|
MaxAge = TimeSpan.FromSeconds(5)
|
||||||
};
|
}.ToString();
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
MaxAge = TimeSpan.FromSeconds(10),
|
||||||
{
|
}.ToString();
|
||||||
MaxAge = TimeSpan.FromSeconds(10),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
context.CachedEntryAge = TimeSpan.FromSeconds(5);
|
context.CachedEntryAge = TimeSpan.FromSeconds(5);
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
|
|
@ -684,19 +668,17 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
MaxAge = TimeSpan.FromSeconds(5),
|
MaxAge = TimeSpan.FromSeconds(5),
|
||||||
MaxStale = true, // This value must be set to true in order to specify MaxStaleLimit
|
MaxStale = true, // This value must be set to true in order to specify MaxStaleLimit
|
||||||
MaxStaleLimit = TimeSpan.FromSeconds(2)
|
MaxStaleLimit = TimeSpan.FromSeconds(2)
|
||||||
};
|
}.ToString();
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
MaxAge = TimeSpan.FromSeconds(5),
|
||||||
{
|
}.ToString();
|
||||||
MaxAge = TimeSpan.FromSeconds(5),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
context.CachedEntryAge = TimeSpan.FromSeconds(6);
|
context.CachedEntryAge = TimeSpan.FromSeconds(6);
|
||||||
|
|
||||||
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
|
|
@ -710,19 +692,17 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
MaxAge = TimeSpan.FromSeconds(5),
|
MaxAge = TimeSpan.FromSeconds(5),
|
||||||
MaxStale = true, // This value must be set to true in order to specify MaxStaleLimit
|
MaxStale = true, // This value must be set to true in order to specify MaxStaleLimit
|
||||||
MaxStaleLimit = TimeSpan.FromSeconds(1)
|
MaxStaleLimit = TimeSpan.FromSeconds(1)
|
||||||
};
|
}.ToString();
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
MaxAge = TimeSpan.FromSeconds(5),
|
||||||
{
|
}.ToString();
|
||||||
MaxAge = TimeSpan.FromSeconds(5),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
context.CachedEntryAge = TimeSpan.FromSeconds(6);
|
context.CachedEntryAge = TimeSpan.FromSeconds(6);
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
|
|
@ -736,20 +716,18 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
||||||
{
|
{
|
||||||
var sink = new TestSink();
|
var sink = new TestSink();
|
||||||
var context = TestUtils.CreateTestContext(sink);
|
var context = TestUtils.CreateTestContext(sink);
|
||||||
context.TypedRequestHeaders.CacheControl = new CacheControlHeaderValue()
|
context.HttpContext.Request.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
MaxAge = TimeSpan.FromSeconds(5),
|
MaxAge = TimeSpan.FromSeconds(5),
|
||||||
MaxStale = true, // This value must be set to true in order to specify MaxStaleLimit
|
MaxStale = true, // This value must be set to true in order to specify MaxStaleLimit
|
||||||
MaxStaleLimit = TimeSpan.FromSeconds(2)
|
MaxStaleLimit = TimeSpan.FromSeconds(2)
|
||||||
};
|
}.ToString();
|
||||||
context.CachedResponseHeaders = new ResponseHeaders(new HeaderDictionary())
|
context.CachedResponseHeaders = new HeaderDictionary();
|
||||||
|
context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
|
||||||
{
|
{
|
||||||
CacheControl = new CacheControlHeaderValue()
|
MaxAge = TimeSpan.FromSeconds(5),
|
||||||
{
|
MustRevalidate = true
|
||||||
MaxAge = TimeSpan.FromSeconds(5),
|
}.ToString();
|
||||||
MustRevalidate = true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
context.CachedEntryAge = TimeSpan.FromSeconds(6);
|
context.CachedEntryAge = TimeSpan.FromSeconds(6);
|
||||||
|
|
||||||
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue