$30 off During Our Annual Pro Sale. View Details »

HTTP/3 と QUIC について

bokken
November 24, 2022

HTTP/3 と QUIC について

HTTP/3 の RFC が publish されたことに合わせて、HTTP/3 と QUIC について紹介します。

bokken

November 24, 2022
Tweet

Other Decks in Programming

Transcript

  1. HTTP/3 and QPACK @bokken HTTP RFC Publication Study 1

  2. About me • Name: bokken • Twitter: @bokken_ • GitHub:

    @negibokken • Like: ◦ ブラウザ ▪ レンダリングエンジンからミニ自作ブラウザを作った ▪ Chromium Contributor として頑張りたい 2
  3. もくじ (持ち時間10分) • HTTP/3 • QPACK 3

  4. HTTP/3 4

  5. 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. HTTP/3 と HTTP/2, HTTP/1.1 の比較 6 ※図の引用元: https://twitter.com/programmingart/status/1533915149827964928 • IP

    層は同じ • TCP ではなく UDP • QUIC 前提になっている • TLS は QUIC に組み込まれている • stream は QUIC が多重化
  7. HTTP/3 概念図 7 • endpoint 間で connection を貼る • リクエストとレスポンスを双方向の

    request stream で送受信(一回で close) • frame 単位で HTTP メッセージをやり取り • control stream で制御用 frame を送れる • push stream で Server Push ができる • encoder / decoder stream は QPACK 用
  8. コネクションの確立 • Server が Alt-Svc ヘッダをレスポンスに付与して HTTP/3 対応を示す ◦ 例)

    Alt-Svc: h3=":50781" (UDP 50781 番ポートで h3 を利用可能) ▪ HTTP/2 ALTSVC Frame, HTTPVSSVC でも指定可能 • クライアントは一度 HTTP/1.1 か HTTP/2 で通信 8
  9. フレーム一覧 • 8 種類のフレームが存在し、送信可能な Stream が違う 9 HTTP ボディ用の Frame

    HTTP ヘッダ用の Frame Server Push キャンセル用の Frame コネクション設定用の Frame サーバ Push 用の Frame コネクション切断用の Frame Push ID の上限を知らせる用の Frame 予約された Frame
  10. HTTP Fields • HTTP/2 と同様に Pseudo-header fields を持っている (CONNECT 以外)

    ◦ request ▪ :method : HTTP メソッド ▪ :scheme : http や https などのスキーマ ▪ :authority : ホストとポート。Host ヘッダフィールドの代わりに使われるべき ▪ :path : パス ◦ response ▪ :status : ステータスコード 10
  11. コネクションのクローズ 11 • Idle Connections ◦ 長い時間パケットを受信しない場合にクローズされる • Connection Shutdown

    ◦ 正常な流れのクローズ。 GOAWAY Frame を送ることによってクローズできる • Immediate Application Closure ◦ HTTP/3 の実装がなんらかの理由で接続終了を伝える • Transport Closure ◦ QUIC 側のエラーによってこれ以上通信できないときのエラー ※ HTTP/2 のときはパケロスでコネクションがうまく閉じられないことがあった
  12. QPACK 12

  13. QPACK 13 • HTTP/3 において Fields を圧縮する方法を定める仕様 • HTTP/2 では

    Fields を圧縮するのは HPACK ◦ HTTP/3 で HPACK をそのまま使わないのは、 head of line blocking が発生するため ◦ HPACK はフレームの到着順序が保証されている前提 ◦ HTTP/3 では全 stream で見るとフレームの到着順は保証されない ▪ (stream 内では到着順は保証されている ) ◦ HPACK はそのまま使えないので QPACK が策定された
  14. Fields を圧縮する方法 • HPACK でも利用していた下記を使う ◦ ハフマン符号化 ◦ リファレンステーブル ▪

    静的テーブル ▪ 動的テーブル 14
  15. ハフマン符号化 • 出現確率が高い文字順にデータ量が少ない符号を割り当てる ◦ QPACK の場合、ハフマン符号のテーブルは HPACK と同じものを利用 ◦ 大規模な

    HTTP 通信の統計をもとに策定されたもの 15 ※Appendix B. Huffman Code より抜粋
  16. ハフマン符号を使う際の注意点 • ハフマン符号を用いるからと言って必ず短くなるとは限らない • HEADERS フレームの H フラグでハフマン符号を使うか選ぶ 図: ビット長が長くなる記号の一例

    図: Field Line のワイヤフレームの一例 16
  17. 静的テーブル | リファレンステーブル • QPACK の仕様であらかじめ規定されている field name と field

    value の組 ◦ 実際のインターネット通信で利用頻度が多いヘッダをリストアップ ◦ 利用頻度が多い Index ほど小さい数字 図: Field Line のワイヤフレームの一例 17
  18. 動的テーブル | リファレンステーブル (1/2) • エンコード命令を使って動的にエントリを追加する ◦ HEADERS フレームで動的テーブルのエントリ追加しない ◦

    encoder stream で別途命令を送信することで HEADERS フレームの到着順に依存しない 18
  19. 動的テーブルの具体例 | リファレンステーブル (2/2) 19 • encoder stream でエントリを追加 •

    動的テーブル更新 • decoder が追加できたことを通知する • request stream で HEADERS frame を送る • decoder 側が処理できたことを示す Section Acknowledgement を返す • decoder 側が HTTP response を返す
  20. まとめ 20 • HTTP/3 ◦ UDP ベースの QUIC を使う ◦

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

    QPACK: Field Compression for HTTP/3 • HTTP/3の解説を書いた (2020/06/01) - ASnoKaze blog • QUIC Tutorial • 『くいっく』HTTP/3編 (無料体験版有り) - 猫耳堂 - BOOTH • QUIC をゆっくり解説シリーズ | IIJ Engineers Blog • HTTP/3 explained 21 HTTP_3_and_QPACK…
  22. 補足: なぜ 4N なのか • QUIC の stream の ID

    が client-initiated で双方向な stream は末尾が 0 ◦ 0x1 - 0x3 もそれぞれ決まっている • なので 0, 4, 8 と増えていく 22
  23. ハフマン符号化 • 出現確率が高い文字順にデータ量が少ない符号を割り当てる 文字 回数 符号 A 3 10 B

    2 110 C 1 111 D 4 0 例) AAABBCDDDD というデータを元にハフマン符号を作ると 1000001100000110000011000010100001010000111000100100010010001001000100 (80bit) →1010101101101110000 (19bit) 23