1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Shlinkio\Shlink\Rest\Middleware; |
6
|
|
|
|
7
|
|
|
use Fig\Http\Message\RequestMethodInterface; |
8
|
|
|
use Psr\Http\Message\ResponseInterface as Response; |
9
|
|
|
use Psr\Http\Message\ServerRequestInterface as Request; |
10
|
|
|
use Psr\Http\Server\MiddlewareInterface; |
11
|
|
|
use Psr\Http\Server\RequestHandlerInterface; |
12
|
|
|
|
13
|
|
|
use function array_shift; |
14
|
|
|
use function explode; |
15
|
|
|
use function Functional\contains; |
16
|
|
|
use function parse_str; |
17
|
|
|
use function Shlinkio\Shlink\Common\json_decode; |
18
|
|
|
use function trim; |
19
|
|
|
|
20
|
|
|
class BodyParserMiddleware implements MiddlewareInterface, RequestMethodInterface |
21
|
|
|
{ |
22
|
7 |
|
public function process(Request $request, RequestHandlerInterface $handler): Response |
23
|
|
|
{ |
24
|
7 |
|
$method = $request->getMethod(); |
25
|
7 |
|
$currentParams = $request->getParsedBody(); |
26
|
|
|
|
27
|
|
|
// In requests that do not allow body or if the body has already been parsed, continue to next middleware |
28
|
|
|
if ( |
29
|
7 |
|
! empty($currentParams) |
30
|
6 |
|
|| contains([ |
31
|
6 |
|
self::METHOD_GET, |
32
|
6 |
|
self::METHOD_HEAD, |
33
|
6 |
|
self::METHOD_OPTIONS, |
34
|
7 |
|
], $method) |
35
|
|
|
) { |
36
|
5 |
|
return $handler->handle($request); |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
// If the accepted content is JSON, try to parse the body from JSON |
40
|
3 |
|
$contentType = $this->getRequestContentType($request); |
41
|
3 |
|
if (contains(['application/json', 'text/json', 'application/x-json'], $contentType)) { |
42
|
2 |
|
return $handler->handle($this->parseFromJson($request)); |
43
|
|
|
} |
44
|
|
|
|
45
|
2 |
|
return $handler->handle($this->parseFromUrlEncoded($request)); |
|
|
|
|
46
|
|
|
} |
47
|
|
|
|
48
|
3 |
|
private function getRequestContentType(Request $request): string |
49
|
|
|
{ |
50
|
3 |
|
$contentType = $request->getHeaderLine('Content-type'); |
51
|
3 |
|
$contentTypes = explode(';', $contentType); |
52
|
3 |
|
return trim(array_shift($contentTypes)); |
53
|
|
|
} |
54
|
|
|
|
55
|
2 |
|
private function parseFromJson(Request $request): Request |
56
|
|
|
{ |
57
|
2 |
|
$rawBody = (string) $request->getBody(); |
58
|
2 |
|
if (empty($rawBody)) { |
59
|
|
|
return $request; |
60
|
|
|
} |
61
|
|
|
|
62
|
2 |
|
$parsedJson = json_decode($rawBody); |
63
|
2 |
|
return $request->withParsedBody($parsedJson); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* @deprecated To be removed on Shlink v3.0.0, supporting only JSON requests. |
68
|
|
|
*/ |
69
|
2 |
|
private function parseFromUrlEncoded(Request $request): Request |
70
|
|
|
{ |
71
|
2 |
|
$rawBody = (string) $request->getBody(); |
72
|
2 |
|
if (empty($rawBody)) { |
73
|
1 |
|
return $request; |
74
|
|
|
} |
75
|
|
|
|
76
|
1 |
|
$parsedBody = []; |
77
|
1 |
|
parse_str($rawBody, $parsedBody); |
78
|
|
|
|
79
|
1 |
|
return $request->withParsedBody($parsedBody); |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.