I use Symfony2 in a complex web application and use HTTP caching to speed up the application.
In a scenario where there is a page of content (inside a private logged in area) which is expensive to generate and only needs to be refreshed when the underlying entity changes, I want to use the ETag header to manage caching in the manner described in the Symfony2 cookbook:
http://symfony.com/doc/current/book/http_cache.html#optimizing-your-code-with-validation
This works fine when the response is set to Public and on a public page. This is because it uses the Symfony reverse proxy (AppCache) to manage the caching.
However I don't want the response to be public (or cached by the reverse proxy).
As far as I understand HTTP Caching it's perfectly possible for the browser to privately cache the page and use ETags to communicate with my controller as to when the content needs to be refreshed. I would like it if the browser received a 304 from my application if the "If-None-Match" request header matches the ETag on the response.
But, with AppCache on (in production) when the response is marked Private (or if it is private by default because there are cookies in the request header), the fetch method in HttpCache
(Symfony 2.3) does this:
// avoid that the backend sends no content
...
$subRequest->headers->remove('if_none_match');
which basically means that by the time the isNotModified() method on the Response is run in my controller, the request->getEtags()
returns an empty array even if the If-None-Match
header was present in the request. Therefore isNotModified() is always false and my application regenerates the content every time.
My question is: why does Symfony's AppCache prevent this form of private cache validation by clearing the if-none-match header? Is there a good reason for it? Is using ETag headers with private responses not a sensible thing to want to do?
Is there a way to disable this behaviour of AppCache?