diff --git a/features/handle_payload.feature b/features/handle_payload.feature index 603062e..bd57a93 100644 --- a/features/handle_payload.feature +++ b/features/handle_payload.feature @@ -34,7 +34,8 @@ Feature: Handle json payload "name": "Bond" } """ - Then the JSON node "name" should not exist + Then the response status code should be 415 + And the JSON node "name" should not exist Scenario: Send invalid data Given I set "Content-Type" header equal to "application/json" diff --git a/src/JsonBodyListener.php b/src/JsonBodyListener.php index 96deb34..e2abd3e 100644 --- a/src/JsonBodyListener.php +++ b/src/JsonBodyListener.php @@ -2,12 +2,14 @@ namespace Rezzza\SymfonyRestApiJson; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException; /** - * Allow to pass JSON raw as request content + * Allow to pass JSON raw as request content. */ class JsonBodyListener { @@ -31,6 +33,10 @@ public function onKernelRequest(GetResponseEvent $event) : $request->getFormat($contentType); if ($format !== 'json') { + if ($this->requestFormatViolateSupportedFormats($format, $request->attributes->get('_supportedFormats', false))) { + throw new UnsupportedMediaTypeHttpException("Request body format '$format' not supported"); + } + return; } @@ -41,7 +47,7 @@ public function onKernelRequest(GetResponseEvent $event) $data = @json_decode($content, true); if (!is_array($data)) { - throw new BadRequestHttpException('Invalid ' . $format . ' message received'); + throw new BadRequestHttpException('Invalid '.$format.' message received'); } $jsonSchema = $request->get('_jsonSchema'); @@ -51,4 +57,12 @@ public function onKernelRequest(GetResponseEvent $event) $request->request = new ParameterBag($data); } + + private function requestFormatViolateSupportedFormats($format, $supportedFormats) + { + return null !== $format + && false !== $supportedFormats + && false === in_array($format, $supportedFormats, true) + ; + } } diff --git a/testapp/index.php b/testapp/index.php index 3bc82de..263c94f 100644 --- a/testapp/index.php +++ b/testapp/index.php @@ -18,7 +18,7 @@ class AppKernel extends Kernel public function registerBundles() { return [ - new Symfony\Bundle\FrameworkBundle\FrameworkBundle() + new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), ]; } @@ -33,7 +33,10 @@ protected function configureRoutes(RouteCollectionBuilder $routes) { // kernel is a service that points to this class // optional 3rd argument is the route name - $routes->add('/echo', 'kernel:echoAction')->setDefault('_jsonSchema', ['request' => 'schema.json']); + $routes->add('/echo', 'kernel:echoAction') + ->setDefault('_jsonSchema', ['request' => 'schema.json']) + ->setDefault('_supportedFormats', ['json']) + ; $routes->add('/exception', 'kernel:exceptionAction'); }