Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0f36710

Browse filesBrowse files
Toflarfabpot
authored andcommitted
Allow to easily ask Symfony not to set a response to private automatically
1 parent 5b27c2f commit 0f36710
Copy full SHA for 0f36710

File tree

2 files changed

+47
-6
lines changed
Filter options

2 files changed

+47
-6
lines changed

‎src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php
+21-5Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,22 @@
2020
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
2121

2222
/**
23-
* Sets the session in the request.
23+
* Sets the session onto the request on the "kernel.request" event and saves
24+
* it on the "kernel.response" event.
25+
*
26+
* In addition, if the session has been started it overrides the Cache-Control
27+
* header in such a way that all caching is disabled in that case.
28+
* If you have a scenario where caching responses with session information in
29+
* them makes sense, you can disable this behaviour by setting the header
30+
* AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER on the response.
2431
*
2532
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
2633
* @author Tobias Schultze <http://tobion.de>
2734
*/
2835
abstract class AbstractSessionListener implements EventSubscriberInterface
2936
{
37+
const NO_AUTO_CACHE_CONTROL_HEADER = 'Symfony-Session-NoAutoCacheControl';
38+
3039
protected $container;
3140

3241
public function __construct(ContainerInterface $container = null)
@@ -60,13 +69,20 @@ public function onKernelResponse(FilterResponseEvent $event)
6069
return;
6170
}
6271

72+
$response = $event->getResponse();
73+
6374
if ($session->isStarted() || ($session instanceof Session && $session->hasBeenStarted())) {
64-
$event->getResponse()
65-
->setPrivate()
66-
->setMaxAge(0)
67-
->headers->addCacheControlDirective('must-revalidate');
75+
if (!$response->headers->has(self::NO_AUTO_CACHE_CONTROL_HEADER)) {
76+
$response
77+
->setPrivate()
78+
->setMaxAge(0)
79+
->headers->addCacheControlDirective('must-revalidate');
80+
}
6881
}
6982

83+
// Always remove the internal header if present
84+
$response->headers->remove(self::NO_AUTO_CACHE_CONTROL_HEADER);
85+
7086
if ($session->isStarted()) {
7187
/*
7288
* Saves the session, in case it is still open, before sending the response/headers.

‎src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php
+26-1Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public function testSessionIsSet()
5656
$this->assertSame($session, $request->getSession());
5757
}
5858

59-
public function testResponseIsPrivate()
59+
public function testResponseIsPrivateIfSessionStarted()
6060
{
6161
$session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock();
6262
$session->expects($this->exactly(2))->method('isStarted')->willReturn(false);
@@ -74,6 +74,31 @@ public function testResponseIsPrivate()
7474
$this->assertTrue($response->headers->hasCacheControlDirective('private'));
7575
$this->assertTrue($response->headers->hasCacheControlDirective('must-revalidate'));
7676
$this->assertSame('0', $response->headers->getCacheControlDirective('max-age'));
77+
$this->assertFalse($response->headers->has(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER));
78+
}
79+
80+
public function testResponseIsStillPublicIfSessionStartedAndHeaderPresent()
81+
{
82+
$session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock();
83+
$session->expects($this->exactly(2))->method('isStarted')->willReturn(false);
84+
$session->expects($this->once())->method('hasBeenStarted')->willReturn(true);
85+
86+
$container = new Container();
87+
$container->set('initialized_session', $session);
88+
89+
$listener = new SessionListener($container);
90+
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->disableOriginalConstructor()->getMock();
91+
92+
$response = new Response();
93+
$response->setSharedMaxAge(60);
94+
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
95+
$listener->onKernelResponse(new FilterResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response));
96+
97+
$this->assertTrue($response->headers->hasCacheControlDirective('public'));
98+
$this->assertFalse($response->headers->hasCacheControlDirective('private'));
99+
$this->assertFalse($response->headers->hasCacheControlDirective('must-revalidate'));
100+
$this->assertSame('60', $response->headers->getCacheControlDirective('s-maxage'));
101+
$this->assertFalse($response->headers->has(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER));
77102
}
78103

79104
public function testUninitilizedSession()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.