x/net/http2/h2c: deprecate h2c package
要約
概要
golang.org/x/net/http2/h2c パッケージは、TLSなしで動作する暗号化されていないHTTP/2接続(h2c)をGoで扱うためのパッケージです。Go 1.24で標準ライブラリ net/http に同等機能が組み込まれたことを受け、このパッケージをdeprecate(非推奨化)するproposalが提出され、正式に承認されました。
ステータス変更
likely_accept → accepted
2026年4月8日に「likely accept」と判定された後、1週間のレビュー期間中に追加の異論が寄せられなかったため、2026年4月16日に正式に「accepted」となりました。提案内容に対してコンセンサスが形成されており、実装フェーズに移行します。
技術的背景
現状の問題点
h2c パッケージはもともと、標準ライブラリが暗号化なしのHTTP/2をサポートしていなかった時期(2018年頃)に、gRPCなど内部サービス間通信の需要に応えるために x/net に追加されました(背景: #14141)。
しかし、このパッケージには以下の問題があります。
- RFC 9113による非推奨: h2cパッケージが実装しているHTTPアップグレード機能(
Upgrade: h2cヘッダーによるHTTP/1.1からHTTP/2への切り替え)は、RFC 9113(Section 3.1)にて「広く普及しなかった」として非推奨とされています - 実装品質の問題: プロトコルアップグレード時に最初のリクエスト全体をメモリに読み込む必要があり、バグも多く含んでいました(CL 407454で修正)。サーバー側のみの対応でクライアント側のアップグレード実装がないため、アップグレード機能のテストカバレッジも存在しません
- Go 1.24で代替手段が標準化: Go 1.24で
net/httpにServer.ProtocolsおよびTransport.Protocolsが追加され、「prior knowledge(事前知識)」方式によるh2cが標準サポートされるようになりました
提案された解決策
golang.org/x/net/http2/h2c パッケージをdeprecate(非推奨)とし、標準ライブラリの net/http で提供されているネイティブなh2cサポートへの移行を促します。
Go 1.24以降、以下の方法で暗号化なしHTTP/2を利用できます。
- サーバー側:
Server.ProtocolsにUnencryptedHTTP2を設定 - クライアント側:
Transport.ProtocolsにUnencryptedHTTP2を含めHTTP1を除外
これによって何ができるようになるか
h2c パッケージが非推奨化されることで、開発者は外部パッケージへの依存なしに標準ライブラリのみでh2cサポートを実装できます。内部サービス間通信(マイクロサービス、gRPC代替、ロードバランサーのSSL終端後のバックエンド通信など)においてクリーンなAPIを利用できるようになります。
コード例
// Before: h2cパッケージを使った従来の書き方
import (
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello world")
})
h2s := &http2.Server{}
server := &http.Server{
Addr: ":8080",
Handler: h2c.NewHandler(handler, h2s), // h2cパッケージでラップが必要
}
log.Fatal(server.ListenAndServe())
// After: Go 1.24以降の標準ライブラリを使った書き方
import "net/http"
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello world")
})
var protocols http.Protocols
protocols.SetUnencryptedHTTP2(true)
protocols.SetHTTP1(true)
server := &http.Server{
Addr: ":8080",
Handler: handler,
Protocols: &protocols, // 標準ライブラリで直接設定
}
log.Fatal(server.ListenAndServe())
議論のハイライト
- RFC 9113による公式非推奨: h2cパッケージのコア機能であるHTTPアップグレード機構は、RFC 9113で既に非推奨とされており、パッケージ自体の存在意義が薄れています
- 標準ライブラリへの機能統合: Go 1.24でネイティブなh2cサポート(prior knowledge方式)が
net/httpに追加されたこと(#67816)が、このdeprecation提案の直接的な背景です - プロトコルアップグレードは今後もサポート予定なし: 提案者(@neild)は、クライアント側のアップグレード実装が存在しないことやセキュリティリスク(h2c smuggling等)を踏まえ、今後も
Upgrade: h2cをサポートする予定はないと明言しています - prior knowledge方式のみを標準化: RFC 9113が推奨する「事前知識」方式のみを標準ライブラリでサポートし、非推奨のアップグレード方式はサポート範囲外とするという設計判断がなされています
- 非推奨化後の移行パス: パッケージをすぐに削除するのではなくdeprecate扱いとすることで、既存コードとの後方互換性を維持しながら段階的な移行を促します