diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 6f4ebf554f..4b25acf795 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -323,6 +323,7 @@ final class CurlResponse implements ResponseInterface if (200 > $statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE)) { $multi->handlesActivity[$id][] = new InformationalChunk($statusCode, $headers); + $location = null; return \strlen($data); } @@ -346,9 +347,7 @@ final class CurlResponse implements ResponseInterface } } - $location = null; - - if ($statusCode < 300 || 400 <= $statusCode || curl_getinfo($ch, CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { + if ($statusCode < 300 || 400 <= $statusCode || null === $location || curl_getinfo($ch, CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { // Headers and redirects completed, time to get the response's body $multi->handlesActivity[$id][] = new FirstChunk(); @@ -361,6 +360,8 @@ final class CurlResponse implements ResponseInterface $logger->info(sprintf('Redirecting: "%s %s"', $info['http_code'], $info['redirect_url'])); } + $location = null; + return \strlen($data); } } diff --git a/src/Symfony/Component/HttpClient/Response/MockResponse.php b/src/Symfony/Component/HttpClient/Response/MockResponse.php index 3b961db4d1..3856112a09 100644 --- a/src/Symfony/Component/HttpClient/Response/MockResponse.php +++ b/src/Symfony/Component/HttpClient/Response/MockResponse.php @@ -257,7 +257,7 @@ class MockResponse implements ResponseInterface $info = $mock->getInfo() ?: []; $response->info['http_code'] = ($info['http_code'] ?? 0) ?: $mock->getStatusCode() ?: 200; $response->addResponseHeaders($info['response_headers'] ?? [], $response->info, $response->headers); - $dlSize = isset($response->headers['content-encoding']) ? 0 : (int) ($response->headers['content-length'][0] ?? 0); + $dlSize = isset($response->headers['content-encoding']) || 'HEAD' === $response->info['http_method'] || \in_array($response->info['http_code'], [204, 304], true) ? 0 : (int) ($response->headers['content-length'][0] ?? 0); $response->info = [ 'start_time' => $response->info['start_time'], diff --git a/src/Symfony/Component/HttpClient/Response/NativeResponse.php b/src/Symfony/Component/HttpClient/Response/NativeResponse.php index 3115bade50..a9865ed09e 100644 --- a/src/Symfony/Component/HttpClient/Response/NativeResponse.php +++ b/src/Symfony/Component/HttpClient/Response/NativeResponse.php @@ -176,7 +176,7 @@ final class NativeResponse implements ResponseInterface $this->multi->handlesActivity[$this->id] = [new FirstChunk()]; - if ('HEAD' === $context['http']['method']) { + if ('HEAD' === $context['http']['method'] || \in_array($this->info['http_code'], [204, 304], true)) { $this->multi->handlesActivity[$this->id][] = null; $this->multi->handlesActivity[$this->id][] = null; diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index ec03bb61c2..10ed100ccc 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -82,6 +82,11 @@ switch ($vars['REQUEST_URI']) { header('Location: ..', true, 302); break; + case '/304': + header('Content-Length: 10', true, 304); + echo '12345'; + return; + case '/307': header('Location: http://localhost:8057/post', true, 307); break; diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index 78d0f1b39c..df7a597590 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -260,6 +260,17 @@ abstract class HttpClientTestCase extends TestCase $response->getStatusCode(); } + public function test304() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/304', [ + 'headers' => ['If-Match' => '"abc"'], + ]); + + $this->assertSame(304, $response->getStatusCode()); + $this->assertSame('', $response->getContent(false)); + } + public function testRedirects() { $client = $this->getHttpClient(__FUNCTION__);