Skip to content

Commit be9fc75

Browse files
Fix session cookie handling in cli context
1 parent 53d9b10 commit be9fc75

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Psr\Container\ContainerInterface;
1515
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16+
use Symfony\Component\HttpFoundation\Cookie;
1617
use Symfony\Component\HttpFoundation\Session\Session;
1718
use Symfony\Component\HttpFoundation\Session\SessionInterface;
1819
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
@@ -115,6 +116,34 @@ public function onKernelResponse(FilterResponseEvent $event)
115116
* it is saved will just restart it.
116117
*/
117118
$session->save();
119+
120+
/*
121+
* Write cookie to request object for cli context based runner like roadrunner,
122+
* where php can not write the cookie.
123+
*/
124+
if (\PHP_SAPI === 'cli') {
125+
$cookieParams = session_get_cookie_params();
126+
127+
$expire = 0;
128+
$lifetime = $cookieParams['lifetime'] ?? null;
129+
if ($lifetime) {
130+
$expire = time() + $lifetime;
131+
}
132+
133+
$response->headers->setCookie(
134+
Cookie::create(
135+
$session->getName(),
136+
$session->getId(),
137+
$expire,
138+
$cookieParams['path'] ?? '/',
139+
$cookieParams['domain'] ?? null,
140+
$cookieParams['secure'] ?? null,
141+
$cookieParams['httponly'] ?? true,
142+
false,
143+
$cookieParams['samesite'] ?? Cookie::SAMESITE_LAX
144+
)
145+
);
146+
}
118147
}
119148
}
120149

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,32 @@ public function testResponseIsStillPublicIfSessionStartedAndHeaderPresent()
120120
$this->assertFalse($response->headers->has(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER));
121121
}
122122

123+
public function testSessionSaveAndResponseHasSessionCookie()
124+
{
125+
$session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock();
126+
$session->expects($this->exactly(2))->method('getUsageIndex')->will($this->onConsecutiveCalls(0, 1));
127+
$session->expects($this->exactly(1))->method('getId')->willReturn('123456');
128+
$session->expects($this->exactly(1))->method('getName')->willReturn('PHPSESSID');
129+
$session->expects($this->exactly(1))->method('save');
130+
$session->expects($this->exactly(1))->method('isStarted')->willReturn(true);
131+
132+
$container = new Container();
133+
$container->set('initialized_session', $session);
134+
135+
$listener = new SessionListener($container);
136+
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->disableOriginalConstructor()->getMock();
137+
138+
$request = new Request();
139+
$listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
140+
141+
$response = new Response();
142+
$listener->onKernelResponse(new ResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response));
143+
144+
$cookies = $response->headers->getCookies();
145+
$this->assertSame('PHPSESSID', $cookies[0]->getName());
146+
$this->assertSame('123456', $cookies[0]->getValue());
147+
}
148+
123149
public function testUninitializedSession()
124150
{
125151
$kernel = $this->createMock(HttpKernelInterface::class);

0 commit comments

Comments
 (0)