OptionsRequestSubscriber.php 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. <?php
  2. namespace Drupal\Core\EventSubscriber;
  3. use Symfony\Cmf\Component\Routing\RouteProviderInterface;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\HttpFoundation\Response;
  6. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  7. use Symfony\Component\HttpKernel\KernelEvents;
  8. use Symfony\Component\Routing\Route;
  9. /**
  10. * Handles options requests.
  11. *
  12. * Therefore it sends a options response using all methods on all possible
  13. * routes.
  14. */
  15. class OptionsRequestSubscriber implements EventSubscriberInterface {
  16. /**
  17. * The route provider.
  18. *
  19. * @var \Symfony\Cmf\Component\Routing\RouteProviderInterface
  20. */
  21. protected $routeProvider;
  22. /**
  23. * Creates a new OptionsRequestSubscriber instance.
  24. *
  25. * @param \Symfony\Cmf\Component\Routing\RouteProviderInterface $route_provider
  26. * The route provider.
  27. */
  28. public function __construct(RouteProviderInterface $route_provider) {
  29. $this->routeProvider = $route_provider;
  30. }
  31. /**
  32. * Tries to handle the options request.
  33. *
  34. * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
  35. * The request event.
  36. */
  37. public function onRequest(GetResponseEvent $event) {
  38. if ($event->getRequest()->isMethod('OPTIONS')) {
  39. $routes = $this->routeProvider->getRouteCollectionForRequest($event->getRequest());
  40. // In case we don't have any routes, a 403 should be thrown by the normal
  41. // request handling.
  42. if (count($routes) > 0) {
  43. // Flatten and unique the available methods.
  44. $methods = array_reduce($routes->all(), function ($methods, Route $route) {
  45. return array_merge($methods, $route->getMethods());
  46. }, []);
  47. $methods = array_unique($methods);
  48. $response = new Response('', 200, ['Allow' => implode(', ', $methods)]);
  49. $event->setResponse($response);
  50. }
  51. }
  52. }
  53. /**
  54. * {@inheritdoc}
  55. */
  56. public static function getSubscribedEvents() {
  57. // Set a high priority so it is executed before routing.
  58. $events[KernelEvents::REQUEST][] = ['onRequest', 1000];
  59. return $events;
  60. }
  61. }