From ccdf3cbe64afca44f7341e51bc41d1d6cfa52003 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 3 Nov 2025 09:42:57 +0100 Subject: [PATCH] [HttpClient] Reject 3xx pushed responses --- src/Symfony/Component/HttpClient/CurlHttpClient.php | 4 +++- src/Symfony/Component/HttpClient/Response/CurlResponse.php | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index b3d6f2adb8ae4..3461119744c3d 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -378,7 +378,9 @@ private static function acceptPushForRequest(string $method, array $options, Pus } } - return true; + $statusCode = $pushedResponse->response->getInfo('http_code') ?: 200; + + return $statusCode < 300 || 400 <= $statusCode; } /** diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 7e95bbcfb9a1c..0c8a5ef146ae2 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -396,7 +396,7 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & $info['peer_certificate_chain'] = array_map('openssl_x509_read', array_column($certinfo, 'Cert')); } - if (300 <= $info['http_code'] && $info['http_code'] < 400) { + if (300 <= $info['http_code'] && $info['http_code'] < 400 && null !== $options) { if (curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { curl_setopt($ch, \CURLOPT_FOLLOWLOCATION, false); } elseif (303 === $info['http_code'] || ('POST' === $info['http_method'] && \in_array($info['http_code'], [301, 302], true))) { @@ -418,7 +418,7 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & $info['redirect_url'] = null; - if (300 <= $statusCode && $statusCode < 400 && null !== $location) { + if (300 <= $statusCode && $statusCode < 400 && null !== $location && null !== $options) { if ($noContent = 303 === $statusCode || ('POST' === $info['http_method'] && \in_array($statusCode, [301, 302], true))) { $info['http_method'] = 'HEAD' === $info['http_method'] ? 'HEAD' : 'GET'; curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, $info['http_method']); @@ -433,7 +433,7 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & if (401 === $statusCode && isset($options['auth_ntlm']) && 0 === strncasecmp($headers['www-authenticate'][0] ?? '', 'NTLM ', 5)) { // Continue with NTLM auth - } elseif ($statusCode < 300 || 400 <= $statusCode || null === $location || curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { + } elseif ($statusCode < 300 || 400 <= $statusCode || null === $location || null === $options || curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { // Headers and redirects completed, time to get the response's content $multi->handlesActivity[$id][] = new FirstChunk();