Skip to content

Commit

Permalink
Breaking change: allowed more complex content-types to validate as JS…
Browse files Browse the repository at this point in the history
…ON by doing the matching using regex.
  • Loading branch information
Jelmer Schreuder committed Apr 21, 2017
1 parent cc96514 commit b913e40
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
21 changes: 20 additions & 1 deletion spec/ServerMiddleware/JsonRequestParserMiddlewareSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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));
Expand Down
16 changes: 13 additions & 3 deletions src/ServerMiddleware/JsonRequestParserMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit b913e40

Please sign in to comment.