GuzzleのcURLハンドラー: プロキシのCONNECTヘッダーを取得する
プロキシのCONNECT応答とWebサイトの応答の両方が重要な場合に、GuzzleのcURLハンドラーで個別の応答ヘッダーブロックを取得します。
HTTPプロキシ経由のHTTPSリクエストでは、CONNECTを受け付ける応答と、その後トンネル内のWebサイトからの応答を受け取ることがあります。最初のルート設定についてはGuzzleのリクエスト単位のプロキシオプションを参照してください。最初の応答のヘッダーが最終的な応答オブジェクトに存在する必要はありません。
自分で選んだHTTPエンドポイントで再現するには、HTTPプロキシ一覧から候補を選び、HTTPSトンネルを受け付けることを確認します。Guzzle 7.10のcURLハンドラーの経路では、各ヘッダーコールバックを個別のブロックとして保持します:
$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(),
];
},
]);
cURL拡張はCURLOPT_SUPPRESS_CONNECT_HEADERSを公開している必要があります。これはlibcurl 7.54.0で導入されたオプションです。falseに設定すると、CONNECTヘッダーがcURLのヘッダーコールバックに届きます。Guzzle 7.10のハンドラーは、完了したヘッダーブロックごとに応答を構築し、その境界でon_headersを呼び出します。
ブロックは順序どおりに保ちます。認証チャレンジ、リダイレクト、情報応答は追加のブロックを生むことがあります。すべての値を1つの配列に平坦化したり、ステータスが200という理由だけで応答を分類したりしないでください。
返される応答は完了したリクエストの応答を表し、blocksはコールバックが収集した観測を保持します。トンネルやTLSの設定に失敗した場合、呼び出し側アプリケーションでスローされた転送例外を処理してください。最終的なWebサイトの応答が存在しないこともあります。
この動作は示したcURLハンドラーに固有です。カスタムハンドラーやストリームハンドラーが同じプロキシハンドシェイクのコールバックを公開する義務はありません。取得したプロキシヘッダーは診断データとして扱い、アカウントに関わる値を不必要に保持しないでください。