Description
The intent of the Vary
response header for CDNs it to be handled like this. To summarize,
- Lookup a key for a request, get a miss
- Get a response
- Store the response at that key, along with its
Vary
header values separately - Lookup a key for a future request, get a hit
- See the cached value has some
Vary
data, compare that to the request's headers - If it doesn't match, get a new response
- Store that response at the same key, but with different
Vary
data - Repeat. At (5), we would find multiple values for a given key and would pick one by the
Vary
data, if possible
This is not what Freckle.App.Cache
does.
What Freckle.App.Cache
does is a) base the key on the values of any headers mentioned in the request Vary
header (unlikely to even be there) and b) ignore the response Vary
header entirely. Point (b) is actually how CloudFront works. Yes, one of the biggest CDNs in the world just ignores this part of the HTTP spec!
Step (7) would require a pretty big re-working of our module, since we don't currently expect multiple CachedResponse
values at any given CacheKey
.
As a solution, I propose we:
- Remove the
Vary
request header handling (unless I'm missing something, it's unlikely to ever even be used) - Decide if we should implement Fastly's correct logic, or not
- If not, we need some way for users of this library to indicate what (if any) request headers should always factor into the cache-key.
Point (3) is how CloudFront works around it's lack of actual Vary
handling: you have to specify separately by CachePolicy any headers that, ahem, vary, such that they should be incorporated into a cache key
This is not a super impactful bug for us here, since our HTTP interactions don't involve CORS. For reasons I won't go into, mishandling Vary: Origin
can lead to CORS bugs. This is the only reason I'm aware of how this all is meant to work.
For us, correct Vary
support is most important for: Accept-Encoding
and Accept-Language
.
Mishandling Vary: Accept-Encoding
, should be OK. Most systems either always request-and-receive GZip or always request-and-receive not-GZip, making cross-caching unlikely. And even if so, we will still look at the Content-Encoding
header and do the Right Thing, regardless of what we requested.
Mishandling Vary: Accept-Language
would be bad, and is the main reason to fix this. If a cached response for Accept-Language: en
is used for a user with Accept-Language: es
, that's obviously no bueno. That said, use of Accept-Language
is not wide-spread (though it should be), compared to (e.g.) a ?lang=en
query parameter, which is handled correctly by this library.
Metadata
Assignees
Labels
Type
Projects
Status
👜 To do