Fix session called initized several time

This commit is contained in:
Jérémy Derussé 2020-10-30 21:47:32 +01:00
parent 8ef1826bee
commit 30a3c7c87b
No known key found for this signature in database
GPG Key ID: 2083FA5758C473D2
2 changed files with 36 additions and 1 deletions

View File

@ -56,7 +56,8 @@ abstract class AbstractSessionListener implements EventSubscriberInterface
$session = null;
$request = $event->getRequest();
if (!$request->hasSession()) {
$request->setSessionFactory(function () { return $this->getSession(); });
$sess = null;
$request->setSessionFactory(function () use (&$sess) { return $sess ?? $sess = $this->getSession(); });
}
$session = $session ?? ($this->container && $this->container->has('initialized_session') ? $this->container->get('initialized_session') : null);

View File

@ -20,11 +20,13 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
use Symfony\Component\HttpKernel\EventListener\SessionListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelInterface;
class SessionListenerTest extends TestCase
{
@ -178,4 +180,36 @@ class SessionListenerTest extends TestCase
$this->assertTrue($response->headers->has('Expires'));
$this->assertLessThanOrEqual((new \DateTime('now', new \DateTimeZone('UTC'))), (new \DateTime($response->headers->get('Expires'))));
}
public function testGetSessionIsCalledOnce()
{
$session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock();
$sessionStorage = $this->getMockBuilder(NativeSessionStorage::class)->getMock();
$kernel = $this->getMockBuilder(KernelInterface::class)->getMock();
$sessionStorage->expects($this->once())
->method('setOptions')
->with(['cookie_secure' => true]);
$requestStack = new RequestStack();
$requestStack->push($masterRequest = new Request([], [], [], [], [], ['HTTPS' => 'on']));
$container = new Container();
$container->set('session_storage', $sessionStorage);
$container->set('session', $session);
$container->set('request_stack', $requestStack);
$event = new GetResponseEvent($kernel, $masterRequest, HttpKernelInterface::MASTER_REQUEST);
$listener = new SessionListener($container);
$listener->onKernelRequest($event);
$subRequest = $masterRequest->duplicate();
// at this point both master and subrequest have a closure to build the session
$masterRequest->getSession();
// calling the factory on the subRequest should not trigger a second call to storage->sesOptions()
$subRequest->getSession();
}
}