Skip to content

Commit

Permalink
[HttpClient] Fix getting through proxies via CONNECT
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-grekas committed May 4, 2023
1 parent 1d52937 commit 78eff39
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 17 deletions.
3 changes: 1 addition & 2 deletions src/Symfony/Component/HttpClient/Response/AmpResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ final class AmpResponse implements ResponseInterface, StreamableInterface

private $multi;
private $options;
private $canceller;
private $onProgress;

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

$info = &$this->info;
$headers = &$this->headers;
$canceller = $this->canceller = new CancellationTokenSource();
$canceller = new CancellationTokenSource();
$handle = &$this->handle;

$info['url'] = (string) $request->getUri();
Expand Down
30 changes: 15 additions & 15 deletions src/Symfony/Component/HttpClient/Response/CurlResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,7 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
}

curl_setopt($ch, \CURLOPT_HEADERFUNCTION, static function ($ch, string $data) use (&$info, &$headers, $options, $multi, $id, &$location, $resolveRedirect, $logger): int {
if (0 !== substr_compare($data, "\r\n", -2)) {
return 0;
}

$len = 0;

foreach (explode("\r\n", substr($data, 0, -2)) as $data) {
$len += 2 + self::parseHeaderLine($ch, $data, $info, $headers, $options, $multi, $id, $location, $resolveRedirect, $logger);
}

return $len;
return self::parseHeaderLine($ch, $data, $info, $headers, $options, $multi, $id, $location, $resolveRedirect, $logger);
});

if (null === $options) {
Expand Down Expand Up @@ -381,19 +371,29 @@ private static function select(ClientState $multi, float $timeout): int
*/
private static function parseHeaderLine($ch, string $data, array &$info, array &$headers, ?array $options, CurlClientState $multi, int $id, ?string &$location, ?callable $resolveRedirect, ?LoggerInterface $logger): int
{
if (!str_ends_with($data, "\r\n")) {
return 0;
}

$waitFor = @curl_getinfo($ch, \CURLINFO_PRIVATE) ?: '_0';

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

if ('' !== $data) {
$statusCode = curl_getinfo($ch, \CURLINFO_RESPONSE_CODE);

if ($statusCode !== $info['http_code'] && !preg_match("#^HTTP/\d+(?:\.\d+)? {$statusCode}(?: |\r\n$)#", $data)) {
return \strlen($data); // Ignore headers from responses to CONNECT requests
}

if ("\r\n" !== $data) {
// Regular header line: add it to the list
self::addResponseHeaders([$data], $info, $headers);
self::addResponseHeaders([substr($data, 0, -2)], $info, $headers);

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

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

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

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

Expand Down

0 comments on commit 78eff39

Please sign in to comment.