feature #35635 [HttpKernel] Make ErrorListener unaware of the event dispatcher (derrabus)
This PR was merged into the 5.1-dev branch.
Discussion
----------
[HttpKernel] Make ErrorListener unaware of the event dispatcher
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | N/A
| License | MIT
| Doc PR | N/A
Under certain circumstances, HttpKernel's `ErrorListener` class might dynamically register and unregister a listener with the dispatcher. If our goal is to make the dispatcher immutable, that specific behavior would be in our way. Also, #34988 would break this workflow.
This PR provides an alternative. The listener is always registered, but I'm using the request to piggyback a flag that activates/deactivates the listener.
Commits
-------
a9d1dede44
[HttpKernel] Make ErrorListener unaware of the event dispatcher.
This commit is contained in:
commit
4253251278
@ -14,11 +14,11 @@ namespace Symfony\Component\HttpKernel\EventListener;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Debug\Exception\FlattenException as LegacyFlattenException;
|
||||
use Symfony\Component\ErrorHandler\Exception\FlattenException;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
|
||||
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
|
||||
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
@ -33,7 +33,7 @@ class ErrorListener implements EventSubscriberInterface
|
||||
protected $logger;
|
||||
protected $debug;
|
||||
|
||||
public function __construct($controller, LoggerInterface $logger = null, $debug = false)
|
||||
public function __construct($controller, LoggerInterface $logger = null, bool $debug = false)
|
||||
{
|
||||
$this->controller = $controller;
|
||||
$this->logger = $logger;
|
||||
@ -47,7 +47,7 @@ class ErrorListener implements EventSubscriberInterface
|
||||
$this->logException($event->getThrowable(), sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()));
|
||||
}
|
||||
|
||||
public function onKernelException(ExceptionEvent $event, string $eventName = null, EventDispatcherInterface $eventDispatcher = null)
|
||||
public function onKernelException(ExceptionEvent $event)
|
||||
{
|
||||
if (null === $this->controller) {
|
||||
return;
|
||||
@ -79,12 +79,15 @@ class ErrorListener implements EventSubscriberInterface
|
||||
|
||||
$event->setResponse($response);
|
||||
|
||||
if ($this->debug && $eventDispatcher instanceof EventDispatcherInterface) {
|
||||
$cspRemovalListener = function ($event) use (&$cspRemovalListener, $eventDispatcher) {
|
||||
$event->getResponse()->headers->remove('Content-Security-Policy');
|
||||
$eventDispatcher->removeListener(KernelEvents::RESPONSE, $cspRemovalListener);
|
||||
};
|
||||
$eventDispatcher->addListener(KernelEvents::RESPONSE, $cspRemovalListener, -128);
|
||||
if ($this->debug) {
|
||||
$event->getRequest()->attributes->set('_remove_csp_headers', true);
|
||||
}
|
||||
}
|
||||
|
||||
public function removeCspHeader(ResponseEvent $event): void
|
||||
{
|
||||
if ($this->debug && $event->getRequest()->attributes->get('_remove_csp_headers', false)) {
|
||||
$event->getResponse()->headers->remove('Content-Security-Policy');
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,6 +117,7 @@ class ErrorListener implements EventSubscriberInterface
|
||||
['logKernelException', 0],
|
||||
['onKernelException', -128],
|
||||
],
|
||||
KernelEvents::RESPONSE => ['removeCspHeader', -128],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,6 @@ class ErrorListenerTest extends TestCase
|
||||
$dispatcher->dispatch($event, KernelEvents::RESPONSE);
|
||||
|
||||
$this->assertFalse($response->headers->has('content-security-policy'), 'CSP header has been removed');
|
||||
$this->assertFalse($dispatcher->hasListeners(KernelEvents::RESPONSE), 'CSP removal listener has been removed');
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user