メインコンテンツへスキップ

Go Proposal Weekly Digest

Go言語のproposal更新を毎週お届け

net/http: pluggable HTTP/3

ステータス変更: active hold

要約

AIによる要約であり、誤りを含む場合があります。

概要

net/httpTransportServer に対してHTTP/3実装をプラグイン方式で接続できるようにするための提案です。net/http パッケージ自体にHTTP/3を組み込むのではなく、外部パッケージ(golang.org/x/net/http3github.com/quic-go/quic-go など)が既存の登録機構を通じて接続できるようにすることを目的としています。

ステータス変更

activehold
2026年6月10日のProposal Review Meetingにて、本proposalは hold(保留)となりました。会議記録によれば、同日に関連する x/net/http3: add experimental HTTP/3 implementation (#70914) も同時に保留となっています。これは、HTTP/3の実装が x/net/internal/http3 パッケージとして開発中の段階にあり、外部に公開できる安定したAPIが確立されていないためと考えられます。ユーザーに公開されるAPIは、内部実装が十分に成熟してから再検討される予定です。

技術的背景

現状の問題点

net/http はHTTP/1とHTTP/2をネイティブにサポートしていますが、HTTP/3(QUIC上で動作するHTTP)には対応していません。HTTP/3を使いたい場合、github.com/quic-go/quic-go などの外部ライブラリを使用して独自にサーバーやクライアントを構築する必要があり、既存の net/http.Transportnet/http.Server との統合ができませんでした。

// 現状: HTTP/3を使うには外部ライブラリで独立して構築が必要
http3Server := &http3.Server{
    Addr:      "localhost:8000",
    Handler:   myHandler,
    TLSConfig: tlsConfig,
}
http3Server.ListenAndServe()
// 別途HTTP/1+HTTP/2用サーバーも起動が必要
http.ListenAndServeTLS(":8001", certFile, keyFile, myHandler)

提案された解決策

ユーザー向けのAPIの変更は最小限に抑えられ、既存の http.Protocols 型にHTTP/3の選択肢を追加することのみです。

package http
// HTTP3 reports whether p includes HTTP/3.
func (p Protocols) HTTP3() bool
// SetHTTP3 adds or removes HTTP/3 from p.
func (p *Protocols) SetHTTP3(ok bool)

内部の登録機構として、クライアント側は既存の Transport.RegisterProtocol をスキームとして "http/3" を指定する形で流用し、サーバー側は既存の Server.TLSNextProto マップに "http/3" エントリを追加する形で実現します。これらの仕組みはユーザーに公開されるAPIではなく、x/net/internal/http3 や quic-go などの実装者が使用するものです。

これによって何ができるようになるか

承認された場合、HTTP/3対応の外部パッケージをインポートするだけで、既存の net/http.Transport / Server コードをほぼそのままにHTTP/3を利用できるようになります。

// After: 外部HTTP/3パッケージを登録するだけで net/http から HTTP/3 が使える
import "golang.org/x/net/http3"
tr := &http.Transport{}
http3.RegisterTransport(tr)  // HTTP/3実装を登録
tr.Protocols = new(http.Protocols)
tr.Protocols.SetHTTP3(true)
tr.Protocols.SetHTTP1(false)
tr.Protocols.SetHTTP2(false)
// 以降のリクエストはHTTP/3で送信される
resp, err := tr.RoundTrip(req)

サーバー側も同様に統合できる想定です。

srv := &http.Server{Addr: "localhost:8000"}
http3.RegisterServer(srv)
srv.Protocols = new(http.Protocols)
srv.Protocols.SetHTTP3(true)
// HTTP/3接続をリッスン
srv.ListenAndServeTLS(certFile, keyFile)

議論のハイライト

  • スコープの絞り込み: 当初の提案では内部登録機構の詳細も含まれていたが、2026年3月25日の委員会での議論を経て、ユーザー向けのAPI変更は http.Protocols 型への HTTP3()/SetHTTP3() 追加のみに絞り込まれた。
  • Happy Eyeballs v3の問題: quic-go のメインテナーである @marten-seemann が指摘したように、HTTP/3(QUIC)はUDPトラフィックをブロックするネットワーク環境での接続失敗リスクがあり、フォールバック機構(Happy Eyeballs v3)が整備されるまでは一般的なHTTPトラフィックでの実用性に懸念がある。
  • サーバー側の価値: @marten-seemann は http3.Serverhttp.Handlertls.Config から起動するのは既に数行でできるため、net/http.Server への統合による恩恵は限定的だと指摘した。
  • HTTP/2の前轍を踏まない: HTTP/2を net/http の外部パッケージとして先に開発した際に依存関係が複雑になった経緯があり、HTTP/3を net/http に直接組み込まず外部パッケージに分離する方針はその教訓に基づいている。
  • 同時保留の背景: 本proposalと x/net/http3 実験的実装提案 (#70914) が同日に保留となっており、内部実装 (x/net/internal/http3) の成熟を待ってから公開APIを確定させるという方針が窺える。

関連リンク