I'm using Apache 2.4.3 as a reverse proxy due to it's advertised compliance with RFC 2616. My app uses headers like this to enable caching at the proxy:
Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: A
Vary: X-Group
ETag: W/"foo1"
After the first request warms the cache, if my app changes to respond with this:
Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: B
Vary: X-Group
ETag: W/"foo2"
The app will respond with 304 Not Modified if the If-None-Match header from Apache matches the origin-generated ETag. However, Apache then caches the second 200 response and replaces the "foo1" record with the new response instead of caching both of the responses with different ETags. Therefore, instead of If-None-Match: W/"foo1", W/"foo2"
the next revalidate request is just If-None-Match: W/"foo2"
. So the cache is constantly getting misses instead of always getting hits.
From the RFC 2616 section 12.1:
However, an origin server is not limited to these dimensions and MAY vary the response based on any aspect of the request, including information outside the request-header fields or within extension header fields not defined by this specification.
I've tried the following combinations for Vary:
Vary: X-Foo
Vary: *
Vary: User-Agent
I've also tried both strong and weak ETags and no matter what I cannot get Apache to cache the two responses simultaneously, it always saves over the previous one. If it can't save more than one variance of a page then ETag is useless, Last-Modified would be just as good.
From the Apache 2.4 docs:
mod_cache implements an RFC 2616 compliant HTTP content caching filter, with support for the caching of content negotiated responses containing the Vary header.
Note that it says "responses" plural. Am I mis-interpreting the HTTP spec or does Apache 2.4 just not fully support ETags after-all?