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 dbc297b

Browse filesBrowse files
committed
[FrameworkBundle][HttpFoundation] Add @Stateless annotation
1 parent f46ab58 commit dbc297b
Copy full SHA for dbc297b

File tree

7 files changed

+361
-4
lines changed
Filter options

7 files changed

+361
-4
lines changed
+54Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\EventListener;
13+
14+
use Symfony\Component\Console\ConsoleEvents;
15+
use Symfony\Component\Console\Event\ConsoleErrorEvent;
16+
use Symfony\Component\Console\Exception\CommandNotFoundException;
17+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
18+
use Symfony\Component\HttpFoundation\Session\SessionInterface;
19+
use Symfony\Component\HttpFoundation\Session\DisableableSessionProxy;
20+
use Symfony\Component\HttpKernel\Event\ControllerEvent;
21+
use Symfony\Component\HttpKernel\KernelEvents;
22+
23+
/**
24+
* Disable session if stateless mode was specified
25+
*
26+
* @author Mathias Arlaud <mathias.arlaud@gmail.com>
27+
*
28+
* @internal
29+
*/
30+
final class DisableSessionSubscriber implements EventSubscriberInterface
31+
{
32+
private $session;
33+
34+
public function __construct(SessionInterface $session)
35+
{
36+
$this->session = $session;
37+
}
38+
39+
public function onController(ControllerEvent $event): void
40+
{
41+
if ($this->session instanceof DisableableSessionProxy) {
42+
if ($event->getRequest()->attributes->get('_stateless', false)) {
43+
$this->session->disable();
44+
}
45+
}
46+
}
47+
48+
public static function getSubscribedEvents(): array
49+
{
50+
return [
51+
KernelEvents::CONTROLLER => ['onController', 2048],
52+
];
53+
}
54+
}

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
<argument type="service" id="session.flash_bag" />
1818
</service>
1919

20+
<service id="disableable_session" class="Symfony\Component\HttpFoundation\Session\DisableableSessionProxy" decorates="session">
21+
<argument type="service" id="disableable_session.inner"/>
22+
</service>
23+
2024
<service id="Symfony\Component\HttpFoundation\Session\SessionInterface" alias="session" />
2125
<service id="Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface" alias="session.storage" />
2226
<service id="SessionHandlerInterface" alias="session.handler" />
@@ -69,6 +73,11 @@
6973
</argument>
7074
</service>
7175

76+
<service id="session.disable_listener" class="Symfony\Bundle\FrameworkBundle\EventListener\DisableSessionSubscriber">
77+
<tag name="kernel.event_subscriber" />
78+
<argument type="service" id="session" />
79+
</service>
80+
7281
<!-- for BC -->
7382
<service id="session.storage.filesystem" alias="session.storage.mock_file" />
7483
</services>

‎src/Symfony/Bundle/FrameworkBundle/Routing/AnnotatedRouteControllerLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Routing/AnnotatedRouteControllerLoader.php
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Routing;
1313

14+
use Symfony\Component\HttpFoundation\Annotation\Stateless;
1415
use Symfony\Component\Routing\Loader\AnnotationClassLoader;
1516
use Symfony\Component\Routing\Route;
1617

@@ -34,6 +35,28 @@ protected function configureRoute(Route $route, \ReflectionClass $class, \Reflec
3435
} else {
3536
$route->setDefault('_controller', $class->getName().'::'.$method->getName());
3637
}
38+
39+
$this->configureStateless($route, $class, $method);
40+
}
41+
42+
/**
43+
* Configures the _stateless default parameter of a given Route instance.
44+
*/
45+
private function configureStateless(Route $route, \ReflectionClass $class, \ReflectionMethod $method): void
46+
{
47+
foreach ($this->reader->getMethodAnnotations($method) as $annotation) {
48+
if ($annotation instanceof Stateless) {
49+
$route->setDefault('_stateless', true);
50+
return;
51+
}
52+
}
53+
54+
foreach ($this->reader->getClassAnnotations($class) as $annotation) {
55+
if ($annotation instanceof Stateless) {
56+
$route->setDefault('_stateless', true);
57+
return;
58+
}
59+
}
3760
}
3861

3962
/**
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpFoundation\Annotation;
13+
14+
/**
15+
* Annotation class for @Stateless().
16+
*
17+
* @Annotation
18+
* @Target({"CLASS", "METHOD"})
19+
*
20+
* @author Mathias Arlaud <mathias.arlaud@gmail.com>
21+
*/
22+
class Stateless
23+
{
24+
}

‎src/Symfony/Component/HttpFoundation/Request.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Request.php
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
1515
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
16+
use Symfony\Component\HttpFoundation\Session\DisableableSessionProxy;
1617
use Symfony\Component\HttpFoundation\Session\SessionInterface;
1718

1819
/**
@@ -749,14 +750,14 @@ public function hasPreviousSession()
749750
* like whether the session is started or not. It is just a way to check if this Request
750751
* is associated with a Session instance.
751752
*
752-
* @return bool true when the Request contains a Session object, false otherwise
753+
* @return bool true when the Request contains an enabled Session object, false otherwise
753754
*/
754755
public function hasSession()
755756
{
756-
return null !== $this->session;
757+
return null !== $this->session && !($this->session instanceof DisableableSessionProxy && $this->session->isDisabled());
757758
}
758759

759-
public function setSession(SessionInterface $session)
760+
public function setSession(?SessionInterface $session)
760761
{
761762
$this->session = $session;
762763
}

0 commit comments

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