As we all know, sending a response header Vary: Some-Header
causes (or should cause) caches to store different variants of the response, one for each value of Some-Header:
it encounters in requests.
However, this method has drawbacks with headers that show enormous variation, such as User-Agent:
or Accept-Language:
.
Let's say our server wants to vary based on such a very variable header, but really just serves a handful of variants. I think the followin almost works:
- The server uses all request headers to determine which variant to serve; let's assume it decides to send variant #42
- The server sends
Etag: variant42-version1
andVary: If-none-match
- The next time this user wants to access the page, it presumably adds
If-none-match: variant42-version1
and therefore tries to retrieve that from the cache - However, there is no such entry in the cache. But a fresh query from the server will cause a response with that Etag again, which will be cached for the future
- If the same user wants to access the page a third time, he will again add
If-none-match: variant42-version1
and this time be served the cached content
The problem with this is the initial case of no Etag at all. Those are the first time visitors for which the complicated evaluation which version to serve needs to be performed - but specifically for these we would still need to vary with the original headers instead of If-none-match ... a vicious circle.
Can this be made work? (Or can the desired effect of reducing cachable variants be achieved differently?)
Accept-Language:
. If I only have an English and a German version available, and a client says "I'm a natve speaker of French, quite good at Russian, understand quite a bit of German, but no English at all" the server will send the German version; thus I'd rather have this occupy only the same slot as the German version served to a client stating "I understand German and nothing else"