1. Qiita
  2. 投稿
  3. Go

GolangのhttptestでHTTP2を使う

  • 14
    いいね
  • 0
    コメント

GolangはGo1.6でHTTP2をサポートした. また2017年2月にリリース予定のGo1.8ではServer Pushを行うためのメソッドも新たに追加される(使い方は HTTP/2 Server Push · Go, the unwritten parts が詳しい). 今後GolangでのHTTP2の利用はさらに増えると考えられる. HTTP2を使うアプリが増える分そのテストも重要になる.

Go1.6におけるHTTP2サポートは素晴らしくAPIの変更なしにサポートが行なわれた. Server側でh2を有効にするにはListenAndServeTLSで起動すればよいしClientもDefaultClientを使えばよい. Golangでサーバーのテストをするときはhttptestパッケージが主に利用されるが,これほど簡単に使える訳ではない. 以下のように軽く設定を入れる必要がある.

func TestHTTP2Server(t *testing.T) {
    ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
    }))

    if err := http2.ConfigureServer(ts.Config, nil); err != nil {
        t.Fatalf("Failed to configure h2 server: %s", err)
    }
    ts.TLS = ts.Config.TLSConfig
    ts.StartTLS()

    tr := &http.Transport{
        TLSClientConfig: &tls.Config{
            InsecureSkipVerify: true,
        },
    }

    if err := http2.ConfigureTransport(tr); err != nil {
        t.Fatalf("Failed to configure h2 transport: %s", err)
    }

    client := &http.Client{
        Transport: tr,
    }

    res, err := client.Get(ts.URL)
    if err != nil {
        t.Fatalf("err: %s", err)
    }
    defer res.Body.Close()

    t.Logf("is HTTP2: %v (%s)\n", res.ProtoAtLeast(2, 0), res.Proto)
}

httptest.Serverhttp.Transportを準備し(InsecureSkipVerifyが必要),http2.ConfigureServerhttp2.ConfigureTransportを呼ぶ必要がある. これでNextProtosなどh2のネゴシエーションに必要な設定がされる.

GolangのHTTP2パッケージは今もgolang.org/x/net/http2で開発がされており,リリース時にはbundleコマンドというパワー系コマンドで標準のnet/httpにぶっ込まれる. テストは主にxにあるがnet/httpにもh2のテストがある.ここでも今回紹介した方法でテストが書かれている(参考).

ちなみにhttp.ClientではServer Pushを受け取ることはできない.テストを書くにはフレームのDecodeなどを頑張る必要がある...