Skip to content

Commit d038a0e

Browse files
bug #50235 [HttpClient] Fix getting through proxies via CONNECT (nicolas-grekas)
This PR was merged into the 5.4 branch. Discussion ---------- [HttpClient] Fix getting through proxies via CONNECT | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - Spotted while trying to hit google via `symfony proxy:start`: ```sh https_proxy=http://127.0.0.1:7080 php test.php ``` where test.php contains: ```php $client = new CurlHttpClient(); $r = $client->request('GET', 'https://google.com/'); dump($r->getStatusCode()); dump($r->getHeaders()); dump($r->getInfo('debug')); ``` Commits ------- 78eff39 [HttpClient] Fix getting through proxies via CONNECT
2 parents 1b66735 + 78eff39 commit d038a0e

File tree

2 files changed

+16
-17
lines changed

2 files changed

+16
-17
lines changed

src/Symfony/Component/HttpClient/Response/AmpResponse.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ final class AmpResponse implements ResponseInterface, StreamableInterface
4747

4848
private $multi;
4949
private $options;
50-
private $canceller;
5150
private $onProgress;
5251

5352
private static $delay;
@@ -73,7 +72,7 @@ public function __construct(AmpClientState $multi, Request $request, array $opti
7372

7473
$info = &$this->info;
7574
$headers = &$this->headers;
76-
$canceller = $this->canceller = new CancellationTokenSource();
75+
$canceller = new CancellationTokenSource();
7776
$handle = &$this->handle;
7877

7978
$info['url'] = (string) $request->getUri();

src/Symfony/Component/HttpClient/Response/CurlResponse.php

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,7 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
7676
}
7777

7878
curl_setopt($ch, \CURLOPT_HEADERFUNCTION, static function ($ch, string $data) use (&$info, &$headers, $options, $multi, $id, &$location, $resolveRedirect, $logger): int {
79-
if (0 !== substr_compare($data, "\r\n", -2)) {
80-
return 0;
81-
}
82-
83-
$len = 0;
84-
85-
foreach (explode("\r\n", substr($data, 0, -2)) as $data) {
86-
$len += 2 + self::parseHeaderLine($ch, $data, $info, $headers, $options, $multi, $id, $location, $resolveRedirect, $logger);
87-
}
88-
89-
return $len;
79+
return self::parseHeaderLine($ch, $data, $info, $headers, $options, $multi, $id, $location, $resolveRedirect, $logger);
9080
});
9181

9282
if (null === $options) {
@@ -381,19 +371,29 @@ private static function select(ClientState $multi, float $timeout): int
381371
*/
382372
private static function parseHeaderLine($ch, string $data, array &$info, array &$headers, ?array $options, CurlClientState $multi, int $id, ?string &$location, ?callable $resolveRedirect, ?LoggerInterface $logger): int
383373
{
374+
if (!str_ends_with($data, "\r\n")) {
375+
return 0;
376+
}
377+
384378
$waitFor = @curl_getinfo($ch, \CURLINFO_PRIVATE) ?: '_0';
385379

386380
if ('H' !== $waitFor[0]) {
387381
return \strlen($data); // Ignore HTTP trailers
388382
}
389383

390-
if ('' !== $data) {
384+
$statusCode = curl_getinfo($ch, \CURLINFO_RESPONSE_CODE);
385+
386+
if ($statusCode !== $info['http_code'] && !preg_match("#^HTTP/\d+(?:\.\d+)? {$statusCode}(?: |\r\n$)#", $data)) {
387+
return \strlen($data); // Ignore headers from responses to CONNECT requests
388+
}
389+
390+
if ("\r\n" !== $data) {
391391
// Regular header line: add it to the list
392-
self::addResponseHeaders([$data], $info, $headers);
392+
self::addResponseHeaders([substr($data, 0, -2)], $info, $headers);
393393

394394
if (!str_starts_with($data, 'HTTP/')) {
395395
if (0 === stripos($data, 'Location:')) {
396-
$location = trim(substr($data, 9));
396+
$location = trim(substr($data, 9, -2));
397397
}
398398

399399
return \strlen($data);
@@ -416,7 +416,7 @@ private static function parseHeaderLine($ch, string $data, array &$info, array &
416416

417417
// End of headers: handle informational responses, redirects, etc.
418418

419-
if (200 > $statusCode = curl_getinfo($ch, \CURLINFO_RESPONSE_CODE)) {
419+
if (200 > $statusCode) {
420420
$multi->handlesActivity[$id][] = new InformationalChunk($statusCode, $headers);
421421
$location = null;
422422

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy