diff --git a/src/http/Request.php b/src/http/Request.php index d7a7f3e..1cce91a 100644 --- a/src/http/Request.php +++ b/src/http/Request.php @@ -7,7 +7,7 @@ use Psr\Http\Message\{ServerRequestInterface, UploadedFileInterface}; use Yii; use yii\base\InvalidConfigException; -use yii\web\{CookieCollection, HeaderCollection, NotFoundHttpException}; +use yii\web\{CookieCollection, HeaderCollection, NotFoundHttpException, RequestParserInterface}; use yii2\extensions\psrbridge\adapter\ServerRequestAdapter; use yii2\extensions\psrbridge\exception\Message; @@ -768,7 +768,7 @@ public function resolve(): array return parent::resolve(); } - /** + /** * Sets and bridges a PSR-7 ServerRequestInterface instance for the current request. * * Wraps the provided PSR-7 {@see ServerRequestInterface} in a {@see ServerRequestAdapter} to enable full PSR-7 @@ -789,10 +789,37 @@ public function resolve(): array */ public function setPsr7Request(ServerRequestInterface $request): void { + $rawContentType = $request->getHeaderLine('Content-Type'); + if (($pos = strpos((string)$rawContentType, ';')) !== false) { + // e.g. text/html; charset=UTF-8 + $contentType = substr($rawContentType, 0, $pos); + } else { + $contentType = $rawContentType; + } + + $parsedParams = null; + + if (isset($this->parsers[$contentType])) { + $parser = Yii::createObject($this->parsers[$contentType]); + if (!($parser instanceof RequestParserInterface)) { + throw new InvalidConfigException("The '$contentType' request parser is invalid. It must implement the yii\\web\\RequestParserInterface."); + } + $parsedParams = $parser->parse((string)$request->getBody(), $rawContentType); + } elseif (isset($this->parsers['*'])) { + $parser = Yii::createObject($this->parsers['*']); + if (!($parser instanceof RequestParserInterface)) { + throw new InvalidConfigException('The fallback request parser is invalid. It must implement the yii\\web\\RequestParserInterface.'); + } + $parsedParams = $parser->parse((string)$request->getBody(), $rawContentType); + } + + if ($parsedParams !== null) { + $request = $request->withParsedBody($parsedParams); + } + $this->adapter = new ServerRequestAdapter( - $request->withHeader('statelessAppStartTime', (string) microtime(true)), + $request->withHeader('statelessAppStartTime', (string) microtime(true)) ); - UploadedFile::setPsr7Adapter($this->adapter); }