from urllib.request import ProxyHandler, build_opener

def make_proxy_opener(proxy_uri):
    return build_opener(ProxyHandler({
        "http": proxy_uri,
        "https": proxy_uri,
    }))

opener = make_proxy_opener("http://proxy.example.net:8080")
# Use opener.open(destination, timeout=10) for this route.

経路が検査に属する場合は、このopener自身のopenメソッドを呼び出します。例のHTTPエンドポイントは、あなたのサービスまたは公開検査向けのHTTPプロキシ一覧から取得できます。この断片は所有関係を示すものであり、認証やヘルスの完全な方針を定義するものではありません。アカウント固有のハンドラは意図したクライアントに接続したままにします。

urllib.request.install_opener()は、後続のモジュールレベルのurlopen()呼び出しが使うプロセス全体の既定値を変更します。そのため、プロキシを巡回するチェッカーは無関係なリクエストを最後のエンドポイントのまま残す可能性があります。一時的にインストールしてクリーンアップで復元しても、共有された変更の間は並行リクエストが実行できてしまいます。

socket.setdefaulttimeout()も同様に、その後作成されるソケットの既定値を変更します。検査だけが受け取るべき場合は操作レベルのタイムアウトを使います。

検査の応答を閉じ、結果を具体的に保ちます。HTTPエラー応答は自動的に死んだプロキシリスナーではありません。非同期サービスで同期urllib検査を使う場合は、ブロックする処理を適切なワーカーへ移します。その実行上の判断は、グローバルなopener変更を分離されたものにはしません。

検査は別のネットワーク方針を残さずに観測結果を返すべきです。自身のクライアントオブジェクトと範囲を限定した操作が、その境界を明示します。

関連記事