diff --git a/core/modules/rest/rest.services.yml b/core/modules/rest/rest.services.yml index e7b43f3..81a281c 100644 --- a/core/modules/rest/rest.services.yml +++ b/core/modules/rest/rest.services.yml @@ -27,3 +27,8 @@ services: arguments: ['@plugin.manager.rest', '@config.factory'] tags: - { name: 'event_subscriber' } + rest.options_subscriber: + class: Drupal\rest\Routing\OptionsRequestSubscriber + arguments: ['@access_manager', '@current_user'] + tags: + - {name: event_subscriber} diff --git a/core/modules/rest/src/Routing/OptionsRequestSubscriber.php b/core/modules/rest/src/Routing/OptionsRequestSubscriber.php new file mode 100644 index 0000000..4539247 --- /dev/null +++ b/core/modules/rest/src/Routing/OptionsRequestSubscriber.php @@ -0,0 +1,101 @@ +accessManager = $access_manager; + $this->account = $account; + } + + /** + * Handles OPTIONS requests. + */ + public function onKernelRequest(GetResponseEvent $event) { + $request = $event->getRequest(); + if ($request->getMethod() == 'OPTIONS') { + $allowed_methods = implode(' ', $this->getAllowedMethods($request)); + $response = new Response(NULL, 200, array('Allow' => $allowed_methods)); + $event->setResponse($response); + } + } + + /** + * Check which methods are allowed for the current request. + */ + protected function getAllowedMethods(Request $request) { + $allow = array(); + $route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT); + if (isset($route)) { + foreach ($this->availableMethods as $method) { + $request->setMethod($method); + if ($this->accessManager->check($route, $request, $this->account)) { + $allow[] = $method; + } + } + } + return $allow; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + return array(KernelEvents::REQUEST => array(array('onKernelRequest', -10000))); + } + +} diff --git a/core/modules/rest/tests/src/Routing/OptionsRequestSubscriberTest.php b/core/modules/rest/tests/src/Routing/OptionsRequestSubscriberTest.php new file mode 100644 index 0000000..50115a9 --- /dev/null +++ b/core/modules/rest/tests/src/Routing/OptionsRequestSubscriberTest.php @@ -0,0 +1,27 @@ + 'Options request subscriber tests', + 'description' => 'Tests that OPTIONS requests work correctly.', + 'group' => 'REST', + ); + } +}