HTTP2.0におけるヘッダ圧縮 Binary Optimized Header Encoding

この記事は古いです。
HTTP2は、HPACKというヘッダ圧縮方式が採用されています。(2016/06/24)


HTTP2.0におけるヘッダ圧縮

HTTP2.0の大きなテーマとしてヘッダ圧縮が挙げられる。

HTTP1のヘッダには非効率な点が二つる

  • 同一のヘッダを何回も送信する(User-Agentなど)
  • テキスト形式でしか送信できず効率が悪い

一つ目に関しては、User-AgentやAcceptヘッダ等は値が変わらないにも関わらず何回も送信し、非常に効率が悪かった。そこで、値が変更になったヘッダのみを送信するDelta Compressionが提案されている。(仕様URL)


二つ目に関しては、Dateヘッダといった時間を示すヘッダや、Cookieのsecure属性といった本来フラグで表せる値について効率化を行うための提案がいくつか考えられている。


Binary Optimized Header Encoding

その一つである、Binary Optimized Header Encoding(仕様URL)
では、辞書形式の圧縮、バイナリ値、UTF-8の使用が提案されている。


ヘッダーは3種類に分類される。

  1. ヘッダー名と値のペア両方が辞書に登録されている
  2. ヘッダー名のみ辞書に登録されている
  3. ヘッダー名が辞書に登録されていない

辞書

辞書は、以下のような形で表現される(例)

ID ヘッダ名 value
0 date
1 :scheme
2 :scheme http
3 :scheme https
4 :scheme ftp
5 :method
6 :method get

1のタイプ

1のタイプは

00 フラグ 辞書ID

の形式で表される。


最初の00は1のタイプであることを示す。
フラグは使用されない。
辞書IDは辞書に登録されているIDを示す。

2のタイプ

2のタイプ

01 フラグ 辞書ID 値の長さ

の形式で表される。


最初の01は2のタイプであることを示す。
フラグは後述。
辞書IDは辞書に登録されているIDを示す。
あとはヘッダの値の長さとその値が格納される。

3のタイプ

3のタイプ

10 フラグ ヘッダ名 ヘッダ名 値の長さ

の形式で表される。


最初の10は3のタイプであることを示す。
フラグは後述。
あとはヘッダ名とその値が長さとともに格納される。

フラグ

フラグはヘッダの値についての情報が格納される。
フラグは6ビットで構成され、それぞれ上位ビットから

  1. 1のときはバイナリ値、0のときはテキスト値。
  2. 1のときはUTF-8、0のときはISO-8859-1。(テキスト値のときのみ使用する)
  3. 1のときはHuffmanエンコードを使用する。(テキスト値のときのみ使用する)
  4. 1のときはヘッダ値が数値であることを示す。
  5. 1のときはヘッダ値が日時であることを示す。
  6. 予約

ヘッダ 圧縮値
:method=GET 00 06
:method=foo 01 76 05 05 00 03 66 6F
foo=bar b6 03 66 6f 6f 05 00 03 62 61 72