プロキシ経由の相対リダイレクトを追跡する
相対 Location を現在の宛先 URL に対して解決し、プロキシのアドレスを URL 解決から排除します。
プロキシ経由で受け取った応答は相対 Location を返すことがあります:
Location: ../new/
現代の HTTP ではここに URI 参照を許します。応答を生成した URL に対して解決してください。その URL が https://docs.example/catalog/old/ だった場合、上記の参照は https://docs.example/catalog/new/ を指します。プロキシのホスト名は基準ではありません。
通常の Python urllib リクエストでは、プロキシのエンドポイント周りで文字列を連結するのではなく、そのリダイレクトハンドラを使用します:
opener = build_opener(ProxyHandler({
"https": "http://proxy.example:8080",
}))
with opener.open("https://docs.example/catalog/old/",
timeout=15) as response:
final_url = response.geturl()
プロキシ認証のないこの公開ドキュメントのリクエストでは、ルートが許可されていれば、HTTP プロキシ一覧の HTTP 候補がサンプルのエンドポイントを置き換えられます。クラスは urllib.request に由来します。通常のハンドラはサポートされるリダイレクトをその制限内で追跡します。final_url が示すのは最終的なリソース URL であり、そこへ到達するために使った仲介者ではありません。
まず解決し、次に経路を選ぶ
リダイレクトは宛先のホストやスキームを変えることがあります。そのため宛先ベースのプロキシポリシーは、その新しい URL も評価する必要があります。最初のホストで機能した経路が次のホストの経路とは限りません。
リダイレクト処理を自分で実装する場合は、ドットセグメントを扱う URI 参照解決を使用してください。実際のステータスコードのメソッド規則を保ち、リダイレクト上限を設けます。Location をホスト名に連結することは、その解決アルゴリズムの代わりにはなりません。
リダイレクトが失敗した場合は、要求した URL、応答ステータス、Location の値、解決済みの次の URL を保持してください。これらの 4 つの値は通常、失敗が URL の構築側か、その後に試みた接続側かを示します。