diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index e77eb86c4c452..660ba61ee9045 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -92,6 +92,10 @@ public function request(string $method, string $url, array $options = []): Respo $scheme = $url['scheme']; $authority = $url['authority']; $host = parse_url($authority, \PHP_URL_HOST); + $proxy = $options['proxy'] + ?? ('https:' === $url['scheme'] ? $_SERVER['https_proxy'] ?? $_SERVER['HTTPS_PROXY'] ?? null : null) + // Ignore HTTP_PROXY except on the CLI to work around httpoxy set of vulnerabilities + ?? $_SERVER['http_proxy'] ?? (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? $_SERVER['HTTP_PROXY'] ?? null : null) ?? $_SERVER['all_proxy'] ?? $_SERVER['ALL_PROXY'] ?? null; $url = implode('', $url); if (!isset($options['normalized_headers']['user-agent'])) { @@ -107,7 +111,7 @@ public function request(string $method, string $url, array $options = []): Respo \CURLOPT_MAXREDIRS => 0 < $options['max_redirects'] ? $options['max_redirects'] : 0, \CURLOPT_COOKIEFILE => '', // Keep track of cookies during redirects \CURLOPT_TIMEOUT => 0, - \CURLOPT_PROXY => $options['proxy'], + \CURLOPT_PROXY => $proxy, \CURLOPT_NOPROXY => $options['no_proxy'] ?? $_SERVER['no_proxy'] ?? $_SERVER['NO_PROXY'] ?? '', \CURLOPT_SSL_VERIFYPEER => $options['verify_peer'], \CURLOPT_SSL_VERIFYHOST => $options['verify_host'] ? 2 : 0, @@ -404,8 +408,15 @@ private static function createRedirectResolver(array $options, string $host): \C } $url = self::parseUrl(curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL)); + $url = self::resolveUrl($location, $url); - return implode('', self::resolveUrl($location, $url)); + curl_setopt($ch, \CURLOPT_PROXY, $options['proxy'] + ?? ('https:' === $url['scheme'] ? $_SERVER['https_proxy'] ?? $_SERVER['HTTPS_PROXY'] ?? null : null) + // Ignore HTTP_PROXY except on the CLI to work around httpoxy set of vulnerabilities + ?? $_SERVER['http_proxy'] ?? (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? $_SERVER['HTTP_PROXY'] ?? null : null) ?? $_SERVER['all_proxy'] ?? $_SERVER['ALL_PROXY'] ?? null + ); + + return implode('', $url); }; } } diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index 7ebf055d75701..ddc5324492c86 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -929,6 +929,16 @@ public function testProxy() $body = $response->toArray(); $this->assertSame('Basic Zm9vOmI9YXI=', $body['HTTP_PROXY_AUTHORIZATION']); + + $_SERVER['http_proxy'] = 'http://localhost:8057'; + try { + $response = $client->request('GET', 'http://localhost:8057/'); + $body = $response->toArray(); + $this->assertSame('localhost:8057', $body['HTTP_HOST']); + $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.0\.1):8057/$#', $body['REQUEST_URI']); + } finally { + unset($_SERVER['http_proxy']); + } } public function testNoProxy()