From bfdf5d92312f42db46ac8ceb21b129ea25e53045 Mon Sep 17 00:00:00 2001 From: Kurt Thiemann Date: Mon, 2 Dec 2024 12:18:11 +0100 Subject: [PATCH] [HttpClient] Always set CURLOPT_CUSTOMREQUEST to the correct HTTP method in CurlHttpClient --- .../Component/HttpClient/CurlHttpClient.php | 3 +-- .../HttpClient/Tests/HttpClientTestCase.php | 22 +++++++++++++++++++ .../Component/HttpClient/composer.json | 2 +- .../HttpClient/Test/Fixtures/web/index.php | 1 + 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 7d996200527eb..3e15bef74cc9e 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -197,13 +197,12 @@ public function request(string $method, string $url, array $options = []): Respo $curlopts[\CURLOPT_RESOLVE] = $resolve; } + $curlopts[\CURLOPT_CUSTOMREQUEST] = $method; if ('POST' === $method) { // Use CURLOPT_POST to have browser-like POST-to-GET redirects for 301, 302 and 303 $curlopts[\CURLOPT_POST] = true; } elseif ('HEAD' === $method) { $curlopts[\CURLOPT_NOBODY] = true; - } else { - $curlopts[\CURLOPT_CUSTOMREQUEST] = $method; } if ('\\' !== \DIRECTORY_SEPARATOR && $options['timeout'] < 1) { diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php index a0e57bf2c5ff4..f572908c1535d 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php +++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php @@ -651,4 +651,26 @@ public function testDefaultContentType() $this->assertSame(['abc' => 'def', 'content-type' => 'application/json', 'REQUEST_METHOD' => 'POST'], $response->toArray()); } + + public function testHeadRequestWithClosureBody() + { + $p = TestHttpServer::start(8067); + + try { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('HEAD', 'http://localhost:8057/head', [ + 'body' => fn () => '', + ]); + $headers = $response->getHeaders(); + } finally { + $p->stop(); + } + + $this->assertArrayHasKey('x-request-vars', $headers); + + $vars = json_decode($headers['x-request-vars'][0], true); + $this->assertIsArray($vars); + $this->assertSame('HEAD', $vars['REQUEST_METHOD']); + } } diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index 23437d5363f28..9c9ee14a4a3ff 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -25,7 +25,7 @@ "php": ">=8.1", "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "~3.4.3|^3.5.1", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", "symfony/service-contracts": "^2.5|^3" }, "require-dev": { diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index a75001785ae2d..59033d55a0350 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -42,6 +42,7 @@ exit; case '/head': + header('X-Request-Vars: '.json_encode($vars, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)); header('Content-Length: '.strlen($json), true); break;