From b913e4010f9682220ca910cbc6d39637944cc06a Mon Sep 17 00:00:00 2001 From: Jelmer Schreuder Date: Fri, 21 Apr 2017 23:44:02 +0200 Subject: [PATCH] Breaking change: allowed more complex content-types to validate as JSON by doing the matching using regex. --- .../JsonRequestParserMiddlewareSpec.php | 21 ++++++++++++++++++- .../JsonRequestParserMiddleware.php | 16 +++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/spec/ServerMiddleware/JsonRequestParserMiddlewareSpec.php b/spec/ServerMiddleware/JsonRequestParserMiddlewareSpec.php index c09790a..3137b11 100644 --- a/spec/ServerMiddleware/JsonRequestParserMiddlewareSpec.php +++ b/spec/ServerMiddleware/JsonRequestParserMiddlewareSpec.php @@ -35,6 +35,25 @@ public function it_can_parse_json( $this->process($request1, $delegate)->shouldReturn($response); } + public function it_can_parse_json_with_charset( + ServerRequestInterface $request1, + ServerRequestInterface $request2, + StreamInterface $body, + DelegateInterface $delegate, + ResponseInterface $response + ) + { + $array = ['test' => 42, 'next' => 'best']; + $body->getContents()->willReturn(json_encode($array)); + $request1->getBody()->willReturn($body); + $request1->getHeaderLine('Content-Type')->willReturn('application/json;charset=utf-8'); + $request1->withParsedBody($array)->willReturn($request2); + + $delegate->process($request2)->willReturn($response); + + $this->process($request1, $delegate)->shouldReturn($response); + } + public function it_can_parse_non_default_json_content_types( ServerRequestInterface $request1, ServerRequestInterface $request2, @@ -43,7 +62,7 @@ public function it_can_parse_non_default_json_content_types( ResponseInterface $response ) { - $this->beConstructedWith(['application/vnd.api+json', 'application/json']); + $this->beConstructedWith(['#^application\/vnd\.api\+json(;|$)#iD', '#^application\/json(;|$)#iD']); $array = ['test' => 42, 'next' => 'best']; $body->getContents()->willReturn(json_encode($array)); diff --git a/src/ServerMiddleware/JsonRequestParserMiddleware.php b/src/ServerMiddleware/JsonRequestParserMiddleware.php index 5791b1c..5b27fa2 100644 --- a/src/ServerMiddleware/JsonRequestParserMiddleware.php +++ b/src/ServerMiddleware/JsonRequestParserMiddleware.php @@ -9,25 +9,35 @@ final class JsonRequestParserMiddleware implements MiddlewareInterface { - /** @var string[] */ + /** @var string[] array of regexes to check against content-types */ private $jsonContentTypes; public function __construct(array $jsonContentTypes = null) { if (is_null($jsonContentTypes)) { - $jsonContentTypes = ['application/json']; + $jsonContentTypes = ['#^application\/json(;|$)#iD']; } $this->jsonContentTypes = $jsonContentTypes; } public function process(ServerRequestInterface $request, DelegateInterface $delegate): ResponseInterface { - if (in_array($request->getHeaderLine('Content-Type'), $this->jsonContentTypes, true)) { + if ($this->isJsonRequest($request->getHeaderLine('Content-Type'))) { $request = $request->withParsedBody($this->parseBody($request)); } return $delegate->process($request); } + private function isJsonRequest(?string $requestContentType) + { + foreach ($this->jsonContentTypes as $jsonContentType) { + if (preg_match($jsonContentType, $requestContentType) > 0) { + return true; + } + } + return false; + } + private function parseBody(ServerRequestInterface $request) : array { $parsedBody = json_decode($request->getBody()->getContents(), true);