HTTP/2 は Go の SOCKS トンネルの中を通る
標準の HTTP トランスポートを複製し、SOCKS プロキシを選び、実際にネゴシエートされた宛先プロトコルを確認します。
SOCKS トンネルは TCP 接続を運びます。Go はそのトンネル越しに宛先と TLS を行い、そこで HTTP/2 をネゴシエートできます。SOCKS サーバー自身が HTTP/2 を話す必要はありません。
Go の標準デフォルトトランスポートを保持するプログラムでは、その設定を複製してプロキシを選びます。
import (
"net/http"
"net/url"
"time"
)
proxyURL := &url.URL{
Scheme: "socks5",
Host: "proxy.example:1080",
}
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.Proxy = http.ProxyURL(proxyURL)
client := &http.Client{
Transport: transport,
Timeout: 30 * time.Second,
}
プロキシと宛先は別々の値のままです。プロキシの値には SOCKS5 プロキシ一覧 から SOCKS5 エンドポイントを選びます。HTTP/2 はあくまで宛先とネゴシエートされます。client を使って実際の HTTPS サービス URL を要求し、その後はアプリケーションの通常のライフサイクルでレスポンスボディを閉じます。
標準デフォルトトランスポートは HTTP/2 をサポートしています。複製すればその設定を保ったままプロキシの選択を変えられます。型アサーションは、プログラムが http.DefaultTransport を別の RoundTripper に置き換えていないことを前提とします。
別途構築したトランスポートでは、特に独自の dial や TLS フックを渡す場合、その HTTP/2 設定を確認してください。Go は ForceAttemptHTTP2 を、新しいリリースではこれらの選択のための明示的な Protocols 設定を公開しています。
宛先は依然として TLS ネゴシエーションで HTTP/2 を提示する必要があります。成功したレスポンスの Proto または ProtoMajor の値を確認して、何が使われたかを見てください。SOCKS 経由で HTTPS 要求が成功したことは、ネゴシエートされたプロトコルが HTTP/2 だったことをそれ自体では証明しません。