8000 bug #50235 [HttpClient] Fix getting through proxies via CONNECT (nico… · symfony/symfony@d038a0e · GitHub
[go: up one dir, main page]

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)
0