1 of 23

HTTP/3 and QPACK

HTTP RFC Publication Study

@bokken

1

2 of 23

About me

  • Name: bokken
  • Twitter: @bokken_
  • GitHub: @negibokken
  • Like:
    • ブラウザ
      • レンダリングエンジンからミニ自作ブラウザを作った
      • Chromium Contributor として頑張りたい

2

3 of 23

もくじ (持ち時間10分)

  • HTTP/3
  • QPACK

3

4 of 23

HTTP/3

4

5 of 23

HTTP/3 の歴史

  • 2013 年: Google QUIC が提案される
  • 2016 年: IETF QUIC (HTTP over QUIC) draft
    • IETF 有志でドラフト作成
    • このときは HTTP over QUIC
  • 2018 年: HTTP over QUIC から HTTP/3 draft に
    • QUIC はアプリケーション層も含んでいたが HTTP/3 は違う
    • HTTP/2 over QUIC ではない
    • HTTP/2 よりも新しいものである
  • 2022 年6月6日: HTTP/3 RFC 🎉

5

6 of 23

HTTP/3 と HTTP/2, HTTP/1.1 の比較

6

  • IP 層は同じ
  • TCP ではなく UDP
  • QUIC 前提になっている
  • TLS は QUIC に組み込まれている
  • stream は QUIC が多重化

7 of 23

HTTP/3 概念図

7

  • endpoint 間で connection を貼る
  • リクエストとレスポンスを双方向の request stream で送受信(一回で close)
  • frame 単位で HTTP メッセージをやり取り
  • control stream で制御用 frame を送れる
  • push stream で Server Push ができる
  • encoder / decoder stream は QPACK 用

8 of 23

コネクションの確立

  • Server が Alt-Svc ヘッダをレスポンスに付与して HTTP/3 対応を示す
    • 例) Alt-Svc: h3=":50781" (UDP 50781 番ポートで h3 を利用可能)
      • HTTP/2 ALTSVC Frame, HTTPVSSVC でも指定可能
  • クライアントは一度 HTTP/1.1 か HTTP/2 で通信

8

9 of 23

フレーム一覧

  • 8 種類のフレームが存在し、送信可能な Stream が違う

9

HTTP ボディ用の Frame

HTTP ヘッダ用の Frame

Server Push キャンセル用の Frame

コネクション設定用の Frame

サーバ Push 用の Frame

コネクション切断用の Frame

Push ID の上限を知らせる用の Frame

予約された Frame

10 of 23

HTTP Fields

  • HTTP/2 と同様に Pseudo-header fields を持っている (CONNECT 以外)
    • request
      • :method : HTTP メソッド
      • :scheme : http や https などのスキーマ
      • :authority : ホストとポート。Host ヘッダフィールドの代わりに使われるべき
      • :path : パス
    • response
      • :status : ステータスコード

10

11 of 23

コネクションのクローズ

  • Idle Connections
    • 長い時間パケットを受信しない場合にクローズされる
  • Connection Shutdown
    • 正常な流れのクローズ。GOAWAY Frame を送ることによってクローズできる
  • Immediate Application Closure
    • HTTP/3 の実装がなんらかの理由で接続終了を伝える
  • Transport Closure
    • QUIC 側のエラーによってこれ以上通信できないときのエラー

11

※ HTTP/2 のときはパケロスでコネクションがうまく閉じられないことがあった

12 of 23

QPACK

12

13 of 23

QPACK

  • HTTP/3 において Fields を圧縮する方法を定める仕様
  • HTTP/2 では Fields を圧縮するのは HPACK
    • HTTP/3 で HPACK をそのまま使わないのは、head of line blocking が発生するため
    • HPACK はフレームの到着順序が保証されている前提
    • HTTP/3 では全 stream で見るとフレームの到着順は保証されない
      • (stream 内では到着順は保証されている)
    • HPACK はそのまま使えないので QPACK が策定された

13

14 of 23

Fields を圧縮する方法

  • HPACK でも利用していた下記を使う
    • ハフマン符号化
    • リファレンステーブル
      • 静的テーブル
      • 動的テーブル

14

15 of 23

ハフマン符号化

  • 出現確率が高い文字順にデータ量が少ない符号を割り当てる
    • QPACK の場合、ハフマン符号のテーブルは HPACK と同じものを利用
    • 大規模な HTTP 通信の統計をもとに策定されたもの

15

Appendix B. Huffman Code より抜粋

16 of 23

ハフマン符号を使う際の注意点

  • ハフマン符号を用いるからと言って必ず短くなるとは限らない
  • HEADERS フレームの H フラグでハフマン符号を使うか選ぶ

16

図: ビット長が長くなる記号の一例

図: Field Line のワイヤフレームの一例

17 of 23

静的テーブル | リファレンステーブル

  • QPACK の仕様であらかじめ規定されている field name と field value の組
    • 実際のインターネット通信で利用頻度が多いヘッダをリストアップ
    • 利用頻度が多い Index ほど小さい数字

17

図: Field Line のワイヤフレームの一例

18 of 23

動的テーブル | リファレンステーブル (1/2)

  • エンコード命令を使って動的にエントリを追加する
    • HEADERS フレームで動的テーブルのエントリ追加しない
    • encoder stream で別途命令を送信することで HEADERS フレームの到着順に依存しない

18

19 of 23

動的テーブルの具体例 | リファレンステーブル (2/2)

19

  • encoder stream でエントリを追加
  • 動的テーブル更新
  • decoder が追加できたことを通知する
  • request stream で HEADERS frame を送る
  • decoder 側が処理できたことを示す �Section Acknowledgement を返す
  • decoder 側が HTTP response を返す

20 of 23

まとめ

  • HTTP/3
    • UDP ベースの QUIC を使う
    • 多数の stream と Frame を使う
    • コネクションのクローズもきちんとされるようにクローズの仕組みを策定
  • QPACK
    • ハフマン符号とリファレンステーブルを使う点は HAPCK 同じ
    • encoder / decoder stream を使って動的テーブルを管理し、フレーム到着順に依存しない

20

HTTP_3_and_QPACK…

21 of 23

参考資料など

21

HTTP_3_and_QPACK…

22 of 23

補足: なぜ 4N なのか

  • QUIC の stream の ID が client-initiated で双方向な stream は末尾が 0
    • 0x1 - 0x3 もそれぞれ決まっている
  • なので 0, 4, 8 と増えていく

22

23 of 23

ハフマン符号化

  • 出現確率が高い文字順にデータ量が少ない符号を割り当てる

23

文字

回数

符号

A

3

10

B

2

110

C

1

111

D

4

0

例) AAABBCDDDD というデータを元にハフマン符号を作ると

1000001100000110000011000010100001010000111000100100010010001001000100 (80bit)�→1010101101101110000 (19bit)