The Key: header being proposed for standardization replaces and extends
the Vary header to provide more fine-grained variant selection by caches.
The attached patch adds the Key: header on Squid generated ESI responses
so that any receiving clients which support the new header are able to
use it for handling our pages. It also fixes the Vary header output in
the same situations to be properly comma-delimited.
Due to the complexity of identifying which values are actually
considered we cannot at this stage emit any Key flags to narrow down the
caching choices. That is marked as a TODO if anyone cares enough to
implement. The fact that this code had such a major Vary: bug and nobody
noticed for ~10 years indicates it is probably not worth it - although
it could also indicate that people who *are* using ESI simply did not
notice the high MISS rate it would cause.
Amos
=== modified file 'src/esi/VarState.cc'
--- src/esi/VarState.cc 2012-11-19 11:29:31 +0000
+++ src/esi/VarState.cc 2013-03-21 01:32:55 +0000
@@ -857,35 +857,43 @@
delete currentFunction;
}
-/* XXX FIXME: this should be comma delimited, no? */
void
-ESIVarState::buildVary (HttpReply *rep)
+ESIVarState::buildVary(HttpReply *rep)
{
+ /* TODO: use Key header flags.
+ * which will mean the eval() function above need to record what
+ * was scanned for in each of these replies.
+ * For now we generate it taking advantage of the flags being optional
+ * such that we can use identical Vary and key headers.
+ */
char tempstr[1024];
tempstr[0]='\0';
if (flags.language)
- strcat (tempstr, "Accept-Language ");
+ strcat(tempstr, ",Accept-Language");
if (flags.cookie)
- strcat (tempstr, "Cookie ");
+ strcat(tempstr, ",Cookie");
if (flags.host)
- strcat (tempstr, "Host ");
+ strcat(tempstr, ",Host");
if (flags.referer)
- strcat (tempstr, "Referer ");
+ strcat(tempstr, ",Referer");
if (flags.useragent)
- strcat (tempstr, "User-Agent ");
+ strcat(tempstr, ",User-Agent");
if (!tempstr[0])
return;
- String strVary (rep->header.getList (HDR_VARY));
-
+ String strVary(rep->header.getList(HDR_VARY));
if (!strVary.size() || strVary[0] != '*') {
- rep->header.putStr (HDR_VARY, tempstr);
+ rep->header.putStr(HDR_VARY, &tempstr[1]));
+ }
+
+ String strVaryKey(rep->header.getList(HDR_KEY));
+ if (!strVaryKey.size()) {
+ rep->header.putStr(HDR_KEY, &tempstr[1]);
}
}
-