この文書は古くなっています。
HTTP/2のヘッダ圧縮の仕組みはHPACKとしてRFC 7541で標準化されました。下記説明と大分違うものです。
SPDY/3のコピーから始まったHTTP2.0だが、ヘッダの圧縮についても大きく変更が加えられた。
SPDYでは辞書付きのdeflate圧縮方式を使用していたが、CRIME攻撃の存在や、CPUリソースの消費の観点より、別の手法を取ることが決定されていた。
幾つかの仕様が提出され、議論が重ねられ、現在HTTP2.0 draft04では「HTTP/2.0 Header Compression」(URL)という仕様がリファレンスに挙げられている。
現在の「HTTP/2.0 Header Compression」はHeader Diffと言う仕様が元になっていて、以下の2つの特徴を持つ。
- HTTPで一般的によく使用されるヘッダ(accept-charset、user-agent等)は、辞書情報(Header Table)のindexを用いて送信できる。
- 1つのコネクション中では、一つ前に送ったヘッダの差分のみを送信する。これにより、同じようなヘッダを毎回送る必要が無くなった。
次に、Header TableとReference Setの説明を行う。
Header Table
Index、Header Name、Header Valueからなる表である。クライアントとサーバ間でそれぞれ保持されており、HTTPリクエスト、HTTPレスポンスでよく使用されるヘッダが事前に入っている(仕様で決められている)。テーブルにないヘッダも、送信するごとにこのテーブルにもそのデータが追加されていく(オプションで指定される)。
初期値は以下のようなデータである。
Index | Header Name | Header Value |
---|---|---|
0 | :scheme | http |
1 | :scheme | https |
2 | :host | |
3 | :path | / |
4 | :method | GET |
5 | accept | |
… | … | … |
34 | te | |
35 | upgrade | |
36 | via | |
37 | warning |
送りたいヘッダがこのHeader Tableにあった場合は、indexを指定してヘッダを送ることが出来る。
- Header NameとHeader Valueの両方がマッチしていれば、indexだけを送信する
- Header Nameのみマッチしていれば、indexとvalueだけを送信する
- Header Nameがマッチしなければ、nameとvalue両方を送信する
Reference Set
クライアントとサーバ間でそれぞれ保持している。送信されたHTTPヘッダの情報が格納される(最初は空)。次のHTTPリクエストを送信する際は、このReference Setの差分のみを送信すれば良くなる。
例
一度目に以下のヘッダを送信する場合
:path /my-example/index.html user-agent my-user-agent x-my-header first
- :path はHeader Tableにあるので、index=3,value=/my-example/index.htmlという情報を送る
- user-agentは同様に index=12,value=my-user-agentという情報を送る
- x-my-headerは name=x-my-header,value=firstという情報を送る
この時のReference Setは以下のようになっている(クライアントとサーバでそれぞれ保持している)
:path, /my-example/index.html user-agent, my-user-agent x-my-header, first
又、ヘッダを付加する際にHeader Tableへも追加されており(オプションで指定可能)、Header Tableは以下のようになる。
0 | :scheme | http |
1 | :scheme | https |
... | ... | ... |
37 | warning | |
38 | :path | /my-example/index.html |
39 | user-agent | my-user-agent |
40 | x-my-header | first |
なので、二度目に以下のヘッダを送信する場合
:path /my-example/resources/script.js user-agent my-user-agent x-my-header second
- Reference Setより「:path, /my-example/index.html」と「x-my-header, first」を削除(それぞれ1byteで指定出来る)という情報を送る
- :path はid=38,value=/my-example/resources/script.jsという情報を送る
- x-my-header はid=40,value=secondという情報を送る
この時のReference Setは以下のようになっている
:path, /my-example/resources/script.js user-agent, my-user-agent x-my-header, second