Skip to content

Commit 2687150

Browse files
eriksencostaEriksen Costa
authored andcommitted
Change BodyListener to not throw exception for empty DELETE requests
When a DELETE is empty and don't have the Content-Type header set, do not throw the UnsupportedMediaTypeHttpException.
1 parent 047620d commit 2687150

File tree

2 files changed

+37
-20
lines changed

2 files changed

+37
-20
lines changed

EventListener/BodyListener.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,32 @@ public function setArrayNormalizer(ArrayNormalizerInterface $arrayNormalizer)
7373
public function onKernelRequest(GetResponseEvent $event)
7474
{
7575
$request = $event->getRequest();
76+
$method = $request->getMethod();
7677

7778
if (!count($request->request->all())
78-
&& in_array($request->getMethod(), array('POST', 'PUT', 'PATCH', 'DELETE'))
79+
&& in_array($method, array('POST', 'PUT', 'PATCH', 'DELETE'))
7980
) {
8081
$contentType = $request->headers->get('Content-Type');
8182

8283
$format = null === $contentType
8384
? $request->getRequestFormat()
8485
: $request->getFormat($contentType);
8586

87+
$content = $request->getContent();
88+
8689
if (!$this->decoderProvider->supports($format)) {
87-
if ($this->throwExceptionOnUnsupportedContentType) {
90+
if (
91+
$this->throwExceptionOnUnsupportedContentType &&
92+
$this->isNotAnEmptyDeleteRequestWithNoSetContentType($method, $content, $contentType)
93+
) {
8894
throw new UnsupportedMediaTypeHttpException("Request body format '$format' not supported");
8995
}
9096

9197
return;
9298
}
9399

94-
$decoder = $this->decoderProvider->getDecoder($format);
95-
$content = $request->getContent();
96-
97100
if (!empty($content)) {
101+
$decoder = $this->decoderProvider->getDecoder($format);
98102
$data = $decoder->decode($content, $format);
99103
if (is_array($data)) {
100104
if (null !== $this->arrayNormalizer) {
@@ -114,4 +118,9 @@ public function onKernelRequest(GetResponseEvent $event)
114118
}
115119
}
116120
}
121+
122+
private function isNotAnEmptyDeleteRequestWithNoSetContentType($method, $content, $contentType)
123+
{
124+
return false === ('DELETE' === $method && empty($content) && null === $contentType);
125+
}
117126
}

Tests/EventListener/BodyListenerTest.php

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ class BodyListenerTest extends \PHPUnit_Framework_TestCase
2929
* @param boolean $decode use decoder provider
3030
* @param Request $request the original request
3131
* @param string $method a http method (e.g. POST, GET, PUT, ...)
32-
* @param string $contentType the request header content type
3332
* @param array $expectedParameters the http parameters of the updated request
33+
* @param string $contentType the request header content type
3434
* @param boolean $throwExceptionOnUnsupportedContentType
3535
* @param string $expectedRequestMethod
3636
*
3737
* @dataProvider testOnKernelRequestDataProvider
3838
*/
39-
public function testOnKernelRequest($decode, Request $request, $method, $contentType, $expectedParameters, $throwExceptionOnUnsupportedContentType = false, $expectedRequestMethod = null)
39+
public function testOnKernelRequest($decode, Request $request, $method, $expectedParameters, $contentType = null, $throwExceptionOnUnsupportedContentType = false, $expectedRequestMethod = null)
4040
{
4141
if (!$expectedRequestMethod) {
4242
$expectedRequestMethod = $method;
@@ -65,7 +65,11 @@ public function testOnKernelRequest($decode, Request $request, $method, $content
6565
}
6666

6767
$request->setMethod($method);
68-
$request->headers = new HeaderBag(array('Content-Type' => $contentType));
68+
69+
if ($contentType) {
70+
$request->headers = new HeaderBag(array('Content-Type' => $contentType));
71+
}
72+
6973
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
7074
->disableOriginalConstructor()
7175
->getMock();
@@ -82,17 +86,17 @@ public function testOnKernelRequest($decode, Request $request, $method, $content
8286
public static function testOnKernelRequestDataProvider()
8387
{
8488
return array(
85-
'Empty POST request' => array(true, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'POST', 'application/json', array('foo')),
86-
'Empty PUT request' => array(true, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'PUT', 'application/json', array('foo')),
87-
'Empty PATCH request' => array(true, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'PATCH', 'application/json', array('foo')),
88-
'Empty DELETE request' => array(true, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'DELETE', 'application/json', array('foo')),
89-
'Empty GET request' => array(false, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'GET', 'application/json', array()),
90-
'POST request with parameters' => array(false, new Request(array(), array('bar'), array(), array(), array(), array(), array('foo')), 'POST', 'application/json', array('bar')),
91-
'POST request with unallowed format' => array(false, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'POST', 'application/fooformat', array()),
92-
'POST request with no Content-Type' => array(true, new Request(array(), array(), array('_format' => 'json'), array(), array(), array(), array('foo')), 'POST', null, array('foo')),
93-
'POST request with _method parameter and disabled method-override' => array(true, new Request(array(), array(), array('_format' => 'json'), array(), array(), array(), array("_method" => "PUT")), 'POST', 'application/json', array('_method' => 'PUT')),
89+
'Empty POST request' => array(true, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'POST', array('foo'), 'application/json'),
90+
'Empty PUT request' => array(true, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'PUT', array('foo'), 'application/json'),
91+
'Empty PATCH request' => array(true, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'PATCH', array('foo'), 'application/json'),
92+
'Empty DELETE request' => array(true, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'DELETE', array('foo'), 'application/json'),
93+
'Empty GET request' => array(false, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'GET', array(), 'application/json'),
94+
'POST request with parameters' => array(false, new Request(array(), array('bar'), array(), array(), array(), array(), array('foo')), 'POST', array('bar'), 'application/json'),
95+
'POST request with unallowed format' => array(false, new Request(array(), array(), array(), array(), array(), array(), array('foo')), 'POST', array(), 'application/fooformat'),
96+
'POST request with no Content-Type' => array(true, new Request(array(), array(), array('_format' => 'json'), array(), array(), array(), array('foo')), 'POST', array('foo')),
97+
'POST request with _method parameter and disabled method-override' => array(true, new Request(array(), array(), array('_format' => 'json'), array(), array(), array(), array("_method" => "PUT")), 'POST', array('_method' => 'PUT'), 'application/json'),
9498
// This test is the last one, because you can't disable the http-method-override once it's enabled
95-
'POST request with _method parameter' => array(true, new Request(array(), array(), array('_format' => 'json'), array(), array(), array(), array("_method" => "PUT")), 'POST', 'application/json', array('_method' => 'PUT'), false, "PUT"),
99+
'POST request with _method parameter' => array(true, new Request(array(), array(), array('_format' => 'json'), array(), array(), array(), array("_method" => "PUT")), 'POST', array('_method' => 'PUT'), 'application/json', false, "PUT"),
96100
);
97101
}
98102

@@ -193,7 +197,7 @@ public function testOnKernelRequestNormalizationException()
193197
public function testBadRequestExceptionOnMalformedContent()
194198
{
195199
$this->setExpectedException('\Symfony\Component\HttpKernel\Exception\BadRequestHttpException');
196-
$this->testOnKernelRequest(true, new Request(array(), array(), array(), array(), array(), array(), 'foo'), 'POST', 'application/json', array());
200+
$this->testOnKernelRequest(true, new Request(array(), array(), array(), array(), array(), array(), 'foo'), 'POST', array(), 'application/json');
197201
}
198202

199203
/**
@@ -202,7 +206,11 @@ public function testBadRequestExceptionOnMalformedContent()
202206
public function testUnsupportedMediaTypeHttpExceptionOnUnsupportedMediaType()
203207
{
204208
$this->setExpectedException('\Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException');
205-
$this->testOnKernelRequest(false, new Request(array(), array(), array(), array(), array(), array(), 'foo'), 'POST', 'application/foo', array(), true);
209+
$this->testOnKernelRequest(false, new Request(array(), array(), array(), array(), array(), array(), 'foo'), 'POST', array(), 'application/foo', true);
206210
}
207211

212+
public function testShouldNotThrowUnsupportedMediaTypeHttpExceptionWhenIsAnEmptyDeleteRequest()
213+
{
214+
$this->testOnKernelRequest(false, new Request(), 'DELETE', array(), null, true);
215+
}
208216
}

0 commit comments

Comments
 (0)