このページの目次
HTTP/3
HTTP/3 は QUIC 上で HTTP を実行する——TCP に依存せず、UDP でカプセル化し、ストリーム間は完全に独立(ヘッドオブラインブロックなし)。QPACK が HPACK に代わり、0-RTT で接続を再開する。HTTP のセマンティクスは変わらず、トランスポート層が完全に書き換えられた。
概要
HTTP/3(RFC 9114, 2022)は、HTTP を TCP から QUIC(UDP)へ移行し、HTTP/2 の最大の未解決問題であった TCP レベルでのヘッドオブラインブロックを解決しました。1 つのストリームでのパケット損失が他のストリームをブロックすることはなくなりました。QUIC の接続移行機能により、モバイルネットワークの切り替え(WiFi↔4G)でも HTTP 接続が切断されなくなりました。QPACK は HPACK に代わり、ヘッダー圧縮における動的テーブルの HOL ブロックを解決しました。HTTP/3 は HTTP/2 と全く同じセマンティクスを使用しています——トランスポート層が変わっただけです。
HTTP/3 = HTTP/2 セマンティクス + QUIC トランスポート
HTTP/3 は HTTP/2 のすべてのセマンティクス(ストリーム、マルチプレクシング、ヘッダー、メソッド、ステータスコード)を維持しつつ、トランスポート層を置き換えました: TCP → QUIC (UDP)。
主な変更点:
- ストリーム: TCP バイトストリーム上のフレームマルチプレクシングから、QUIC のストリームはプロトコルの最上位層へ
- HPACK → QPACK: HPACK の「動的テーブル更新の損失 → HOL ブロック」を解決
- TLS 1.3: 必須(QUIC は暗号化内蔵、平文の HTTP/3 は存在しない)
- Server Push: 廃止済み(Chrome/nginx はいずれも削除済み)
QPACK
HPACK の問題: 動的テーブル更新を含む HEADERS フレームが失われると → 受信側は後の HEADERS をデコードできず → HOL ブロックが再発!
QPACK: 動的テーブル更新とデータフレームは、QUIC の異なるユニディレクショナルストリーム上で送信される:
エンコーダストリーム(ユニディレクショナル、QPACK エンコーダ → デコーダ):
テーブル更新: Insert (name, value) + TSS (Table State Synchronize)
デコーダストリーム(ユニディレクショナル、デコーダ → エンコーダ):
フィードバック: Section Acknowledgment, Stream Cancellation
要求/応答ストリーム(双方向):
HEADERS + DATA フレーム(動的テーブルのインデックスを参照)
→ テーブル更新の損失はエンコーダストリーム(テーブル更新)のみをブロックし、要求/応答はブロックされない!
デプロイ: Alt-Svc
HTTP/2 または HTTP/1.1 の応答ヘッダー:
Alt-Svc: h3=":443"; ma=86400
h3: QUIC 上の HTTP/3
ma (max-age): 86400 秒間、この代替エンティティを記憶
:443: QUIC ポート(通常は同じポート)
ブラウザ: Alt-Svc を受信 → 同じホストへの次回接続で → QUIC:443 を優先して試行
→ QUIC が不通の場合(UDP がブロックされている、QUIC バージョンの不一致)→ TCP にフォールバック
参考
- RFC: 9114, 9204
- ツール:
curl --http3 -v, Chromechrome://net-internals/#http3
キーワード: HTTP/3, QUIC, QPACK, Alt-Svc, 接続移行, 0-RTT, ユニディレクショナルストリーム