ISUCONのベンチマーカーでGoのhttp.Clientをhttp2で使おうとしてハマった話 - Qiita
以前の記事では以下のように作ったクライアントを都度生成し、かつGoのコードにパッチを当てることで対応しました。
c := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
Goにパッチを当てずに対応する方法はないでしょうか。Goにパッチを当てずに以下のようにするとどうでしょう。
c := &http.Client{
Transport: &http2.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
これでも期待通りに動くように見えますが、これだとHTTP/1.1にしか対応してないサーバーに接続できなくなります。ちなみにHTTP/1.1までしか対応してないサーバーを立てたい場合は GODEBUG=http2server=0 ./server
という感じに実行します。
ここで前回当てたパッチをもう一度確認します。
TLSClientConfigを上書きしつつ、http2も使えるようにするパッチ by catatsuy · Pull Request #80 · isucon/isucon6-final
を見てもらえれば分かりますが、TLSClientConfigを上書きすると飛ばされる処理で重要な処理は http2configureTransport
です。これは golang.org/x/net/http2 をGoのコード内部に取り込むために使ったbundleコマンドによってリネームされた関数で、元々は configureTransport
という関数名です。bundleコマンドについては下のリンクを参照してください。
configureTransport
はプライベートな関数ですが、内部でそれを呼び出すhttp2.ConfigureTransport
関数があるので、それを呼び出せばよいです。なので以下のようにします。
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
if err := http2.ConfigureTransport(tr); err != nil {
log.Fatalf("Failed to configure h2 transport: %s", err)
}
c := &http.Client{
Transport: tr,
}
こうすればGoのコードにパッチを当てずに、今回期待する動きを実現できそうです。
ということでPR作りました。
パッチを当てずに証明書を無視するクライアントでHTTP2を使えるようにする by catatsuy · Pull Request #270 · isucon/isucon6-final