Skip to content

Commit 89cdea1

Browse files
committed
fix #257 - again
1 parent f442766 commit 89cdea1

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

src/CacheCow.Client/CachingHandler.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public CachingHandler(ICacheStore cacheStore, IVaryHeaderStore varyHeaderStore)
7070
if (!response.StatusCode.IsIn(_cacheableStatuses))
7171
return ResponseValidationResult.NotCacheable;
7272

73+
// Technically any response is cacheable unless we are told so or some rules
74+
// but we DO NOT deem cacheable a response which does not bother to put CacheControl header
7375
if (!response.IsSuccessStatusCode || response.Headers.CacheControl == null ||
7476
response.Headers.CacheControl.NoStore) // || response.Headers.CacheControl.NoCache was removed. See issue
7577
return ResponseValidationResult.NotCacheable;
@@ -79,6 +81,9 @@ public CachingHandler(ICacheStore cacheStore, IVaryHeaderStore varyHeaderStore)
7981

8082
response.Headers.Date = response.Headers.Date ?? DateTimeOffset.UtcNow; // this also helps in cache creation
8183
var dateTimeOffset = response.Headers.Date;
84+
var age = TimeSpan.Zero;
85+
if (response.Headers.Age.HasValue)
86+
age = response.Headers.Age.Value;
8287

8388
TraceWriter.WriteLine(
8489
String.Format("CachedResponse date was => {0} - compared to UTC.Now => {1}", dateTimeOffset, DateTimeOffset.UtcNow), TraceLevel.Verbose);
@@ -94,19 +99,19 @@ public CachingHandler(ICacheStore cacheStore, IVaryHeaderStore varyHeaderStore)
9499
if (response.Headers.CacheControl.NoCache)
95100
return ResponseValidationResult.MustRevalidate;
96101

97-
// here we use
98-
if (response.Content.Headers.Expires != null &&
99-
response.Content.Headers.Expires < DateTimeOffset.UtcNow)
102+
if (response.Headers.CacheControl.MaxAge != null &&
103+
DateTimeOffset.UtcNow > response.Headers.Date.Value.Add(response.Headers.CacheControl.MaxAge.Value.Subtract(age)))
100104
return response.Headers.CacheControl.ShouldRevalidate(MustRevalidateByDefault)
101105
? ResponseValidationResult.MustRevalidate : ResponseValidationResult.Stale;
102106

103-
if (response.Headers.CacheControl.MaxAge != null &&
104-
DateTimeOffset.UtcNow > response.Headers.Date.Value.Add(response.Headers.CacheControl.MaxAge.Value))
107+
if (response.Headers.CacheControl.SharedMaxAge != null &&
108+
DateTimeOffset.UtcNow > response.Headers.Date.Value.Add(response.Headers.CacheControl.SharedMaxAge.Value.Subtract(age)))
105109
return response.Headers.CacheControl.ShouldRevalidate(MustRevalidateByDefault)
106110
? ResponseValidationResult.MustRevalidate : ResponseValidationResult.Stale;
107111

108-
if (response.Headers.CacheControl.SharedMaxAge != null &&
109-
DateTimeOffset.UtcNow > response.Headers.Date.Value.Add(response.Headers.CacheControl.SharedMaxAge.Value))
112+
// moved this down since Expires is < MaxAge
113+
if (response.Content.Headers.Expires != null &&
114+
response.Content.Headers.Expires < DateTimeOffset.UtcNow)
110115
return response.Headers.CacheControl.ShouldRevalidate(MustRevalidateByDefault)
111116
? ResponseValidationResult.MustRevalidate : ResponseValidationResult.Stale;
112117

test/CacheCow.Client.Tests/ResponseValidatorTests.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace CacheCow.Client.Tests
1212
{
13-
13+
1414
public class ResponseValidatorTests
1515
{
1616
[Theory]
@@ -158,5 +158,28 @@ public void Test_OK()
158158
Assert.Equal(cachingHandler.ResponseValidator(response), ResponseValidationResult.OK);
159159
}
160160

161+
// issue #257
162+
[Fact]
163+
public void Test_Age()
164+
{
165+
var cachingHandler = new CachingHandler()
166+
{
167+
MustRevalidateByDefault = false
168+
};
169+
170+
var response = new HttpResponseMessage(HttpStatusCode.OK);
171+
response.Headers.CacheControl = new CacheControlHeaderValue()
172+
{
173+
Public = true,
174+
MaxAge = TimeSpan.FromSeconds(200),
175+
MustRevalidate = false
176+
};
177+
response.Headers.Age = TimeSpan.FromSeconds(300); // more than MaxAge
178+
179+
response.Headers.Date = DateTimeOffset.UtcNow;
180+
response.Content = new ByteArrayContent(new byte[256]);
181+
Assert.Equal(ResponseValidationResult.Stale, cachingHandler.ResponseValidator(response));
182+
}
183+
161184
}
162185
}

0 commit comments

Comments
 (0)