Skip to content

Commit d54d33f

Browse files
committed
Custom request body parsers, spunoff from reactphp/http#220 (comment)
1 parent 6e91b09 commit d54d33f

3 files changed

Lines changed: 149 additions & 0 deletions

File tree

composer.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "wyrihaximus/custom-request-body-parsers",
3+
"require": {
4+
"php": "^7.0",
5+
"psr/http-message": "^1.0"
6+
},
7+
"autoload": {
8+
"psr-4": {
9+
"WyriHaximus\\React\\Http\\Middleware\\": "src/"
10+
}
11+
}
12+
}

composer.lock

Lines changed: 70 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/CustomRequestBodyParsers.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace WyriHaximus\React\Http\Middleware;
4+
5+
use Psr\Http\Message\ServerRequestInterface;
6+
final class CustomRequestBodyParsers
7+
{
8+
private $types = array();
9+
10+
public function __construct()
11+
{
12+
/**
13+
* Via: https://github.com/reactphp/http/pull/220#discussion_r140863176
14+
*/
15+
$this->addType('application/json', function (ServerRequestInterface $request) {
16+
$result = json_decode((string)$request->getBody(), true);
17+
if (!is_array($result)) {
18+
return null;
19+
}
20+
return $result;
21+
});
22+
23+
/**
24+
* Via: https://github.com/reactphp/http/pull/220#discussion_r140863176
25+
*/
26+
$xmlParser = function (ServerRequestInterface $request) {
27+
$backup = libxml_disable_entity_loader(true);
28+
$backup_errors = libxml_use_internal_errors(true);
29+
$result = simplexml_load_string((string)$request->getBody());
30+
libxml_disable_entity_loader($backup);
31+
libxml_clear_errors();
32+
libxml_use_internal_errors($backup_errors);
33+
if ($result === false) {
34+
return $request;
35+
}
36+
return $request->withParsedBody($result);
37+
};
38+
$this->addType('application/xml', $xmlParser);
39+
$this->addType('text/xml', $xmlParser);
40+
}
41+
42+
public function addType($type, $callback)
43+
{
44+
$this->types[$type] = $callback;
45+
}
46+
47+
public function __invoke(ServerRequestInterface $request, $next)
48+
{
49+
$type = $request->getHeaderLine('Content-Type');
50+
51+
if (!isset($this->types[$type])) {
52+
return $next($request);
53+
}
54+
55+
try {
56+
$parser = $this->types[$type];
57+
/** @var ServerRequestInterface $request */
58+
$request = $parser($request);
59+
} catch (\Exception $e) {
60+
return $next($request);
61+
} catch (\Throwable $t) {
62+
return $next($request);
63+
}
64+
65+
return $next($request);
66+
}
67+
}

0 commit comments

Comments
 (0)