Skip to content

Commit 84147bf

Browse files
authored
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.
1 parent 0e288e3 commit 84147bf

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

src/http/Request.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ public function resolve(): array
768768
return parent::resolve();
769769
}
770770

771-
/**
771+
/**
772772
* Sets and bridges a PSR-7 ServerRequestInterface instance for the current request.
773773
*
774774
* Wraps the provided PSR-7 {@see ServerRequestInterface} in a {@see ServerRequestAdapter} to enable full PSR-7
@@ -789,10 +789,35 @@ public function resolve(): array
789789
*/
790790
public function setPsr7Request(ServerRequestInterface $request): void
791791
{
792+
$rawContentType = $this->getContentType();
793+
if (($pos = strpos((string)$rawContentType, ';')) !== false) {
794+
// e.g. text/html; charset=UTF-8
795+
$contentType = substr($rawContentType, 0, $pos);
796+
} else {
797+
$contentType = $rawContentType;
798+
}
799+
800+
if (isset($this->parsers[$contentType])) {
801+
$parser = Yii::createObject($this->parsers[$contentType]);
802+
if (!($parser instanceof RequestParserInterface)) {
803+
throw new InvalidConfigException("The '$contentType' request parser is invalid. It must implement the yii\\web\\RequestParserInterface.");
804+
}
805+
$parsedParams = $parser->parse((string)$request->getBody(), $rawContentType);
806+
} elseif (isset($this->parsers['*'])) {
807+
$parser = Yii::createObject($this->parsers['*']);
808+
if (!($parser instanceof RequestParserInterface)) {
809+
throw new InvalidConfigException('The fallback request parser is invalid. It must implement the yii\\web\\RequestParserInterface.');
810+
}
811+
$parsedParams = $parser->parse((string)$request->getBody(), $rawContentType);
812+
}
813+
814+
if ($parsedParams !== null) {
815+
$request = $request->withParsedBody((array)$parsedParams);
816+
}
817+
792818
$this->adapter = new ServerRequestAdapter(
793-
$request->withHeader('statelessAppStartTime', (string) microtime(true)),
819+
$request->withHeader('statelessAppStartTime', (string) microtime(true))
794820
);
795-
796821
UploadedFile::setPsr7Adapter($this->adapter);
797822
}
798823

0 commit comments

Comments
 (0)