でこてっくろぐ ねお

UbieのSRE。でこらいふろぐ(http://dekolife.hatenablog.com/)の姉妹版。デコテックログ(deko tech log)である

HTTP/3のQPACKに至るHTTPのヘッダ圧縮の流れメモ(Real World HTTPを読んで

Real World HTTP ミニ版を読んでいてSPDY, HTTP/2, HTTP/3におけるHTTPヘッダ圧縮について触れられていた。 このエントリではそこを深掘りし、SPDYのDeflateに始まるHTTPのヘッダ圧縮がどのようにHTTP/3のQPACKにつながっているかを書く。(これで正しいのか誰か教えてほしい

SPDY時代: Deflate

SPDYのDeflateは部分文字列一致で圧縮した後にハフマン符号化によって圧縮する。 部分文字列一致による圧縮であるため、一部でも文字列が合致した組があると圧縮されるということから、リクエストを1バイトずつ内容を変えて送信し、フレームの長さを見ることで内容を推測するようなCRIME攻撃に弱かったため、圧縮機能は非推奨となった(という認識だけど正しい?

HTTP/2時代: HPACK

HPACKはヘッダ名もしくはヘッダの値に対する完全一致でハフマン符号化による圧縮を行うためCRIME攻撃への弱さは克服している。 事前に定義された静的な辞書と動的な辞書を使っており、動的な辞書は送信側が投げる順番で受信側がヘッダを受け取ることを想定した作りとなっている。TCPの条件下ではこれは守られるが、HTTP/3のようにTCPを使わずストリーム内においてのフレームの順序さえ守られてさえいればいいという制約化(=別ストリームのフレーム同士は送信順に関係なく受信されうる)においては、動的な辞書の内容が送信側と受信側で一致するという確証が持てないため使えない。もしなんらかの方法でそれを直列化するような実装にした場合、せっかくストリーム単位での順序制御にしてHead of Line Blockingを減らそうとしているのにHPACKのためにBlockingが発生してしまうことになる。

HTTP/3時代: QPACK

上記HPACKをHTTP/3上で使う場合に発生する問題を解決するために、辞書の追加時はキーと値の情報をやり取りし、削除はお互いが同意をとって実施することで若干圧縮率を犠牲にしつつ、順序に依存しないQPACKとなった。 これにより、順序を守る必要はなくなったためストリーム単位でのフレームの順序制御にも大きなブロッキングが起きず使えるようになった。 ただし、別フレームで追加されたキーが参照された際は、ブロッキングが起きる。これを防ぐため、別ストリームでそれぞれ同じキーの追加を行ってもいいとかなんとか(詳しくない

終わりに

というわけで、関連知識を深掘りしそれを本エントリにまとめたのはいいんだけど、まとめ直した後に再度Real Workd HTTPミニ版の該当箇所を読んだところ、かなりの割合でこのエントリがReal Workd HTTPミニ版に載っていることの劣化版焼き直しになってしまっていることに気付いてしまった…。改めて、書籍ってすごいなと思ったが、私の学びの記録として本エントリはおいておく。 皆は、このエントリ読まずにReal Workd HTTP読めばいいと思う。 まぁ、このエントリを読むと、パッと見で時系列がある程度分かる、という利点はある。

2019/04/08 18:05 追記 よくみたらこのエントリのpublishの少し前に以下のような、このエントリの上位互換のようなエントリが出ていた。皆はこちらをみたほうが幸せかもしれない。 HTTP/3のヘッダ圧縮仕様QPACKについて - ASnoKaze blog

本エントリにあたって参考にした文献

Deflateについて

CRIMEについて

HPACKについて

QPACKについて