An HTTPS request through an HTTP proxy can receive one response accepting CONNECT and a later response from the website inside that tunnel. For the initial route setup, see Guzzle’s per-request proxy option. A header on the first response need not exist on the final response object.

For a reproduction using an HTTP endpoint you choose yourself, take a candidate from the HTTP proxy list and confirm it accepts the HTTPS tunnel. For Guzzle 7.10's cURL-handler path, preserve each header callback as a separate block:

$blocks = [];
$client = new \GuzzleHttp\Client([
    'handler' => \GuzzleHttp\HandlerStack::create(
        new \GuzzleHttp\Handler\CurlHandler()
    ),
]);

$response = $client->get('https://www.example.com/', [
    'proxy' => 'http://proxy.example:8080',
    'curl' => [CURLOPT_SUPPRESS_CONNECT_HEADERS => false],
    'on_headers' => function (
        \Psr\Http\Message\ResponseInterface $part
    ) use (&$blocks) {
        $blocks[] = [
            'status' => $part->getStatusCode(),
            'reason' => $part->getReasonPhrase(),
            'headers' => $part->getHeaders(),
        ];
    },
]);

The cURL extension must expose CURLOPT_SUPPRESS_CONNECT_HEADERS, an option introduced by libcurl 7.54.0. Setting it false allows CONNECT headers to reach cURL's header callback. The Guzzle 7.10 handler builds a response for each completed header block and calls on_headers at that boundary.

Keep the blocks in order. Authentication challenges, redirects and informational replies can produce additional blocks; do not flatten all values into one array or classify a response solely because its status is 200.

The returned response represents the completed request's response, while blocks preserves the observations collected by the callbacks. If the tunnel or TLS setup fails, handle the thrown transfer exception in the calling application; a final website response may not exist.

This behavior is tied to the stated cURL handler. A custom or stream handler is not required to expose the same proxy-handshake callbacks. Treat captured proxy headers as diagnostic data and avoid retaining account-bearing values unnecessarily.

Winndannde jowitiiɗe heen