-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Multiple Cache-Control headers sent in 4.0.0-BETA4 #24988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
From the PHP documentation perspective, it looks like you are correct. One for @nicolas-grekas, I don't get why we've made this change in Symfony 🤔 |
Actually, all you have to do, is to set the Symfony session storage |
It's true that multiple Cache-Control headers are sent. Yet this is allowed by the HTTP spec so not a bug in itself. |
The issue is, why is this setting set to '0' and not ''? # config/packages/framework.yaml
parameters:
session.storage.options:
cache_limiter: 0 |
it's been always documented like that (this is a Symfony setting, not a PHP one, so we can derivate a bit from the PHP doc actually.) |
Yes it fixes it, but it looks more like a workaround to a strange default behavior. |
OK, nice. |
@xabbuh can this be documented somehow? yesterday I've spent 3 hours to find how to set the documenting this config as example... # config/packages/framework.yaml
parameters:
session.storage.options:
cache_limiter: 0 |
@goetas Would you mind opening an issue in the docs repo (best search before if we already have one)? |
Note that the doc should be clear that this is not recommended, as this will generate corrupted http caches. |
@nicolas-grekas yes I'm aware of it, I was using in mu particular case |
I think there are serious implications here. I too spent 2 hours figuring out why Chrome and Safari are not respecting my Cache-Control settings. In my Response I set the following to avoid 304 Not Modified requests/responses because I am serving a file which is never going to change in the future:
However both Chrome and Safari kept on sending requests. After inspecting the headers I noticed two Cache-Control headers:
The first header is sent by Symfony, the second one because of my Response. But it seems the browsers do not discard the After manually commenting out the Symfony header it all worked out fine. If I change Any ideas? |
See #25448, it contains everything on the topic. |
Thanks for pointing me to that issue. You say there:
This is want I want BUT only for this specific Response (otherwise browsers will not cache to response as intended). For all other responses the current Symfony default ( How to accomplish that? |
Not sure you can. |
I also had the same need, it was per url/path (serving cacheable images only to authorized users was the case...)
The cache was in-browser |
Same here, only authorized users may access the static media files which is not an uncommon scenario. Since upgrading Symfony 3.3 to 3.4 our number of requests has increased by 60% due to this. A nice solution would be to set these headers in the Response class by default instead of using the A workaround for me could be to use Any thoughts on this? |
I found a work-around for my use case. I added
before returning the response, which overwrites the Symfony I really believe Symfony should avoid using the |
I'm sorry but I still fail to understand. As soon as a resource is public, it can be served directly to next users, bypassing any authentication. |
The session is needed because these static media files may only be served to authenticated users.
The real issue is that the default This is the Symfony header:
Both |
This makes no sense to me. As soon as a resource is served by a reverse proxy- which "public" allows, it cannot be authenticated anymore using the session. How do you resolve that? |
So I change Then my original point still stands: 304's can't be avoided by the default Symfony Do you understand my issue here? |
I understand your issue, but I'm challenging it's reality. We just agreed that private is correct and public is buggy. |
I can't ensure that so it can be reused even if the user is logged out. This is no different than the
Do you agree it would be more flexible and Symfony-like to set these headers on the Response object instead of using the |
@nicolas-grekas as explained here, this is one of many thickets dealing with a similar issue... Using the |
@goetas you're right, that's how it should be. That's not how it works today, so PR welcome. I'm not in a hurry to fix this myself, especially as it looks like getting correct CC headers is hard/easy to get wrong (see above.) By providing full flexibility, a new solution should also provide guidance to correct semantic. |
@nicolas-grekas Great to hear! Was interested to know what is the general direction! |
Why does framework:
session:
gc_maxlifetime: 7200
save_path: '%kernel.root_dir%/var/session/'
name: 'sid'
cache_limiter: 0 |
Although I agree with @nicolas-grekas that if you start a session a response should be considered to be private, the implementation like it is now is inconsistent. I think we must always suppress the To fix this properly, imho we should do the following:
This would result in a consistent behaviour no matter what session storage or reverse proxy you use. |
…g raw header() when session is started (Toflar) This PR was merged into the 3.4 branch. Discussion ---------- [HttpKernel] Call Response->setPrivate() instead of sending raw header() when session is started | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #24988 | License | MIT | Doc PR | - As described in #24988 I think the current handling of the `Cache-Control` header set by the `NativeSessionStorage` causes inconsistent behaviour. In #24988 @nicolas-grekas states that if you start a session a response should be considered to be private. I do agree with this but up until now, nobody takes care of this on `kernel.response`. I think we must always suppress the `NativeSessionStorage` from generating any headers by default. Otherwise the `Cache-Control` header never makes it to the `Response` instance and is thus missed by `kernel.response` listeners and for example the Symfony HttpCache. So depending on whether you use Symfony's HttpCache or Varnish as a reverse proxy, caching would be handled differently. Varnish would consider the response to be private if you set the php.ini setting `session.cache_limiter` to `nocache` (which is default) because it will receive the header. HttpCache would not because the `Cache-Control` header is not present on the `Response`. That's inconsistent and may cause confusion or problems when switching proxies. Commits ------- dbc1c1c [HttpKernel] Call Response->setPrivate() instead of sending raw header() when session is started
…g raw header() when session is started (Toflar) This PR was merged into the 3.4 branch. Discussion ---------- [HttpKernel] Call Response->setPrivate() instead of sending raw header() when session is started | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony/symfony#24988 | License | MIT | Doc PR | - As described in #24988 I think the current handling of the `Cache-Control` header set by the `NativeSessionStorage` causes inconsistent behaviour. In #24988 @nicolas-grekas states that if you start a session a response should be considered to be private. I do agree with this but up until now, nobody takes care of this on `kernel.response`. I think we must always suppress the `NativeSessionStorage` from generating any headers by default. Otherwise the `Cache-Control` header never makes it to the `Response` instance and is thus missed by `kernel.response` listeners and for example the Symfony HttpCache. So depending on whether you use Symfony's HttpCache or Varnish as a reverse proxy, caching would be handled differently. Varnish would consider the response to be private if you set the php.ini setting `session.cache_limiter` to `nocache` (which is default) because it will receive the header. HttpCache would not because the `Cache-Control` header is not present on the `Response`. That's inconsistent and may cause confusion or problems when switching proxies. Commits ------- dbc1c1c [HttpKernel] Call Response->setPrivate() instead of sending raw header() when session is started
…g raw header() when session is started (Toflar) This PR was merged into the 3.4 branch. Discussion ---------- [HttpKernel] Call Response->setPrivate() instead of sending raw header() when session is started | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony/symfony#24988 | License | MIT | Doc PR | - As described in #24988 I think the current handling of the `Cache-Control` header set by the `NativeSessionStorage` causes inconsistent behaviour. In #24988 @nicolas-grekas states that if you start a session a response should be considered to be private. I do agree with this but up until now, nobody takes care of this on `kernel.response`. I think we must always suppress the `NativeSessionStorage` from generating any headers by default. Otherwise the `Cache-Control` header never makes it to the `Response` instance and is thus missed by `kernel.response` listeners and for example the Symfony HttpCache. So depending on whether you use Symfony's HttpCache or Varnish as a reverse proxy, caching would be handled differently. Varnish would consider the response to be private if you set the php.ini setting `session.cache_limiter` to `nocache` (which is default) because it will receive the header. HttpCache would not because the `Cache-Control` header is not present on the `Response`. That's inconsistent and may cause confusion or problems when switching proxies. Commits ------- dbc1c1c4b6 [HttpKernel] Call Response->setPrivate() instead of sending raw header() when session is started
…rivate automatically (Toflar) This PR was squashed before being merged into the 4.1-dev branch (closes #26681). Discussion ---------- Allow to easily ask Symfony not to set a response to private automatically | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | This PR is related to the many discussions going on about the latest (Symfony 3.4+) changes regarding the way Symfony handles the session. I think we're almost there now, Symfony 4.1 automatically turns responses into `private` responses once the session is started and it's all done in the `AbstractSessionListener` where the session is also saved. In other issues/PRs (symfony/symfony#25583, symfony/symfony#25699, symfony/symfony#24988) it was agreed that setting the response to `private` if the session is started is a good default for Symfony. It was also agreed that setting it to `private` does not always make sense because you **can share a response** across sessions, it just requires a more complex caching setup with shared user context etc. So there must be an easy way to disable this behaviour. Right now it's very hard to do so because what you end up doing is basically decorating the `session_listener` which is very hard because you have to keep track on that over different Symfony versions as the base listener might get additional features etc. The [FOSCacheBundle](FriendsOfSymfony/FOSHttpCacheBundle#438) is already having this problem, [Contao](contao/core-bundle#1388) has the same issue and there will be probably more. Basically everyone that wants to share a response cache across the session will have to decorate the default listener. That's just too hard, so I came up with this solution. The header is easy. Every project can add that easily. It does not require any extension, configuration or adjustment of any service. It's clean, transparent and has absolutely no impact on "default" Symfony setups. Would be happy to have some feedback before 4.1 freeze. Commits ------- 0f36710 Allow to easily ask Symfony not to set a response to private automatically
…rivate automatically (Toflar) This PR was squashed before being merged into the 4.1-dev branch (closes #26681). Discussion ---------- Allow to easily ask Symfony not to set a response to private automatically | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | This PR is related to the many discussions going on about the latest (Symfony 3.4+) changes regarding the way Symfony handles the session. I think we're almost there now, Symfony 4.1 automatically turns responses into `private` responses once the session is started and it's all done in the `AbstractSessionListener` where the session is also saved. In other issues/PRs (#25583, #25699, #24988) it was agreed that setting the response to `private` if the session is started is a good default for Symfony. It was also agreed that setting it to `private` does not always make sense because you **can share a response** across sessions, it just requires a more complex caching setup with shared user context etc. So there must be an easy way to disable this behaviour. Right now it's very hard to do so because what you end up doing is basically decorating the `session_listener` which is very hard because you have to keep track on that over different Symfony versions as the base listener might get additional features etc. The [FOSCacheBundle](FriendsOfSymfony/FOSHttpCacheBundle#438) is already having this problem, [Contao](contao/core-bundle#1388) has the same issue and there will be probably more. Basically everyone that wants to share a response cache across the session will have to decorate the default listener. That's just too hard, so I came up with this solution. The header is easy. Every project can add that easily. It does not require any extension, configuration or adjustment of any service. It's clean, transparent and has absolutely no impact on "default" Symfony setups. Would be happy to have some feedback before 4.1 freeze. Commits ------- 0f36710 Allow to easily ask Symfony not to set a response to private automatically
Uh oh!
There was an error while loading. Please reload this page.
This is since this commit: cf4eb46
Because of this change the
Cache-Control
header is sent always. As far as I know thesession.cache_limiter
off state is''
and not'0'
.http://php.net/manual/en/function.session-cache-limiter.php
The text was updated successfully, but these errors were encountered: