Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[HttpKernel] Fix Apache mod_expires Session Cache-Control issue#33487
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
nicolas-grekas commentedSep 7, 2019
That's for 3.4, right? Could you please add a test case also? |
pbowyer commentedSep 7, 2019
Yes, will redo against 3.4. The code didn't apply to both versions, so it needs a separate patch for each. |
pbowyer commentedSep 7, 2019
@nicolas-grekas ✔️ Now against 3.4 ✔️ Test coverage added Had to force-push a second time to get Appveyor to rerun, as I force-pushed the first time before changing the base branch for the PR. |
fabpot commentedSep 8, 2019
Thank you@pbowyer. |
…issue (pbowyer)This PR was squashed before being merged into the 3.4 branch (closes#33487).Discussion----------[HttpKernel] Fix Apache mod_expires Session Cache-Control issue| Q | A| ------------- | ---| Branch? | 3.4 for bug fixes <!-- see below -->| Bug fix? | yes| New feature? | no <!-- please update src/**/CHANGELOG.md files -->| BC breaks? | no <!-- seehttps://symfony.com/bc -->| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->| Tests pass? | yes <!-- please add some, will be required by reviewers -->| License | MITApaches's [mod_expires](https://httpd.apache.org/docs/current/mod/mod_expires.html) is a widely used module to set HTTP caching headers. It allows you to set a default cache lifetime as well as lifetimes by mime_type.When an application server has set a `Cache-Control` header, mod_expires ignores this and sets its own, resulting in duplicate `Cache-Control` headers and conflicting information. It does this _unless_ the application server sets an `Expires` header, in which case mod_expires does nothing. This is documented on the link above:> When the `Expires` header is already part of the response generated by the server, for example when generated by a CGI script or proxied from an origin server, this module does not change or add an `Expires` or `Cache-Control` header.Symfony automatically sets a `Cache-Control` header if a session exists. This patch adds an `Expires` header to ensure it's respected by mod_expires.## Example 1With the following Apache config:```apache<IfModule mod_expires.c> ExpiresActive on ExpiresDefault "access plus 1 month"</IfModule>```The HTTP response headers are:### Without the patch```HTTP/1.1 200 OKDate: Fri, 06 Sep 2019 08:02:02 GMTServer: Apache/2.4.37 (Ubuntu)Cache-Control: max-age=0, must-revalidate, privateCache-Control: max-age=2592000Expires: Sun, 06 Oct 2019 08:02:00 GMTVary: Accept-EncodingContent-Encoding: gzipContent-Length: 13099Connection: closeContent-Type: text/html; charset=UTF-8```### With the patch```HTTP/1.1 200 OKDate: Fri, 06 Sep 2019 08:21:34 GMTServer: Apache/2.4.37 (Ubuntu)Cache-Control: max-age=0, must-revalidate, privateExpires: Fri, 06 Sep 2019 08:21:34 GMTVary: Accept-EncodingContent-Encoding: gzipContent-Length: 13098Connection: closeContent-Type: text/html; charset=UTF-8```## Example 2With the following Apache config:```apache<IfModule mod_expires.c> ExpiresActive on ExpiresDefault "access plus 1 month" ExpiresByType text/html "access plus 0 seconds"</IfModule>```### Without the patch```HTTP/1.1 200 OKDate: Fri, 06 Sep 2019 08:18:40 GMTServer: Apache/2.4.37 (Ubuntu)Cache-Control: max-age=0, must-revalidate, privateCache-Control: max-age=0Expires: Fri, 06 Sep 2019 08:18:39 GMTVary: Accept-EncodingContent-Encoding: gzipContent-Length: 13099Connection: closeContent-Type: text/html; charset=UTF-8```### With the patch```HTTP/1.1 200 OKDate: Fri, 06 Sep 2019 08:20:40 GMTServer: Apache/2.4.37 (Ubuntu)Cache-Control: max-age=0, must-revalidate, privateExpires: Fri, 06 Sep 2019 08:20:40 GMTVary: Accept-EncodingContent-Encoding: gzipContent-Length: 13100Connection: closeContent-Type: text/html; charset=UTF-8```Commits-------9e94276 [HttpKernel] Fix Apache mod_expires Session Cache-Control issue
| if ($sessioninstanceof Session ?$session->getUsageIndex() !==end($this->sessionUsageStack) :$session->isStarted()) { | ||
| $event->getResponse() | ||
| ->setExpires(new \DateTime()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Is it on purpose, that this even overrides the expires header that has been set before this line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
this is about forcing the page to be uncacheable anyway. So yes.
Uh oh!
There was an error while loading.Please reload this page.
Apaches'smod_expires is a widely used module to set HTTP caching headers. It allows you to set a default cache lifetime as well as lifetimes by mime_type.
When an application server has set a
Cache-Controlheader, mod_expires ignores this and sets its own, resulting in duplicateCache-Controlheaders and conflicting information. It does thisunless the application server sets anExpiresheader, in which case mod_expires does nothing. This is documented on the link above:Symfony automatically sets a
Cache-Controlheader if a session exists. This patch adds anExpiresheader to ensure it's respected by mod_expires.Example 1
With the following Apache config:
The HTTP response headers are:
Without the patch
With the patch
Example 2
With the following Apache config:
Without the patch
With the patch