Skip to content

[HttpFoundation] Add support for parsing non-POST requests using request_parse_body() (PHP 8.4) #59358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: 7.3
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions src/Symfony/Component/HttpFoundation/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,24 @@
public static function createFromGlobals(): static
{
$request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER);

if (str_starts_with($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded')
&& \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH'], true)
$contentType = $request->headers->get('CONTENT_TYPE', '');
$method = strtoupper($request->server->get('REQUEST_METHOD', 'GET'));

if (
\in_array($method, ['PUT', 'DELETE', 'PATCH'], true)
&& (
str_starts_with($contentType, 'application/x-www-form-urlencoded')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd let this check on the content-type to the request_parse_body function, no need to implement it ourselves

Copy link
Author

@rottifant rottifant Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?
A content type check is required because if, for example, a request with content-type application/json is passed to the function, it will throw RequestParseBodyException: Content-Type "application/json" is not supported. Or are we going to catch and handle it? RequestParseBodyException is also thrown with invalid content, not just unsupported.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean the check for the content-type: we can catch the exception and deal with it instead of checking the content-type ourselves (and diverging from the native check).
We have to add logic to deal with the exception anyway, we cannot let it bubble down unhandled (createFromGlobals isn't expected to throw such exceptions).

Copy link
Author

@rottifant rottifant Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, my bad. I overlooked the "on the content-type" in your message...
I checked this because RequestParseBodyException is also thrown with invalid content, not just unsupported Content-Type. Or are we going to differentiate this?

|| str_starts_with($contentType, 'multipart/form-data')
)
) {
parse_str($request->getContent(), $data);
$request->request = new InputBag($data);
if (\PHP_VERSION_ID >= 80400) {
[$post, $files] = request_parse_body();

Check failure on line 266 in src/Symfony/Component/HttpFoundation/Request.php

View workflow job for this annotation

GitHub Actions / Psalm

UndefinedFunction

src/Symfony/Component/HttpFoundation/Request.php:266:35: UndefinedFunction: Function Symfony\Component\HttpFoundation\request_parse_body does not exist, consider enabling the allFunctionsGlobal config option if scanning legacy codebases (see https://psalm.dev/021)

Check failure on line 266 in src/Symfony/Component/HttpFoundation/Request.php

View workflow job for this annotation

GitHub Actions / Psalm

UndefinedFunction

src/Symfony/Component/HttpFoundation/Request.php:266:35: UndefinedFunction: Function Symfony\Component\HttpFoundation\request_parse_body does not exist, consider enabling the allFunctionsGlobal config option if scanning legacy codebases (see https://psalm.dev/021)
$request->request = new InputBag($post);
$request->files = new FileBag($files);
} elseif (str_starts_with($contentType, 'application/x-www-form-urlencoded')) {
parse_str($request->getContent(), $data);
$request->request = new InputBag($data);
}
}

return $request;
Expand Down
Loading