Skip to content

Commit 514a0f9

Browse files
[HttpClient] Fix getting through proxies via CONNECT
1 parent 9cefd68 commit 514a0f9

File tree

2 files changed

+16
-17
lines changed

2 files changed

+16
-17
lines changed

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();

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)