LibHTTP+RequestServer: Send revalidation attributes without parsing

The caching RFC is quite strict about the format of date strings. If we
received a revalidation attribute with an invalid date string, we would
previously fail a runtime assertion. This was because to start a
revalidation request, we would simply check for the presence of any
revalidation header; but then when we issued the request, we would fail
to parse the header, and end up with all attributes being null.

We now don't parse the revalidation attributes at all. Whatever we
receive in the Last-Modified response header is what we will send in the
If-Modified-Since request header, verbatim. For better or worse, this is
how other browsers behave. So if the server sends us an invalid date
string, it can receive its own date format for revalidation.
This commit is contained in:
Timothy Flynn
2026-02-10 08:00:23 -05:00
committed by Tim Flynn
parent 21c827e8af
commit d97a3d9b5a
Notes: github-actions[bot] 2026-02-10 14:11:20 +00:00
4 changed files with 32 additions and 6 deletions

View File

@@ -527,6 +527,33 @@
// with an invalid revalidation attribute results in the cache being refreshed.
await (async () => {
url = await createRequest("/cache-test/expired-and-refreshed-due-to-invalid-revalidation-attributes", {
headers: {
Age: "2",
"Cache-Control": "max-age=5,must-revalidate",
"Last-Modified": new Date().toUTCString().replace("GMT", "+0000"),
},
});
response = await cacheFetch(url);
expectCacheStatus(url, response, "written-to-cache");
response = await cacheFetch(url);
expectCacheStatus(url, response, "read-from-cache");
// By not attaching a TEST_CACHE_RESPOND_WITH_NOT_MODIFIED header, we tell http-test-server to respond to
// revalidation requests with an HTTP 200 (i.e. revalidation fails).
response = await cacheFetch(url, {
headers: {
[TEST_CACHE_REQUEST_TIME_OFFSET]: "5",
},
});
expectCacheStatus(url, response, "written-to-cache");
})();
// Expired responses are cached until their max-age directive is reached. A must-revalidate cache directive
// with an unsuccessful revalidation results in the cache being refreshed.
await (async () => {
url = await createRequest("/cache-test/expired-and-refreshed-due-to-unsuccessful-revalidation", {
headers: {
Age: "2",
"Cache-Control": "max-age=5,must-revalidate",