From 960f6191e3e2899e1c1e216e749f3c811ae6c9d1 Mon Sep 17 00:00:00 2001 From: Raphael Rott Date: Fri, 3 Jan 2025 17:34:10 +0100 Subject: [PATCH 1/3] [HttpFoundation] Add support for `request_parse_body` in Request::createFromGlobals() Introduce initial support for parsing `multipart/form-data` in PUT/PATCH requests using PHP 8.4's `request_parse_body()` function. Known issue: Some tests fail due to missing Content-Type handling and lack of proper test setup for PUT/PATCH requests. These will be addressed in follow-up changes. --- .../Component/HttpFoundation/Request.php | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index db78105cc83cf..9021d0aade1e3 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -252,12 +252,24 @@ public function initialize(array $query = [], array $request = [], array $attrib 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') + || str_starts_with($contentType, 'multipart/form-data') + ) ) { - parse_str($request->getContent(), $data); - $request->request = new InputBag($data); + if (version_compare(phpversion(), '8.4.0', '>=') && function_exists('request_parse_body')) { + [$_POST, $_FILES] = request_parse_body(); + $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; From b6ebc60de805adbccf3234a3d4f2481665a18755 Mon Sep 17 00:00:00 2001 From: Raphael Rott Date: Sat, 4 Jan 2025 12:10:34 +0100 Subject: [PATCH 2/3] [HttpFoundation] Usage of PHP_VERSION_ID --- src/Symfony/Component/HttpFoundation/Request.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index 9021d0aade1e3..b1f318eebb326 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -262,7 +262,7 @@ public static function createFromGlobals(): static || str_starts_with($contentType, 'multipart/form-data') ) ) { - if (version_compare(phpversion(), '8.4.0', '>=') && function_exists('request_parse_body')) { + if (PHP_VERSION_ID >= 80400) { [$_POST, $_FILES] = request_parse_body(); $request->request = new InputBag($_POST); $request->files = new FileBag($_FILES); From 699e21e1217fe7acf112724803d39af8a83b6358 Mon Sep 17 00:00:00 2001 From: Raphael Rott Date: Sun, 5 Jan 2025 12:40:13 +0100 Subject: [PATCH 3/3] [HttpFoundation] CS Patch, no overwriting of globals --- .../Component/HttpFoundation/Request.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index b1f318eebb326..c292585063c54 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -256,20 +256,20 @@ public static function createFromGlobals(): static $method = strtoupper($request->server->get('REQUEST_METHOD', 'GET')); if ( - in_array($method, ['PUT', 'DELETE', 'PATCH'], true) + \in_array($method, ['PUT', 'DELETE', 'PATCH'], true) && ( str_starts_with($contentType, 'application/x-www-form-urlencoded') || str_starts_with($contentType, 'multipart/form-data') ) ) { - if (PHP_VERSION_ID >= 80400) { - [$_POST, $_FILES] = request_parse_body(); - $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); - } + if (\PHP_VERSION_ID >= 80400) { + [$post, $files] = request_parse_body(); + $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;