vendor/symfony/http-kernel/EventListener/FragmentListener.php line 53

  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\HttpKernel\EventListener;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpKernel\Event\RequestEvent;
  14. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  15. use Symfony\Component\HttpKernel\KernelEvents;
  16. use Symfony\Component\HttpKernel\UriSigner;
  17. /**
  18.  * Handles content fragments represented by special URIs.
  19.  *
  20.  * All URL paths starting with /_fragment are handled as
  21.  * content fragments by this listener.
  22.  *
  23.  * Throws an AccessDeniedHttpException exception if the request
  24.  * is not signed or if it is not an internal sub-request.
  25.  *
  26.  * @author Fabien Potencier <fabien@symfony.com>
  27.  *
  28.  * @final
  29.  */
  30. class FragmentListener implements EventSubscriberInterface
  31. {
  32.     private UriSigner $signer;
  33.     private string $fragmentPath;
  34.     /**
  35.      * @param string $fragmentPath The path that triggers this listener
  36.      */
  37.     public function __construct(UriSigner $signerstring $fragmentPath '/_fragment')
  38.     {
  39.         $this->signer $signer;
  40.         $this->fragmentPath $fragmentPath;
  41.     }
  42.     /**
  43.      * Fixes request attributes when the path is '/_fragment'.
  44.      *
  45.      * @throws AccessDeniedHttpException if the request does not come from a trusted IP
  46.      */
  47.     public function onKernelRequest(RequestEvent $event)
  48.     {
  49.         $request $event->getRequest();
  50.         if ($this->fragmentPath !== rawurldecode($request->getPathInfo())) {
  51.             return;
  52.         }
  53.         if ($request->attributes->has('_controller')) {
  54.             // Is a sub-request: no need to parse _path but it should still be removed from query parameters as below.
  55.             $request->query->remove('_path');
  56.             return;
  57.         }
  58.         if ($event->isMainRequest()) {
  59.             $this->validateRequest($request);
  60.         }
  61.         parse_str($request->query->get('_path'''), $attributes);
  62.         $request->attributes->add($attributes);
  63.         $request->attributes->set('_route_params'array_replace($request->attributes->get('_route_params', []), $attributes));
  64.         $request->query->remove('_path');
  65.     }
  66.     protected function validateRequest(Request $request)
  67.     {
  68.         // is the Request safe?
  69.         if (!$request->isMethodSafe()) {
  70.             throw new AccessDeniedHttpException();
  71.         }
  72.         // is the Request signed?
  73.         if ($this->signer->checkRequest($request)) {
  74.             return;
  75.         }
  76.         throw new AccessDeniedHttpException();
  77.     }
  78.     public static function getSubscribedEvents(): array
  79.     {
  80.         return [
  81.             KernelEvents::REQUEST => [['onKernelRequest'48]],
  82.         ];
  83.     }
  84. }