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

Open in your IDE?
  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\GetResponseEvent;
  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 since Symfony 4.3
  29.  */
  30. class FragmentListener implements EventSubscriberInterface
  31. {
  32.     private $signer;
  33.     private $fragmentPath;
  34.     /**
  35.      * @param UriSigner $signer       A UriSigner instance
  36.      * @param string    $fragmentPath The path that triggers this listener
  37.      */
  38.     public function __construct(UriSigner $signerstring $fragmentPath '/_fragment')
  39.     {
  40.         $this->signer $signer;
  41.         $this->fragmentPath $fragmentPath;
  42.     }
  43.     /**
  44.      * Fixes request attributes when the path is '/_fragment'.
  45.      *
  46.      * @throws AccessDeniedHttpException if the request does not come from a trusted IP
  47.      */
  48.     public function onKernelRequest(GetResponseEvent $event)
  49.     {
  50.         $request $event->getRequest();
  51.         if ($this->fragmentPath !== rawurldecode($request->getPathInfo())) {
  52.             return;
  53.         }
  54.         if ($request->attributes->has('_controller')) {
  55.             // Is a sub-request: no need to parse _path but it should still be removed from query parameters as below.
  56.             $request->query->remove('_path');
  57.             return;
  58.         }
  59.         if ($event->isMasterRequest()) {
  60.             $this->validateRequest($request);
  61.         }
  62.         parse_str($request->query->get('_path'''), $attributes);
  63.         $request->attributes->add($attributes);
  64.         $request->attributes->set('_route_params'array_replace($request->attributes->get('_route_params', []), $attributes));
  65.         $request->query->remove('_path');
  66.     }
  67.     protected function validateRequest(Request $request)
  68.     {
  69.         // is the Request safe?
  70.         if (!$request->isMethodSafe(false)) {
  71.             throw new AccessDeniedHttpException();
  72.         }
  73.         // is the Request signed?
  74.         // we cannot use $request->getUri() here as we want to work with the original URI (no query string reordering)
  75.         if ($this->signer->check($request->getSchemeAndHttpHost().$request->getBaseUrl().$request->getPathInfo().(null !== ($qs $request->server->get('QUERY_STRING')) ? '?'.$qs ''))) {
  76.             return;
  77.         }
  78.         throw new AccessDeniedHttpException();
  79.     }
  80.     public static function getSubscribedEvents()
  81.     {
  82.         return [
  83.             KernelEvents::REQUEST => [['onKernelRequest'48]],
  84.         ];
  85.     }
  86. }