From d7c13610acc586f31a38e559c1a144a10ab914b3 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 21 Mar 2022 10:27:48 +0100 Subject: [PATCH] [HttpClient] On redirections don't send content-related request headers --- src/Symfony/Component/HttpClient/CurlHttpClient.php | 6 ++++-- .../Component/HttpClient/NativeHttpClient.php | 7 +++++-- .../HttpClient/Tests/HttpClientTestCase.php | 12 ++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 2830c5025063e..3b63addec8865 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -204,9 +204,11 @@ public function request(string $method, string $url, array $options = []): Respo $hasContentLength = isset($options['normalized_headers']['content-length'][0]); - foreach ($options['headers'] as $header) { + foreach ($options['headers'] as $i => $header) { if ($hasContentLength && 0 === stripos($header, 'Content-Length:')) { - continue; // Let curl handle Content-Length headers + // Let curl handle Content-Length headers + unset($options['headers'][$i]); + continue; } if (':' === $header[-2] && \strlen($header) - 2 === strpos($header, ': ')) { // curl requires a special syntax to send empty headers diff --git a/src/Symfony/Component/HttpClient/NativeHttpClient.php b/src/Symfony/Component/HttpClient/NativeHttpClient.php index 939eb425c7672..f52d93d5eb7e0 100644 --- a/src/Symfony/Component/HttpClient/NativeHttpClient.php +++ b/src/Symfony/Component/HttpClient/NativeHttpClient.php @@ -430,9 +430,12 @@ private static function createRedirectResolver(array $options, string $host, ?ar if ('POST' === $options['method'] || 303 === $info['http_code']) { $info['http_method'] = $options['method'] = 'HEAD' === $options['method'] ? 'HEAD' : 'GET'; $options['content'] = ''; - $options['header'] = array_filter($options['header'], static function ($h) { + $filterContentHeaders = static function ($h) { return 0 !== stripos($h, 'Content-Length:') && 0 !== stripos($h, 'Content-Type:'); - }); + }; + $options['header'] = array_filter($options['header'], $filterContentHeaders); + $redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], $filterContentHeaders); + $redirectHeaders['with_auth'] = array_filter($redirectHeaders['with_auth'], $filterContentHeaders); stream_context_set_option($context, ['http' => $options]); } diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php index cf33bd9816e86..d36e7f70b72ca 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php +++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php @@ -194,6 +194,18 @@ public function testFixContentLength() $this->assertSame(['abc' => 'def', 'REQUEST_METHOD' => 'POST'], $body); } + public function testDropContentRelatedHeadersWhenFollowingRequestIsUsingGet() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('POST', 'http://localhost:8057/302', [ + 'body' => 'foo', + 'headers' => ['Content-Length: 3'], + ]); + + $this->assertSame(200, $response->getStatusCode()); + } + public function testNegativeTimeout() { $client = $this->getHttpClient(__FUNCTION__);