From 04f1dcfad414c24eaba8a949c32c3247b9282368 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Thu, 4 May 2023 11:28:18 +0100 Subject: [PATCH] Issue #3093973 by robindh, Diego_Mow, smustgrave, Grayle: Allow DELETE requests to return a response body (cherry picked from commit a5b62885f581de61effd1de1175208f668c5308b) --- .../ResourceResponseSubscriber.php | 5 ++--- .../rest/src/Routing/ResourceRoutes.php | 2 +- .../ResourceResponseSubscriberTest.php | 22 +++++++++---------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php b/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php index 02330d2c636a..d01fcbfa30e8 100644 --- a/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php +++ b/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php @@ -122,7 +122,7 @@ public function getResponseFormat(RouteMatchInterface $route_match, Request $req return $acceptable_formats[0]; } - // Sometimes, there are no acceptable formats, e.g. DELETE routes. + // Sometimes, there are no acceptable formats. return NULL; } @@ -141,8 +141,7 @@ public function getResponseFormat(RouteMatchInterface $route_match, Request $req * @param \Symfony\Component\Serializer\SerializerInterface $serializer * The serializer to use. * @param string|null $format - * The response format, or NULL in case the response does not need a format, - * for example for the response to a DELETE request. + * The response format, or NULL in case the response does not need a format. * * @todo Add test coverage for language negotiation contexts in * https://www.drupal.org/node/2135829. diff --git a/core/modules/rest/src/Routing/ResourceRoutes.php b/core/modules/rest/src/Routing/ResourceRoutes.php index f4628130f81c..a3cfe746057d 100644 --- a/core/modules/rest/src/Routing/ResourceRoutes.php +++ b/core/modules/rest/src/Routing/ResourceRoutes.php @@ -116,7 +116,7 @@ protected function getRoutesForResourceConfig(RestResourceConfigInterface $rest_ // - set the allowed request body content types/formats for methods that // allow request bodies to be sent (unless hardcoded by the plugin) // - set the allowed authentication providers - if (in_array($method, ['GET', 'HEAD', 'POST', 'PUT', 'PATCH'], TRUE) && !$route->hasRequirement('_format')) { + if (in_array($method, ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'], TRUE) && !$route->hasRequirement('_format')) { $route->addRequirements(['_format' => implode('|', $rest_resource_config->getFormats($method))]); } if (in_array($method, ['POST', 'PATCH', 'PUT'], TRUE) && !$route->hasRequirement('_content_type_format')) { diff --git a/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php b/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php index 44f5d55dc4a4..3efc3f021ab8 100644 --- a/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php +++ b/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php @@ -136,7 +136,7 @@ public function testOnResponseWithCacheableResponse($methods, array $supported_r $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => $this->randomMachineName()], $route_requirements)); // The RequestHandler must return a ResourceResponseInterface object. - $handler_response = new ResourceResponse($method !== 'DELETE' ? ['REST' => 'Drupal'] : NULL); + $handler_response = new ResourceResponse(['REST' => 'Drupal']); $this->assertInstanceOf(ResourceResponseInterface::class, $handler_response); $this->assertInstanceOf(CacheableResponseInterface::class, $handler_response); @@ -186,7 +186,7 @@ public function testOnResponseWithUncacheableResponse($methods, array $supported $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => $this->randomMachineName()], $route_requirements)); // The RequestHandler must return a ResourceResponseInterface object. - $handler_response = new ModifiedResourceResponse($method !== 'DELETE' ? ['REST' => 'Drupal'] : NULL); + $handler_response = new ModifiedResourceResponse(['REST' => 'Drupal']); $this->assertInstanceOf(ResourceResponseInterface::class, $handler_response); $this->assertNotInstanceOf(CacheableResponseInterface::class, $handler_response); @@ -344,7 +344,7 @@ public function providerTestResponseFormat() { ]; $unsafe_method_bodyless_test_cases = [ - 'unsafe methods without response bodies (DELETE): client requested no format, response should have no format' => [ + 'unsafe methods without request bodies (DELETE): client requested no format, response should have the first acceptable format' => [ ['DELETE'], ['xml', 'json'], ['xml', 'json'], @@ -352,10 +352,10 @@ public function providerTestResponseFormat() { ['Content-Type' => 'application/json'], NULL, 'xml', - NULL, - '', + 'text/xml', + $xml_encoded, ], - 'unsafe methods without response bodies (DELETE): client requested format (XML), response should have no format' => [ + 'unsafe methods without request bodies (DELETE): client requested format (XML), response should have xml format' => [ ['DELETE'], ['xml', 'json'], ['xml', 'json'], @@ -363,10 +363,10 @@ public function providerTestResponseFormat() { ['Content-Type' => 'application/json'], NULL, 'xml', - NULL, - '', + 'text/xml', + $xml_encoded, ], - 'unsafe methods without response bodies (DELETE): client requested format (JSON), response should have no format' => [ + 'unsafe methods without request bodies (DELETE): client requested format (JSON), response should have json format' => [ ['DELETE'], ['xml', 'json'], ['xml', 'json'], @@ -374,8 +374,8 @@ public function providerTestResponseFormat() { ['Content-Type' => 'application/json'], NULL, 'json', - NULL, - '', + 'application/json', + $json_encoded, ], ]; -- GitLab