From 84147bf4b1465ddad05e07bdc8bedcbb5da9b2fe Mon Sep 17 00:00:00 2001 From: Blezigen Date: Wed, 26 Nov 2025 13:31:36 +0300 Subject: [PATCH 1/3] fix(http): Enhance setPsr7Request: parse body Introduce a proper bridge between PSR-7 ServerRequestInterface and Yii Request, including request body parsing. The setPsr7Request method now: - extracts the raw Content-Type header (trimming parameters like `charset=UTF-8`); - resolves an appropriate request parser from `$this->parsers` (or the `'*'` fallback, if configured); - parses the PSR-7 request body and injects the result into `parsedBody` via `$request->withParsedBody()`; - wraps the request in `ServerRequestAdapter` while adding the `statelessAppStartTime` header for tracing/debugging; - updates the PSR-7 adapter for `UploadedFile` via `UploadedFile::setPsr7Adapter()`. This change: - aligns PSR-7-based requests with the existing Yii Request behavior regarding body parsing and UploadedFile handling; - enables stateless application startup time tracing at the PSR-7 request level; - keeps compatibility with existing Yii request parsers configured in the application. --- src/http/Request.php | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/http/Request.php b/src/http/Request.php index d7a7f3e3..402351d4 100644 --- a/src/http/Request.php +++ b/src/http/Request.php @@ -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,35 @@ public function resolve(): array */ public function setPsr7Request(ServerRequestInterface $request): void { + $rawContentType = $this->getContentType(); + if (($pos = strpos((string)$rawContentType, ';')) !== false) { + // e.g. text/html; charset=UTF-8 + $contentType = substr($rawContentType, 0, $pos); + } else { + $contentType = $rawContentType; + } + + 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((array)$parsedParams); + } + $this->adapter = new ServerRequestAdapter( - $request->withHeader('statelessAppStartTime', (string) microtime(true)), + $request->withHeader('statelessAppStartTime', (string) microtime(true)) ); - UploadedFile::setPsr7Adapter($this->adapter); } From ca94b34a055acbe61c8adef599cad80c98be9fe1 Mon Sep 17 00:00:00 2001 From: Blezigen Date: Wed, 26 Nov 2025 13:44:45 +0300 Subject: [PATCH 2/3] fix(http): fix problem from Coderabbitai --- src/http/Request.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/http/Request.php b/src/http/Request.php index 402351d4..eefec3db 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; @@ -789,7 +789,7 @@ public function resolve(): array */ public function setPsr7Request(ServerRequestInterface $request): void { - $rawContentType = $this->getContentType(); + $rawContentType = $request->getHeaderLine('Content-Type'); if (($pos = strpos((string)$rawContentType, ';')) !== false) { // e.g. text/html; charset=UTF-8 $contentType = substr($rawContentType, 0, $pos); @@ -797,6 +797,8 @@ public function setPsr7Request(ServerRequestInterface $request): void $contentType = $rawContentType; } + $parsedParams = null; + if (isset($this->parsers[$contentType])) { $parser = Yii::createObject($this->parsers[$contentType]); if (!($parser instanceof RequestParserInterface)) { From 178a159457bc9a4fad116f4ca52591fd9122cdde Mon Sep 17 00:00:00 2001 From: Blezigen Date: Wed, 26 Nov 2025 13:51:35 +0300 Subject: [PATCH 3/3] fix(http): Remove the unnecessary cast Remove the unnecessary (array) cast to support object-based parsed bodies. --- src/http/Request.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http/Request.php b/src/http/Request.php index eefec3db..1cce91a4 100644 --- a/src/http/Request.php +++ b/src/http/Request.php @@ -814,7 +814,7 @@ public function setPsr7Request(ServerRequestInterface $request): void } if ($parsedParams !== null) { - $request = $request->withParsedBody((array)$parsedParams); + $request = $request->withParsedBody($parsedParams); } $this->adapter = new ServerRequestAdapter(