本文書は RFC7541 "HPACK: Header Compression for HTTP/2" の日本語訳です。
正確性が保証されているものではありません。原文に目を通すことを推奨いたします。
また、日本語訳の修正は GitHubの日本語訳リポジトリ にて受け付けています。

最終更新日: 2015/11/03
翻訳者: Ryo Okubo
翻訳協力: flano-yuki, Jxck

HPACK: HTTP/2 のためのヘッダ圧縮

概要

この仕様書は HTTP/2 で使われる HTTP ヘッダフィールドを効率的に表現する圧縮フォーマット HPACK を定義します。

このメモの状態

これは Internet Standards Track 文書です。

この文書は Internet Engineering Task Force (IETF) の成果物です。 これは、IETF コミュニティの合意を表現するものであり、公開の査読を受け、Internet Engineering Steering Group (IESG) により発行が承認されました。 Internet Standards に関するさらなる情報は RFC 5741 の2章に記述されています。

この文書の現在の状態やエラッタ、フィードバックの提供方法についての情報は http://www.rfc-editor.org/info/rfc7541. で参照できます。

著作権表示

Copyright © 2015 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.


目次

1. はじめに

HTTP/1.1 ([RFC7230] を参照) において、ヘッダフィールドは圧縮されません。 Web ページは 12 から数百のリクエストを含むようになってきており、これらのリクエストの中の余分なヘッダフィールドは不必要に帯域を消費し、レイテンシを大きく増加します。

SPDY [SPDY] は最初、余分なヘッダフィールドを効率的に表現することで非常に効率的にする DEFLATE [DEFLATE] フォーマットを使用してヘッダフィールドを圧縮することによりこの無駄に取り組みました。しかしながら、このアプローチは CRIME (Compression Ratio Info-leak Made Easy) 攻撃で実証された通りセキュリティリスクがあります。 ([CRIME]を参照)

この仕様書は余分なヘッダフィールドを消去し、既知のセキュリティ攻撃への脆弱性を抑制し、そして制限された環境で使用する制限されたメモリ要求を持つヘッダフィールドの新しい圧縮方式 HPACK を定義します。 HPACK の潜在的なセキュリティへの懸念は Section 7 に記述します。

HPACK のフォーマットは意図的にシンプルで柔軟性を欠かせています。この二つの特徴によって実装の誤りによる相互運用性とセキュリティイシューのリスクを減らします。拡張メカニズムは定義されていません。フォーマットの変更は完全な代替仕様の定義によってのみ成り立ちます。

1.1 概要

この仕様で定義されるフォーマットはヘッダフィールドのリストを重複可能な名前と値のペアの順序付けられたコレクションとして扱います。名前と値は不透明なオクテットの並びになることを考慮し、ヘッダフィールドの順序は圧縮と展開の後で保存されます。

エンコーディングはヘッダフィールドとインデックスされた値をマップするヘッダフィールドテーブルによって決まります。これらのヘッダフィールドテーブルは、新しいフィールドをエンコードもしくはデコードする時に増分更新を行えます。

エンコードされた形式内で、ヘッダフィールドはリテラルもしくはヘッダフィールドテーブル内の一つのヘッダフィールドへの参照として表現されます。従って、ヘッダフィールドのリストは参照とリテラル値を混ぜ合わせてエンコードできます。

リテラル値は直接エンコードされるか静的なハフマン符号を使います。

エンコーダはヘッダフィールドテーブルに新しいエントリとして挿入するヘッダフィールドを決定する責任があります。デコーダはエンコーダによって定められたヘッダフィールドテーブルに対する修正を行い、その処理内でヘッダフィールドのリストを再構築します。これによりデコーダをシンプル化し、非常に様々なエンコーダと相互運用可能にすることができます。

ヘッダフィールドを表現するためのこれらの異なったメカニズムの使用を解説する例は Appendix C にあります。

1.2 表記

この文書のキーワード "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", そして "OPTIONAL" は RFC 2119 [RFC2119] に記述された通りに解釈されます。

全ての数値はネットワークバイトオーダーです。特に断りが無い限り値は符号なしです。リテラルの値は必要に応じて 10 進数または 16 進数で与えられます。

1.3 用語

この仕様は下記の用語を使用します:

ヘッダフィールド:
名前と値のペア。名前と値どちらも不定なオクテットの連続として扱われます。
動的テーブル:
動的テーブル (Section 2.3.2 を参照) は保存されたヘッダフィールドとインデックス値を関連付けるのに使用されるテーブルです。このテーブルは動的でエンコーディングやデコーディングのコンテキスト特有です。
静的テーブル:
静的テーブル(Section 2.3.1 を参照) は頻繁に使われるヘッダフィールドとインデックス値を静的に関連づけるテーブルです。このテーブルは順序付けられ、リードオンリーであり、常にアクセス可能で、すべてのエンコーディングやデコーディングのコンテキストの間で共有される可能性があります。
ヘッダリスト:
ヘッダリストは一緒にエンコードされるヘッダフィールドの順序付けられたコレクションであり、重複したヘッダフィールドを含むことができます。 HTTP/2 ヘッダブロックに含まれるヘッダフィールドの完全なリストがヘッダリストです。
ヘッダフィールド表現:
ヘッダフィールドはリテラルかインデックスのどちらかのエンコードされた形式で表現できます。 (Section 2.4 を参照)
ヘッダブロック:
デコード時に完全なヘッダリストを提供するヘッダフィールド表現の順序付けられたリストです。

2. 圧縮処理の概要

この仕様ではエンコーダの為の特定のアルゴリズムについては記述しません。代わりに、デコーダがどう処理することが期待され、この定義で許されるエンコーディングを行う為にエンコーダに許されることを正確に定義します。

2.1 ヘッダリストの順序

HPACK はヘッダリスト内のヘッダフィールドの順序を保存します。エンコーダはオリジナルのヘッダリスト内の順序に従ってヘッダブロックのヘッダフィールド表現を順序付けなければなりません (MUST) 。デコーダはヘッダブロック内の順序によってデコードされたヘッダリストのヘッダフィールドを順序付けなければなりません (MUST) 。

2.2 エンコーディングとデコーディングのコンテキスト

ヘッダブロックを展開するため、デコーダはデコーディングコンテキストとして動的テーブル (Section 2.3.2 を参照) の管理のみを必要とします。他に必要な状態はありません。

HTTP のような双方向コミュニケーションに使用される際、エンコーディングとデコーディングの動的テーブルは完全に独立したエンドポイントによって管理されます。例えば、リクエストとレスポンスの動的テーブルは分離されます。

2.3 インデックステーブル

HPACK はヘッダフィールドとインデックスを関連付ける二つのテーブルを使用します。静的テーブル (Section 2.3.1 を参照) は予め定義されており、 (ほとんどは空の値を持った) よく使用されるヘッダフィールドを持ちます。動的テーブル (Section 2.3.2 を参照) は動的であり、エンコーダによってエンコードされたヘッダリスト内で繰り返し使用されるヘッダフィールドを指すのに使用できます。

これら二つのテーブルはインデックス値の定義のため単一のアドレス空間内で結合されます。 (Section 2.3.3 を参照)

2.3.1 静的テーブル

静的テーブルは予め定義されたヘッダフィールドの静的リストで構成されます。このエントリは Appendix A で定義されます。

2.3.2 動的テーブル

動的テーブルは先入先出順で管理されるヘッダフィールドのリストで構成されます。動的テーブルの最初であり最新のエントリは最小のインデックスに、最古のエントリは最大のインデックスになります。

動的テーブルは最初は空です。各ヘッダブロックとして追加されるエントリは展開されています。

動的テーブルは重複するエントリ(例えば、同じ名前と同じ値を持つエントリ)を持つことができます。従って、重複したエントリはデコーダによってエラーとして扱われてはいけません (MUST NOT) 。

エンコーダは動的テーブルの更新のしかたを決定するので、動的テーブルに使用されるメモリ量を制御することができます。デコーダのメモリ要件を制限するために、動的テーブルサイズは厳密に束縛されます (Section 4.2 を参照) 。

ヘッダフィールド表現のリストの処理中にデコーダは動的テーブルを更新します。(Section 3.2 を参照)

2.3.3 インデックスアドレス空間

静的テーブルと動的テーブルは単一のインデックスアドレス空間内で結合されます。

1 から静的テーブルの長さの間の指定は静的テーブル内の要素を参照します (Section 2.3.1 を参照) 。

静的テーブルの長さより大きい指定は動的テーブル (Section 2.3.2 を参照) 内の要素を参照します。静的テーブルの長さは動的テーブルのインデックスを検索するため差し引かれます。

両方のテーブルの長さの合計値より大きい指定はデコードエラーとして扱われなければなりません (MUST) 。

静的テーブルサイズ s 、動的テーブルサイズ k として、下記の図は全体の有効なインデックスアドレス空間を示しています。

        <----------  Index Address Space ---------->
        <-- Static  Table -->  <-- Dynamic Table -->
        +---+-----------+---+  +---+-----------+---+
        | 1 |    ...    | s |  |s+1|    ...    |s+k|
        +---+-----------+---+  +---+-----------+---+
                               ^                   |
                               |                   V
                        Insertion Point      Dropping Point

図 1: インデックスアドレス空間

2.4 ヘッダフィールド表現

エンコードされたヘッダフィールドはインデックスもしくはリテラルで表現できます。

インデックス表現はヘッダフィールドを静的テーブルもしくは動的テーブルのエントリへの参照として定義します。 (Section 6.1 を参照)

リテラル表現は名前と値を指定することでヘッダフィールドを定義します。ヘッダフィールド名はリテラル、もしくは静的テーブルまたは動的テーブルのエントリへの参照として表現できます。ヘッダフィールド値はリテラルで表現されます。

3 つの異なるリテラル表現は下記のように定義されます:

  • ヘッダフィールドを新しいエントリとして動的テーブルの先頭に追加するリテラル表現 (Section 6.2.1 を参照) 。
  • 動的テーブルへのヘッダフィールドの追加を行わないリテラル表現 (Section 6.2.2 を参照) 。
  • 特に中継者に再エンコードされる際に、ヘッダフィールドが常にリテラル表現を使用するような追加条件を伴う、動的テーブルへのヘッダフィールドの追加を行わないリテラル表現 (Section 6.2.3 を参照) 。この表現は圧縮によって危険にさらされないようヘッダフィールド値を保護することを意図しています。 (詳細については Section 7.1.3 を参照) 。

3 つの表現から 1 つを選択するのは、センシティブなヘッダフィールド値を保護するため、セキュリティ上の理由から導くことができます (Section 7.1 を参照) 。

ヘッダフィールド名とヘッダフィールド値のリテラル表現はそのままのものか静的ハフマン符号 (Section 5.2 を参照) を用いたもののどちらかのオクテットの並びでエンコードできます。

3. ヘッダブロックのデコード処理

3.1 ヘッダブロック処理

デコーダはオリジナルのヘッダリストを逐次的に再構成することでヘッダブロックを処理します。

ヘッダブロックはヘッダフィールド表現を連結したものです。含められるヘッダフィールド表現の違いは Section 6 で説明します。

いったんヘッダフィールドがデコードされ再構成されたヘッダリストに追加されたら、そのヘッダフィールドは削除することはできません。ヘッダリストに追加されたヘッダフィールドはアプリケーションに安全に渡されます。

アプリケーションに結果のヘッダフィールドを渡すことで、デコーダは動的テーブルが必要とするのとは別の一時的なメモリ消費を最低限にして実装できます。

3.2 ヘッダフィールド表現の処理

ヘッダリストを得るためのヘッダブロックの処理をこの節で定義します。デコード処理でうまくヘッダリストを生成することを確実にするため、デコーダは下記の規則に従わなければなりません (MUST) 。

ヘッダブロックに含まれるすべてのヘッダフィールド表現は下記に示す通り、現れた順に処理されます。様々なヘッダフィールド表現のフォーマットの詳細と、追加の処理命令は Section 6 にあります。

インデックス表現 は 下記のアクションを伴います:

  • 静的テーブルもしくは動的テーブルの参照されるエントリに対応するヘッダフィールドをデコード済みヘッダリストに追加する。

動的テーブルに 追加されていない リテラル表現 は下記のアクションを伴います:

  • ヘッダフィールドをデコード済みヘッダリストに追加する。

動的テーブルに 追加されている リテラル表現 は下記のアクションを伴います:

  • ヘッダフィールドをデコード済みヘッダリストに追加する。
  • ヘッダフィールドは動的テーブルの先頭に挿入されます。この挿入処理は動的テーブルの以前のエントリの削除を引き起こす可能性があります (Section 4.4 を参照) 。

4. 動的テーブルの管理

デコーダ側のメモリ要件を制限するため、動的テーブルはサイズが制限されます。

4.1 テーブルサイズの計算

動的テーブルのサイズはそのエントリのサイズの合計値です。

エントリのサイズはその名前のオクテットの長さ (Section 5.2 で定義される通り) と値のオクテットの長さに 32 を加えた合計値です。

エントリのサイズはハフマンエンコーディングの適用無しの名前と値の長さで計算されます。

  • 注意: エントリに関連付くオーバーヘッドとして追加の 32 オクテットを付加します。例として、エントリの名前と値を参照するための 2 つの 64 ビットポインタと、名前と値への参照数を数える 2 つの 64 ビット整数を使うエントリ構造は 32 オクテットのオーバーヘッドを持ちます。

4.2 最大テーブルサイズ

HPACK を使用するプロトコルは、エンコーダが動的テーブルに使用することが許可される最大サイズを決定します。 HTTP/2 において、この値は SETTINGS_HEADER_TABLE_SIZE 設定 ([HTTP2] の 6.5.2 節を参照) で決定されます。

エンコーダはこの最大値より小さな容量を使用することを選択することが可能です (Section 6.3 を参照) が、その値はプロトコルによって設定された最大値以下に留めなければなりません (MUST) 。

動的テーブルの最大サイズの変更は動的テーブルサイズ更新 (Section 6.3 を参照) から通知されます。この動的テーブルサイズ更新は動的テーブルサイズの変更の後に最初のヘッダブロックの先頭が続かなければなりません (MUST) 。 HTTP/2 において、これは設定同期 ([HTTP2] の 6.5.3 節を参照) で追従します。

二つのヘッダブロックの送信の間に複数のテーブルサイズの最大値の更新が起こる可能性があります。この場合このサイズはこの区間内に一度以上変更され、区間内に現れた最小の最大テーブルサイズが動的テーブルサイズ更新内で通知されなければなりません (MUST) 。最終的な最大サイズは常に通知され、多くて二つの動的テーブルサイズ更新が引き起こされます。これはデコーダがデコーダテーブルサイズに基づき削除を実行することを可能にするのを確実にします (Section 4.3 を参照) 。

このメカニズムで 0 の最大サイズを設定することで動的テーブルからエントリを完全にクリアして、その後に再格納することができます。

4.3 動的テーブルサイズ変更時のエントリの削除

動的テーブルの最大サイズが減少するたびに、動的テーブルのサイズが最大サイズ以下になるまで動的テーブルの末尾からエントリが削除されます。

4.4 新しいエントリ追加時のエントリの削除

動的テーブルに新しいエントリが追加される前に、動的テーブルのサイズが (最大サイズ - 新しいエントリサイズ) 以下になるかテーブルが空になるまで動的テーブルの末尾からエントリが削除されます。

もし新しいエントリのサイズが最大サイズ以下なら、エントリはテーブルに追加されます。最大サイズより大きいエントリの追加を試みることはエラーにはなりません; 最大サイズより大きなエントリの追加を試みるとすべてのエントリを空にすることになり、テーブルを空にする結果になります。

動的テーブルに新しいエントリを追加する際、そのエントリは削除される可能性のある動的テーブルのエントリの名前を参照する可能性があります。新しいエントリを挿入する前に動的テーブルから参照されるエントリが削除される場合、参照される名前を削除するのを避けるよう実装に注意してください。

5. プリミティブ型表現

HPACK エンコーディングは二つのプリミティブ型を使用します: 符号なしの可変長整数と、オクテットの文字列

5.1 整数表現

整数は名前のインデックス、ヘッダフィールドのインデックスまたは文字列の長さを表現するために使用されます。整数表現はオクテット内のどこからでも開始できます。処理の最適化のため、整数表現は常にオクテットの末尾で終わります。

整数は 2 つのパートで表現されます: 現在のオクテットを埋めるプレフィックスとプレフィックス内に収まらない整数値のため使用されるオクテットのオプションのリスト。プレフィックスのビット数 (N と呼ばれる) はこの整数表現のパラメータです。

整数値が十分小さい、すなわち 2^N-1 未満の場合、 N ビットプレフィックス内にエンコードされます。

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| ? | ? | ? |       Value       |
+---+---+---+-------------------+

図 2: プレフィックス内のエンコードされた整数値 (N = 5 の場合)

そうでない場合、プレフィックスの全てのビットが 1 ならその値は 2^N-1 分減らされ、一個以上のオクテットのリストを使用してエンコードされます。各オクテットの最上位ビットは継続フラグとして使用されます: リストの最終オクテットを除きこの値には 1 がセットされます。残りのオクテットのビットは残った値をエンコードするのに使用されます。

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| ? | ? | ? | 1   1   1   1   1 |
+---+---+---+-------------------+
| 1 |    Value-(2^N-1) LSB      |
+---+---------------------------+
               ...
+---+---------------------------+
| 0 |    Value-(2^N-1) MSB      |
+---+---------------------------+

図 3: プレフィックスの後ろのエンコードされた整数値 (N = 5 の場合)

オクテットのリストからの整数値のデコード処理はリストのオクテットの逆順から開始します。その後、オクテット毎に最上位ビットを除去します。オクテットの残りのビットは連結され、その結果の値は整数値を得るために 2^N-1 分加算されます。

プレフィックスサイズ N は常に 1 から 8 ビットの間です。オクテット境界から開始する整数は 8 ビットプレフィックスを持ちます。

整数 I を表現する擬似コードは下記の通り:

if I < 2^N - 1, encode I on N bits
else
    encode (2^N - 1) on N bits
    I = I - (2^N - 1)
    while I >= 128
         encode (I % 128 + 128) on 8 bits
         I = I / 128
    encode I on 8 bits

整数 I をデコードする擬似コードは下記の通り:

decode I from the next N bits
if I < 2^N - 1, return I
else
    M = 0
    repeat
        B = next octet
        I = I + (B & 127) * 2^M
        M = M + 7
    while B & 128 == 128
    return I

整数のエンコード処理を解説する例は Appendix C.1 にあります。

この整数表現は不定サイズの値が許可されます。エンコーダはゼロ値の巨大な数値を送ることも可能ですが、オクテットを浪費して整数値のオーバーフローを起こす可能性があります。値やオクテットの長さでの過度に巨大な整数のエンコードはデコードエラーとして扱われなければなりません (MUST) 。制限の差異は実装上の制限に基づいて、各々の整数の使用方法の違いに合わせることができます。

5.2 文字列リテラル表現

ヘッダフィールド名とヘッダフィールド値は文字列リテラルで表現できます。文字列リテラルは文字列リテラルのオクテットに直接、もしくはハフマン符号 ([HUFFMAN] を参照) を使用することでオクテットの連続としてエンコードされます。

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| H |    String Length (7+)     |
+---+---------------------------+
|  String Data (Length octets)  |
+-------------------------------+

図 4: 文字列リテラル表現

文字列リテラル表現は下記のフィールドを含みます:

H:
1 ビットフラグ H 。文字列のオクテットがハフマンエンコーディングされているかどうかを示します。
String Length:
文字列リテラルをエンコードするのに使用されたオクテットの数。 7 ビットプレフィックスの整数としてエンコードされます。(Section 5.1 を参照)
String Data:
文字列リテラルのエンコードされたデータ。もし H が '0' なら、エンコードされたデータは文字列リテラルの生のオクテットです。もし H が '1' なら、エンコードされたデータは文字列リテラルをハフマンエンコーディングされています。

ハフマンエンコーディングを使用する文字列リテラルは Appendix B で定義されるハフマン符号でエンコードされます。(リクエストの例として Appendix C.4 を、レスポンスの例として Appendix C.6 を参照) エンコードされたデータは文字列リテラルの各オクテットに対応する符号のビット列です。

ハフマンエンコードされたデータは常にオクテット境界で終わるわけではないので、その後に次のオクテット境界までパディングが挿入されます。このパディングが文字列リテラルの一部だと誤認されることを防ぐため、符号の最上位ビットに EOS (end-of-string) に対応するシンボルが使用されます。

デコーディングにおいて、エンコードされたデータの最後の不完全なコードはパディングだとみなされ、破棄されます。 7 ビットより大きいパディングはデコードエラーとして扱われなければなりません (MUST) 。 EOS シンボルのコードの最上位ビットに対応しないパディングはデコードエラーとして扱われなければなりません (MUST) 。 EOS シンボルを含むハフマンエンコードされた文字列リテラルはデコードエラーとして扱われなければなりません (MUST) 。

6. バイナリフォーマット

この節では様々なヘッダフィールド表現の詳細フォーマットと、加えて動的テーブルサイズ更新命令について記述します。

6.1 インデックスヘッダフィールド表現

インデックスヘッダフィールド表現は静的テーブルまたは動的テーブルのエントリを識別します。(Section 2.3 を参照)

インデックスヘッダフィールド表現は Section 3.2 で記述した通り、デコードされたヘッダリストへのヘッダフィールドの追加を発生させます。

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 1 |        Index (7+)         |
+---+---------------------------+

図 5: インデックスヘッダフィールド

インデックスヘッダフィールドは 1 ビットパターン '1' から開始し、マッチするヘッダフィールドのインデックスが後に続きます。インデックスは 7 ビットプレフィックスの整数として表現されます (Section 5.1 を参照) 。

0 のインデックス値は使用されません。もしインデックスヘッダフィールド表現でこれが見つかった場合、デコードエラーとして扱われなければなりません (MUST) 。

6.2 リテラルヘッダフィールド表現

リテラルヘッダフィールド表現はリテラルヘッダフィールド値を含みます。ヘッダフィールド名はリテラル、もしくは静的テーブルか動的テーブルに存在するテーブルエントリへの参照として与えられます。 (Section 2.3 を参照)

この仕様ではリテラルヘッダフィールド表現の 3 つの形式、インデックスを伴う、インデックスを伴わない、インデックスしないものを定義します。

6.2.1 インデックス更新を伴うリテラルヘッダフィールド

インデックス更新を伴うリテラルヘッダフィールド表現はデコードされたヘッダリストへのヘッダフィールドの追加と動的テーブルへの新しいエントリの挿入を発生させます。

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 0 | 1 |      Index (6+)       |
+---+---+-----------------------+
| H |     Value Length (7+)     |
+---+---------------------------+
| Value String (Length octets)  |
+-------------------------------+

図 6: インデックス更新を伴うリテラルヘッダフィールド - インデックスされた名前

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 0 | 1 |           0           |
+---+---+-----------------------+
| H |     Name Length (7+)      |
+---+---------------------------+
|  Name String (Length octets)  |
+---+---------------------------+
| H |     Value Length (7+)     |
+---+---------------------------+
| Value String (Length octets)  |
+-------------------------------+

図 7: インデックス更新を伴うリテラルヘッダフィールド - 新しい名前

インデックス更新を伴うリテラルヘッダフィールド表現は 2 ビットパターン '01' から開始します。

もし静的テーブルまたは動的テーブルに格納されたエントリのヘッダフィールド名に、ヘッダフィールド名とマッチする場合、ヘッダフィールド名はそのエントリのインデックスを用いて表現できます。この場合、エントリのインデックスは 6 ビットプレフィックスの整数値として表現されます。 (Section 5.1 を参照) この値は常に非ゼロです。

そうでなければ、ヘッダフィールド名が文字列リテラル (Section 5.2 を参照) として表現されます。 6 ビットインデックスの代わりに 0 値が使用され、ヘッダフィールド名が続きます。

どちらのヘッダフィールド名表現の形式も、文字列リテラル (Section 5.2 を参照) として表現されたヘッダフィールド値が続きます。

6.2.2 インデックス更新を伴わないリテラルヘッダフィールド

インデックス更新を伴わないリテラルヘッダフィールド表現は、動的テーブルの変更を伴わずにデコードされたヘッダリストへのヘッダフィールドの追加を引き起こします。

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 |  Index (4+)   |
+---+---+-----------------------+
| H |     Value Length (7+)     |
+---+---------------------------+
| Value String (Length octets)  |
+-------------------------------+

図 8: インデックス更新を伴わないリテラルヘッダフィールド - インデックスされた名前

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 |       0       |
+---+---+-----------------------+
| H |     Name Length (7+)      |
+---+---------------------------+
|  Name String (Length octets)  |
+---+---------------------------+
| H |     Value Length (7+)     |
+---+---------------------------+
| Value String (Length octets)  |
+-------------------------------+

図 9: インデックス更新を伴わないリテラルヘッダフィールド - 新しい名前

インデックス更新を伴わないリテラルヘッダフィールド表現は 4 ビットパターン '0000' から開始します。

もし静的テーブルまたは動的テーブルに格納されたエントリのヘッダフィールド名に、ヘッダフィールド名とマッチする場合、ヘッダフィールド名はそのエントリのインデックスを用いて表現できます。この場合、エントリのインデックスは 4 ビットプレフィックスの整数値として表現されます。 (Section 5.1 を参照) この値は常に非ゼロです。

そうでなければ、ヘッダフィールド名が文字列リテラル (Section 5.2 を参照) として表現されます。 4 ビットインデックスの代わりに 0 値が使用され、ヘッダフィールド名が続きます。

どちらのヘッダフィールド名表現の形式も、文字列リテラル (Section 5.2 を参照) として表現されたヘッダフィールド値が続きます。

6.2.3 インデックスされないリテラルヘッダフィールド

インデックスされないリテラルヘッダフィールド表現は動的テーブルの変更を伴わずにデコードされたヘッダリストへのヘッダフィールドの追加を引き起こします。中継者はこのヘッダフィールドのエンコードに同じ表現を使用しなければなりません (MUST) 。

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 1 |  Index (4+)   |
+---+---+-----------------------+
| H |     Value Length (7+)     |
+---+---------------------------+
| Value String (Length octets)  |
+-------------------------------+

図 10: インデックスされないリテラルヘッダフィールド - インデックスされた名前

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 1 |       0       |
+---+---+-----------------------+
| H |     Name Length (7+)      |
+---+---------------------------+
|  Name String (Length octets)  |
+---+---------------------------+
| H |     Value Length (7+)     |
+---+---------------------------+
| Value String (Length octets)  |
+-------------------------------+

図 11: インデックスされないリテラルヘッダフィールド - 新しい名前

インデックスされないリテラルヘッダフィールド表現は 4 ビットパターン '0001' から開始します。

ヘッダフィールドがインデックスされないリテラルヘッダフィールドとして表現される際、常にこのリテラル表現でエンコードされなければなりません (MUST) 。特に、ピアがインデックスされないリテラルヘッダフィールドとして表現されたヘッダフィールドを受け取ってそれを送信する際、そのヘッダフィールドを転送するのに同じ表現を使用しなければなりません (MUST) 。

この表現は圧縮によるリスクに晒されないようヘッダフィールド値を保護することを意図しています (詳細は Section 7.1 を参照) 。

この表現のエンコーディングはインデクシングを伴わないリテラルヘッダフィールドと同様です (Section 6.2.2 を参照) 。

6.3 動的テーブルサイズ更新

動的テーブルサイズ更新は動的テーブルのサイズの変更を通知します。

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 1 |   Max size (5+)   |
+---+---------------------------+

図 12: 最大動的テーブルサイズの変更

動的テーブルサイズ更新は 3 ビットパターン '001' から開始し、 5 ビットプレフィックスの整数値 (Section 5.1 を参照) として表現される新しい最大値が続きます。

新しい最大値は HPACK を使用するプロトコルによって決められた上限値以下でなければなりません (MUST) 。この上限を超過した値はデコードエラーとして扱われなければなりません (MUST) 。 HTTP/2 において、この上限は デコーダが受け取りエンコーダが知らせた ([HTTP2] の 6.5.3 節を参照) SETTINGS_HEADER_TABLE_SIZE パラメータ ([HTTP2] の 6.5.2 節を参照) の最後の値です。

動的テーブルの最大サイズの減少はエントリの削除を引き起こす可能性があります。 (Section 4.3 を参照) 。

7. セキュリティへの配慮

この節では HPACK の潜在的なセキュリティへの懸念部分について記述します。

7.1 動的テーブルの状態の探り当て

HPACK は HTTP のようなプロトコルに存在する冗長性を排除することによってエンコーディングをされたヘッダフィールドの長さを減らします。これの究極的なゴールは HTTP リクエストやレスポンスを送るために必要なデータの量を減らすことです。

ヘッダフィールドをエンコードするのに使用される圧縮コンテキストは、エンコードし送信するヘッダフィールドを定義できてかつ一旦エンコードされたフィールドの長さを観測できる攻撃者によって探り当てられる可能性があります。攻撃者がどちらも行える際、動的テーブルの状態に関する推測を検証するためにリクエストをうまく修正することが可能です。もし推測した値が短い長さに圧縮されるなら、攻撃者はエンコードされた長さと推測した値が正しいという推量を確認できます。

これは トランスポートレイヤセキュリティ (TLS) プロトコル ( [TLS12] を参照) を用いても起こる可能性があります。なぜなら TLS がコンテンツの秘密保護を提供していても、そのコンテンツの長さに関しては限られた保護のみしか提供されないためです。

  • 注意: パティングスキームはこれらが行える攻撃者に対して、与えらた推測に関連する長さを学習するための推測の増加数にのみ作用するような限られた保護のみ提供します。パディングスキームは送信されるビット数を増加することによって圧縮に対しても直接作用します。

CRIME [CRIME] のような攻撃はこれらの一般的な攻撃者の能力の存在を証明しています。 DEFLATE [DEFLATE] の事実を悪用するこの攻撃はプレフィックスマッチングに基づき冗長性を減らします。これは同時に攻撃者に文字の推測を検証することを許してしまい、指数関数時間の攻撃を線形時間の攻撃にしてしまいます。

7.1.1 HPACK と HTTP への適応性

HPACK は全体のヘッダフィールド値ではなく個々の文字をマッチさせることを推測値に強制することによる CRIME [CRIME] に則った攻撃を緩和はしますが完全な防御はしません。攻撃者は推測値が正しいか否かのみを学習することはできるため、ヘッダフィールド値の総当たり推測に成り下がります。

特定のヘッダフィールド値の復元の実行可能性は、従って値のエントロピーに依存します。結果として、高エントロピーの値はうまく復元される可能性は低くなります。しかしながら低エントロピーの値は弱さが残ります。

この性質の攻撃は一つの HTTP/2 コネクション上で行われる二つの互いに信用できないエンティティ制御リクエストとレスポンスの任意のタイミングで行えます。 もし共有の HPACK エンコーダが一つのエンティティに動的テーブルへのエントリの追加を許可し、他者がそのエントリにアクセスするなら、テーブルの状態を学習できます。

互いに信用できないエンティティからのリクエストとレスポンスがあるのは中継者がどちらかの時です:

  • 複数のクライアントからのリクエストを一つのコネクション上でオリジンサーバに送る、または
  • 複数のオリジンサーバからのレスポンスを共有された一つのコネクション上でクライアントに送る。

web ブラウザも異なる web オリジン [ORIGIN] に対して同じコネクションで作成されるリクエストが互いに信用できないエンティティによって作成されることを仮定する必要があります。

7.1.2 緩和策

ヘッダフィールドの機密性が求められる HTTP のユーザは推測不可能にするのに十分なエントロピーを持つ値を使用することができます。しかしながらこれは実用的な解決方法とはいえません。なぜならすべての HTTP のユーザに攻撃を緩和するためのステップを行うことを強制することになるためです。 HTTP の使用方法に新たな制約を加えることになります。

HTTP のユーザに制約を課すのではなく、代わりに HPACK の実装は動的テーブルの探り当ての可能性を制限するために圧縮方法を制限することができます。

理想的な解決方法は動的テーブルへのアクセスを、ヘッダフィールドを構築するエンティティに基づいて分離することです。テーブルに追加されるヘッダフィールド値はエンティティに属し、その値を作成したエンティティのみが値を抽出できます。

このオプションの圧縮性能を向上するため、信頼しているエンティティは公開状態にタグ付けします。例えば、 web ブラウザは Accept-Encoding ヘッダフィールドの値は全リクエストで使用可能にします。

ヘッダフィールドの起源の良い情報を持たないエンコーダは代わりに多くの異なる値をもつヘッダフィールドに対して、ヘッダフィールド値の推測のための大量の攻撃が起こった際に、更なる推測を効率的に防ぐため、将来のメッセージでそのヘッダフィールドが動的テーブルのエントリと比較されないようにするような処置を行ってもかまいません。

  • 注意: もし攻撃者が値の再入を行える信頼できる経路を持つ場合、動的テーブルからのヘッダフィールドに対応するエントリを単純に削除するのでは不十分である可能性があります。例えば、 web ブラウザにおいて画像を読み込むためのリクエストは典型的に Cookie ヘッダフィールド (この種類の攻撃で価値あるターゲットである可能性が高い) を含み、 web サイトは簡単に画像が読み込まれることを強制できるので、それによって動的テーブルのエントリはリフレッシュされます。

このレスポンスはヘッダフィールド値の長さに反比例する可能性があります。ヘッダフィールドに動的テーブルを使わないようマークすることで、短い値を長い値より素早くかつ高い確率にすることができます。

7.1.3 インデックスされないリテラル

実装は、圧縮せずに代わりにリテラルとして値をエンコードすることでセンシティブなヘッダフィールドを保護することを選ぶこともできます。

ヘッダフィールドのインデックス表現の生成を止めることは、圧縮がすべてのホップで行われない場合のみ影響します。インデックスされないリテラル (Section 6.2.3 を参照) は中継者に特定の値が意図的にリテラルとして送信されたことを通知するのに使用できます。

中継者はインデックスされないリテラル表現を使った値を別のインデックスされる表現で再エンコードしてはいけません (MUST NOT) 。 HPACK が再エンコードに使われる場合、インデックスされないリテラル表現を使わなければなりません (MUST) 。

ヘッダフィールドにインデックスされないリテラル表現を使用する選択は、幾つかの要因に依存します。 HPACK は全体のヘッダフィールド値の推測に対する保護を行わないため、短いかエントロピーの低い値は攻撃者によってより容易に復元しやすくなります。従って、エンコーダは低いエントロピーの値のインデックスを行わないことを選ぶこともできます。

エンコーダは Cookie や Authorization ヘッダフィールドのような、重要でセンシティブなヘッダフィールドの復元を考慮してヘッダフィールドの値のインデックスを行わないことを選ぶこともできます。

対して、エンコーダは公開された値の場合、少しの値をもつもしくは値のないヘッダフィールドの値をインデックスすることを選ぶこともできます。例えば、 User-Agent ヘッダフィールドはリクエスト毎に変化することがなく、任意のサーバに送られます。この場合、特に User-Agent に使われる値の確認は少ない値で与えられます。

これらのインデックスされないリテラル表現の使用の決定基準は新しい攻撃の発見により時間を経て変化する可能性があることに注意してください。

7.2 静的ハフマンエンコーディング

静的ハフマンエンコーディングに対する現在知られている攻撃はありません。静的ハフマンエンコーディングテーブルを用いることが情報漏えいを引き起こすことを示した研究がありますが、攻撃者は意味のある情報を復元するためにこの情報漏えいを利用することはできないと結論付けています ([PETAL] を参照) 。

7.3 メモリ消費

攻撃者はエンドポイントにメモリを使い尽くさせることを試みることができます。 HPACK はエンドポイントで割り当てられたメモリ量のピークと状態を制限するよう設計されています。

エンコーダによって使用されるメモリ量は、動的テーブルの最大サイズの定義を通して HPACK を使用するプロトコルによって制限されます。 HTTP/2 において、この値は設定パラメータ SETTINGS_HEADER_TABLE_SIZE ([HTTP2] を通してデコーダによって制御されます。この制限は動的テーブルに格納されるデータのサイズと、加えてオーバーヘッドへの少しの配慮を考慮しています。

デコーダは動的テーブルの最大サイズとして適切な値を設定することで状態メモリの量を制限できます。 HTTP/2 において、 SETTINGS_HEADER_TABLE_SIZE パラメータに適切な値を設定することで実現されます。エンコーダはデコーダに許可された値未満の動的テーブルサイズを通知することで使用する状態メモリの量を制限できます。 (Section 6.3 を参照)

エンコーダやデコーダで消費される一時メモリ量はヘッダフィールドを連続的に処理することで制限できます。実装はヘッダフィールドの完全なリストを保持する必要はありません。しかしながら他の理由のため完全なヘッダリストを保持することがアプリケーションによっては必要になるかもしれないことに注意してください; HPACK がこれを強制していないにも関わらず、アプリケーションの制限でこれが必要になるかもしれません。

7.4 実装上の制限

HPACK の実装は整数のための巨大な値、整数や長い文字列リテラルのための長いエンコーディングがセキュリティの弱点を生まないことを確実にすることが必要です。

実装はエンコードされた長さ (Section 5.1 を参照)と同様、整数として受け入れる値を制限しなければなりません。同様に、文字列リテラル(Section 5.2 を参照) として受け入れる長さを制限しなければなりません。

8. 参考文献

8.1 引用文献

[HTTP2]Belshe, M., Peon, R., and M. Thomson, Ed., “Hypertext Transfer Protocol Version 2 (HTTP/2)”, RFC 7540, May 2015, <http://www.rfc-editor.org/info/rfc7540>.
[RFC2119]Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997, <http://www.rfc-editor.org/info/rfc2119>.
[RFC7230]Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing”, RFC 7230, June 2014, <http://www.rfc-editor.org/info/rfc7230>.

8.2 参考文献

[CANONICAL]Schwartz, E. and B. Kallick, “Generating a canonical prefix encoding”, Communications of the ACM Volume 7 Issue 3, pp. 166-169, March 1964, <https://dl.acm.org/citation.cfm?id=363991>.
[CRIME]Rizzo, J. and T. Duong, “The CRIME Attack”, September 2012, <https://docs.google.com/a/twist.com/presentation/d/11eBmGiHbYcHR9gL5nDyZChu_-lCa2GizeuOfaLU2HOU>.
[DEFLATE]Deutsch, P., “DEFLATE Compressed Data Format Specification version 1.3”, RFC 1951, May 1996, <http://www.rfc-editor.org/info/rfc1951>.
[HUFFMAN]Huffman, D., “A Method for the Construction of Minimum Redundancy Codes”, Proceedings of the Institute of Radio Engineers Volume 40, Number 9, pp. 1098-1101, September 1952, <http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=4051119>.
[ORIGIN]Barth, A., “The Web Origin Concept”, RFC 6454, December 2011, <http://www.rfc-editor.org/info/rfc6454>.
[PETAL]Tan, J. and J. Nahata, “PETAL: Preset Encoding Table Information Leakage”, April 2013, <http://www.pdl.cmu.edu/PDL-FTP/associated/CMU-PDL-13-106.pdf>.
[SPDY]Belshe, M. and R. Peon, “SPDY Protocol”, Internet-Draft draft-mbelshe-httpbis-spdy-00 (work in progress), February 2012.
[TLS12]Dierks, T. and E. Rescorla, “The Transport Layer Security (TLS) Protocol Version 1.2”, RFC 5246, August 2008, <http://www.rfc-editor.org/info/rfc5246>.

A. 静的テーブル定義

静的テーブル (Section 2.3.1 を参照) は予め定義されており変更不可能なヘッダフィールドのリストで構成されます。

静的テーブルは HTTP/2 特有の疑似ヘッダフィールド ([HTTP2] 8.1.2.1 節を参照) の追加を伴った、有名な web サイトで最も頻繁に使用されたヘッダフィールドから作成されました。少数のヘッダフィールドの値は頻繁に使用される値としてエントリに追加されています。その他のヘッダフィールドは、空の値で追加されています。

Table 1 リストは静的テーブルを構成する予め定義されたヘッダフィールドと各エントリのインデックスを列挙しています。

Table 1: 静的テーブルエントリ
インデックスヘッダ名ヘッダ値
1:authority
2:methodGET
3:methodPOST
4:path/
5:path/index.html
6:schemehttp
7:schemehttps
8:status200
9:status204
10:status206
11:status304
12:status400
13:status404
14:status500
15accept-charset
16accept-encodinggzip, deflate
17accept-language
18accept-ranges
19accept
20access-control-allow-origin
21age
22allow
23authorization
24cache-control
25content-disposition
26content-encoding
27content-language
28content-length
29content-location
30content-range
31content-type
32cookie
33date
34etag
35expect
36expires
37from
38host
39if-match
40if-modified-since
41if-none-match
42if-range
43if-unmodified-since
44last-modified
45link
46location
47max-forwards
48proxy-authenticate
49proxy-authorization
50range
51referer
52refresh
53retry-after
54server
55set-cookie
56strict-transport-security
57transfer-encoding
58user-agent
59vary
60via
61www-authenticate

B. ハフマン符号

下記のハフマン符号はハフマン符号化を伴う文字列リテラルのエンコーディング時に使用されます(Section 5.2 を参照)。

このハフマン符号は HTTP ヘッダの多くのサンプルで得られた統計から生成されました。これはユニークなコード長を持つシンボルが無いことを確実にするよう幾つかの微調整を行ったカノニカルハフマン符号 ([CANONICAL] を参照) です。

テーブルの各行はシンボルを表現するのに使用されるコードを定義します:

sym:
表現されるシンボル。オクテットの 10 進数値です。可能であればアスキー表現でも表記しています。特別なシンボル "EOS" は文字列リテラルの終わりを示すのに使用されます。
code as bits:
2 進数で表現されたシンボルのハフマンコード。最上位ビット (MSB) で調整されています。
code as hex:
16 進数で表現されたシンボルのハフマンコード。最下位ビット (LSB) で調整されています。
len:
シンボルを表現するコードのビット数。

例として、シンボル 47 (アスキー文字 "/" に対応します) のコードは 6 ビット "0", "1", "1", "0", "0", "0" から構成されます。これは 6 ビットでエンコードされた値 0x18 (16 進数で) に対応します。

                                                     code
                       code as bits                 as hex   len
     sym              aligned to MSB                aligned   in
                                                    to LSB   bits
    (  0)  |11111111|11000                             1ff8  [13]
    (  1)  |11111111|11111111|1011000                7fffd8  [23]
    (  2)  |11111111|11111111|11111110|0010         fffffe2  [28]
    (  3)  |11111111|11111111|11111110|0011         fffffe3  [28]
    (  4)  |11111111|11111111|11111110|0100         fffffe4  [28]
    (  5)  |11111111|11111111|11111110|0101         fffffe5  [28]
    (  6)  |11111111|11111111|11111110|0110         fffffe6  [28]
    (  7)  |11111111|11111111|11111110|0111         fffffe7  [28]
    (  8)  |11111111|11111111|11111110|1000         fffffe8  [28]
    (  9)  |11111111|11111111|11101010               ffffea  [24]
    ( 10)  |11111111|11111111|11111111|111100      3ffffffc  [30]
    ( 11)  |11111111|11111111|11111110|1001         fffffe9  [28]
    ( 12)  |11111111|11111111|11111110|1010         fffffea  [28]
    ( 13)  |11111111|11111111|11111111|111101      3ffffffd  [30]
    ( 14)  |11111111|11111111|11111110|1011         fffffeb  [28]
    ( 15)  |11111111|11111111|11111110|1100         fffffec  [28]
    ( 16)  |11111111|11111111|11111110|1101         fffffed  [28]
    ( 17)  |11111111|11111111|11111110|1110         fffffee  [28]
    ( 18)  |11111111|11111111|11111110|1111         fffffef  [28]
    ( 19)  |11111111|11111111|11111111|0000         ffffff0  [28]
    ( 20)  |11111111|11111111|11111111|0001         ffffff1  [28]
    ( 21)  |11111111|11111111|11111111|0010         ffffff2  [28]
    ( 22)  |11111111|11111111|11111111|111110      3ffffffe  [30]
    ( 23)  |11111111|11111111|11111111|0011         ffffff3  [28]
    ( 24)  |11111111|11111111|11111111|0100         ffffff4  [28]
    ( 25)  |11111111|11111111|11111111|0101         ffffff5  [28]
    ( 26)  |11111111|11111111|11111111|0110         ffffff6  [28]
    ( 27)  |11111111|11111111|11111111|0111         ffffff7  [28]
    ( 28)  |11111111|11111111|11111111|1000         ffffff8  [28]
    ( 29)  |11111111|11111111|11111111|1001         ffffff9  [28]
    ( 30)  |11111111|11111111|11111111|1010         ffffffa  [28]
    ( 31)  |11111111|11111111|11111111|1011         ffffffb  [28]
' ' ( 32)  |010100                                       14  [ 6]
'!' ( 33)  |11111110|00                                 3f8  [10]
'"' ( 34)  |11111110|01                                 3f9  [10]
'#' ( 35)  |11111111|1010                               ffa  [12]
'$' ( 36)  |11111111|11001                             1ff9  [13]
'%' ( 37)  |010101                                       15  [ 6]
'&' ( 38)  |11111000                                     f8  [ 8]
''' ( 39)  |11111111|010                                7fa  [11]
'(' ( 40)  |11111110|10                                 3fa  [10]
')' ( 41)  |11111110|11                                 3fb  [10]
'*' ( 42)  |11111001                                     f9  [ 8]
'+' ( 43)  |11111111|011                                7fb  [11]
',' ( 44)  |11111010                                     fa  [ 8]
'-' ( 45)  |010110                                       16  [ 6]
'.' ( 46)  |010111                                       17  [ 6]
'/' ( 47)  |011000                                       18  [ 6]
'0' ( 48)  |00000                                         0  [ 5]
'1' ( 49)  |00001                                         1  [ 5]
'2' ( 50)  |00010                                         2  [ 5]
'3' ( 51)  |011001                                       19  [ 6]
'4' ( 52)  |011010                                       1a  [ 6]
'5' ( 53)  |011011                                       1b  [ 6]
'6' ( 54)  |011100                                       1c  [ 6]
'7' ( 55)  |011101                                       1d  [ 6]
'8' ( 56)  |011110                                       1e  [ 6]
'9' ( 57)  |011111                                       1f  [ 6]
':' ( 58)  |1011100                                      5c  [ 7]
';' ( 59)  |11111011                                     fb  [ 8]
'<' ( 60)  |11111111|1111100                           7ffc  [15]
'=' ( 61)  |100000                                       20  [ 6]
'>' ( 62)  |11111111|1011                               ffb  [12]
'?' ( 63)  |11111111|00                                 3fc  [10]
'@' ( 64)  |11111111|11010                             1ffa  [13]
'A' ( 65)  |100001                                       21  [ 6]
'B' ( 66)  |1011101                                      5d  [ 7]
'C' ( 67)  |1011110                                      5e  [ 7]
'D' ( 68)  |1011111                                      5f  [ 7]
'E' ( 69)  |1100000                                      60  [ 7]
'F' ( 70)  |1100001                                      61  [ 7]
'G' ( 71)  |1100010                                      62  [ 7]
'H' ( 72)  |1100011                                      63  [ 7]
'I' ( 73)  |1100100                                      64  [ 7]
'J' ( 74)  |1100101                                      65  [ 7]
'K' ( 75)  |1100110                                      66  [ 7]
'L' ( 76)  |1100111                                      67  [ 7]
'M' ( 77)  |1101000                                      68  [ 7]
'N' ( 78)  |1101001                                      69  [ 7]
'O' ( 79)  |1101010                                      6a  [ 7]
'P' ( 80)  |1101011                                      6b  [ 7]
'Q' ( 81)  |1101100                                      6c  [ 7]
'R' ( 82)  |1101101                                      6d  [ 7]
'S' ( 83)  |1101110                                      6e  [ 7]
'T' ( 84)  |1101111                                      6f  [ 7]
'U' ( 85)  |1110000                                      70  [ 7]
'V' ( 86)  |1110001                                      71  [ 7]
'W' ( 87)  |1110010                                      72  [ 7]
'X' ( 88)  |11111100                                     fc  [ 8]
'Y' ( 89)  |1110011                                      73  [ 7]
'Z' ( 90)  |11111101                                     fd  [ 8]
'[' ( 91)  |11111111|11011                             1ffb  [13]
'\' ( 92)  |11111111|11111110|000                     7fff0  [19]
']' ( 93)  |11111111|11100                             1ffc  [13]
'^' ( 94)  |11111111|111100                            3ffc  [14]
'_' ( 95)  |100010                                       22  [ 6]
'`' ( 96)  |11111111|1111101                           7ffd  [15]
'a' ( 97)  |00011                                         3  [ 5]
'b' ( 98)  |100011                                       23  [ 6]
'c' ( 99)  |00100                                         4  [ 5]
'd' (100)  |100100                                       24  [ 6]
'e' (101)  |00101                                         5  [ 5]
'f' (102)  |100101                                       25  [ 6]
'g' (103)  |100110                                       26  [ 6]
'h' (104)  |100111                                       27  [ 6]
'i' (105)  |00110                                         6  [ 5]
'j' (106)  |1110100                                      74  [ 7]
'k' (107)  |1110101                                      75  [ 7]
'l' (108)  |101000                                       28  [ 6]
'm' (109)  |101001                                       29  [ 6]
'n' (110)  |101010                                       2a  [ 6]
'o' (111)  |00111                                         7  [ 5]
'p' (112)  |101011                                       2b  [ 6]
'q' (113)  |1110110                                      76  [ 7]
'r' (114)  |101100                                       2c  [ 6]
's' (115)  |01000                                         8  [ 5]
't' (116)  |01001                                         9  [ 5]
'u' (117)  |101101                                       2d  [ 6]
'v' (118)  |1110111                                      77  [ 7]
'w' (119)  |1111000                                      78  [ 7]
'x' (120)  |1111001                                      79  [ 7]
'y' (121)  |1111010                                      7a  [ 7]
'z' (122)  |1111011                                      7b  [ 7]
'{' (123)  |11111111|1111110                           7ffe  [15]
'|' (124)  |11111111|100                                7fc  [11]
'}' (125)  |11111111|111101                            3ffd  [14]
'~' (126)  |11111111|11101                             1ffd  [13]
    (127)  |11111111|11111111|11111111|1100         ffffffc  [28]
    (128)  |11111111|11111110|0110                    fffe6  [20]
    (129)  |11111111|11111111|010010                 3fffd2  [22]
    (130)  |11111111|11111110|0111                    fffe7  [20]
    (131)  |11111111|11111110|1000                    fffe8  [20]
    (132)  |11111111|11111111|010011                 3fffd3  [22]
    (133)  |11111111|11111111|010100                 3fffd4  [22]
    (134)  |11111111|11111111|010101                 3fffd5  [22]
    (135)  |11111111|11111111|1011001                7fffd9  [23]
    (136)  |11111111|11111111|010110                 3fffd6  [22]
    (137)  |11111111|11111111|1011010                7fffda  [23]
    (138)  |11111111|11111111|1011011                7fffdb  [23]
    (139)  |11111111|11111111|1011100                7fffdc  [23]
    (140)  |11111111|11111111|1011101                7fffdd  [23]
    (141)  |11111111|11111111|1011110                7fffde  [23]
    (142)  |11111111|11111111|11101011               ffffeb  [24]
    (143)  |11111111|11111111|1011111                7fffdf  [23]
    (144)  |11111111|11111111|11101100               ffffec  [24]
    (145)  |11111111|11111111|11101101               ffffed  [24]
    (146)  |11111111|11111111|010111                 3fffd7  [22]
    (147)  |11111111|11111111|1100000                7fffe0  [23]
    (148)  |11111111|11111111|11101110               ffffee  [24]
    (149)  |11111111|11111111|1100001                7fffe1  [23]
    (150)  |11111111|11111111|1100010                7fffe2  [23]
    (151)  |11111111|11111111|1100011                7fffe3  [23]
    (152)  |11111111|11111111|1100100                7fffe4  [23]
    (153)  |11111111|11111110|11100                  1fffdc  [21]
    (154)  |11111111|11111111|011000                 3fffd8  [22]
    (155)  |11111111|11111111|1100101                7fffe5  [23]
    (156)  |11111111|11111111|011001                 3fffd9  [22]
    (157)  |11111111|11111111|1100110                7fffe6  [23]
    (158)  |11111111|11111111|1100111                7fffe7  [23]
    (159)  |11111111|11111111|11101111               ffffef  [24]
    (160)  |11111111|11111111|011010                 3fffda  [22]
    (161)  |11111111|11111110|11101                  1fffdd  [21]
    (162)  |11111111|11111110|1001                    fffe9  [20]
    (163)  |11111111|11111111|011011                 3fffdb  [22]
    (164)  |11111111|11111111|011100                 3fffdc  [22]
    (165)  |11111111|11111111|1101000                7fffe8  [23]
    (166)  |11111111|11111111|1101001                7fffe9  [23]
    (167)  |11111111|11111110|11110                  1fffde  [21]
    (168)  |11111111|11111111|1101010                7fffea  [23]
    (169)  |11111111|11111111|011101                 3fffdd  [22]
    (170)  |11111111|11111111|011110                 3fffde  [22]
    (171)  |11111111|11111111|11110000               fffff0  [24]
    (172)  |11111111|11111110|11111                  1fffdf  [21]
    (173)  |11111111|11111111|011111                 3fffdf  [22]
    (174)  |11111111|11111111|1101011                7fffeb  [23]
    (175)  |11111111|11111111|1101100                7fffec  [23]
    (176)  |11111111|11111111|00000                  1fffe0  [21]
    (177)  |11111111|11111111|00001                  1fffe1  [21]
    (178)  |11111111|11111111|100000                 3fffe0  [22]
    (179)  |11111111|11111111|00010                  1fffe2  [21]
    (180)  |11111111|11111111|1101101                7fffed  [23]
    (181)  |11111111|11111111|100001                 3fffe1  [22]
    (182)  |11111111|11111111|1101110                7fffee  [23]
    (183)  |11111111|11111111|1101111                7fffef  [23]
    (184)  |11111111|11111110|1010                    fffea  [20]
    (185)  |11111111|11111111|100010                 3fffe2  [22]
    (186)  |11111111|11111111|100011                 3fffe3  [22]
    (187)  |11111111|11111111|100100                 3fffe4  [22]
    (188)  |11111111|11111111|1110000                7ffff0  [23]
    (189)  |11111111|11111111|100101                 3fffe5  [22]
    (190)  |11111111|11111111|100110                 3fffe6  [22]
    (191)  |11111111|11111111|1110001                7ffff1  [23]
    (192)  |11111111|11111111|11111000|00           3ffffe0  [26]
    (193)  |11111111|11111111|11111000|01           3ffffe1  [26]
    (194)  |11111111|11111110|1011                    fffeb  [20]
    (195)  |11111111|11111110|001                     7fff1  [19]
    (196)  |11111111|11111111|100111                 3fffe7  [22]
    (197)  |11111111|11111111|1110010                7ffff2  [23]
    (198)  |11111111|11111111|101000                 3fffe8  [22]
    (199)  |11111111|11111111|11110110|0            1ffffec  [25]
    (200)  |11111111|11111111|11111000|10           3ffffe2  [26]
    (201)  |11111111|11111111|11111000|11           3ffffe3  [26]
    (202)  |11111111|11111111|11111001|00           3ffffe4  [26]
    (203)  |11111111|11111111|11111011|110          7ffffde  [27]
    (204)  |11111111|11111111|11111011|111          7ffffdf  [27]
    (205)  |11111111|11111111|11111001|01           3ffffe5  [26]
    (206)  |11111111|11111111|11110001               fffff1  [24]
    (207)  |11111111|11111111|11110110|1            1ffffed  [25]
    (208)  |11111111|11111110|010                     7fff2  [19]
    (209)  |11111111|11111111|00011                  1fffe3  [21]
    (210)  |11111111|11111111|11111001|10           3ffffe6  [26]
    (211)  |11111111|11111111|11111100|000          7ffffe0  [27]
    (212)  |11111111|11111111|11111100|001          7ffffe1  [27]
    (213)  |11111111|11111111|11111001|11           3ffffe7  [26]
    (214)  |11111111|11111111|11111100|010          7ffffe2  [27]
    (215)  |11111111|11111111|11110010               fffff2  [24]
    (216)  |11111111|11111111|00100                  1fffe4  [21]
    (217)  |11111111|11111111|00101                  1fffe5  [21]
    (218)  |11111111|11111111|11111010|00           3ffffe8  [26]
    (219)  |11111111|11111111|11111010|01           3ffffe9  [26]
    (220)  |11111111|11111111|11111111|1101         ffffffd  [28]
    (221)  |11111111|11111111|11111100|011          7ffffe3  [27]
    (222)  |11111111|11111111|11111100|100          7ffffe4  [27]
    (223)  |11111111|11111111|11111100|101          7ffffe5  [27]
    (224)  |11111111|11111110|1100                    fffec  [20]
    (225)  |11111111|11111111|11110011               fffff3  [24]
    (226)  |11111111|11111110|1101                    fffed  [20]
    (227)  |11111111|11111111|00110                  1fffe6  [21]
    (228)  |11111111|11111111|101001                 3fffe9  [22]
    (229)  |11111111|11111111|00111                  1fffe7  [21]
    (230)  |11111111|11111111|01000                  1fffe8  [21]
    (231)  |11111111|11111111|1110011                7ffff3  [23]
    (232)  |11111111|11111111|101010                 3fffea  [22]
    (233)  |11111111|11111111|101011                 3fffeb  [22]
    (234)  |11111111|11111111|11110111|0            1ffffee  [25]
    (235)  |11111111|11111111|11110111|1            1ffffef  [25]
    (236)  |11111111|11111111|11110100               fffff4  [24]
    (237)  |11111111|11111111|11110101               fffff5  [24]
    (238)  |11111111|11111111|11111010|10           3ffffea  [26]
    (239)  |11111111|11111111|1110100                7ffff4  [23]
    (240)  |11111111|11111111|11111010|11           3ffffeb  [26]
    (241)  |11111111|11111111|11111100|110          7ffffe6  [27]
    (242)  |11111111|11111111|11111011|00           3ffffec  [26]
    (243)  |11111111|11111111|11111011|01           3ffffed  [26]
    (244)  |11111111|11111111|11111100|111          7ffffe7  [27]
    (245)  |11111111|11111111|11111101|000          7ffffe8  [27]
    (246)  |11111111|11111111|11111101|001          7ffffe9  [27]
    (247)  |11111111|11111111|11111101|010          7ffffea  [27]
    (248)  |11111111|11111111|11111101|011          7ffffeb  [27]
    (249)  |11111111|11111111|11111111|1110         ffffffe  [28]
    (250)  |11111111|11111111|11111101|100          7ffffec  [27]
    (251)  |11111111|11111111|11111101|101          7ffffed  [27]
    (252)  |11111111|11111111|11111101|110          7ffffee  [27]
    (253)  |11111111|11111111|11111101|111          7ffffef  [27]
    (254)  |11111111|11111111|11111110|000          7fffff0  [27]
    (255)  |11111111|11111111|11111011|10           3ffffee  [26]
EOS (256)  |11111111|11111111|11111111|111111      3fffffff  [30]

C. 

付録には、リクエストとレスポンス両方の、ハフマン符号化を伴う場合と伴わない場合の、整数、ヘッダフィールド表現そしてヘッダフィールドのリストのすべてのエンコーディングの例があります。

C.1 整数表現の例

この節では (Section 5.1 を参照) に詳細がある整数値の表現の例を記述します。

C.1.1 例 1: 5 ビットプレフィックスを用いた 10 のエンコーディング

値 10 は 5 ビットプレフィックスでエンコードされます。

  • 10 は 31 (2^5 - 1) より小さいので 5 ビットプレフィックスを用いて表現されます。
  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| X | X | X | 0 | 1 | 0 | 1 | 0 |   10 stored on 5 bits
+---+---+---+---+---+---+---+---+

C.1.2 例 2: 5 ビットプレフィックスを用いた 1337 のエンコーディング

値 I=1337 は 5 ビットプレフィックスでエンコードされます。

  • 1337 は 31 (2^5 - 1) より大きい。
    • 5 ビットプレフィックスは 最大値(31) で満たされます。
  • I = 1337 - (2^5 - 1) = 1306.
    • I (1306) は 128 以上で、 while ループ本体が実行します:
      • I % 128 == 26
      • 26 + 128 == 154
      • 154 は 8 ビットでエンコードされます: 10011010
      • I に 10 がセットされます (1306 / 128 == 10)
      • I は 128 より大きくなく、 while ループは終了します。
    • 10 になった I は 8 ビットでエンコードされます: 00001010.
  • 処理終了。
  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| X | X | X | 1 | 1 | 1 | 1 | 1 |  Prefix = 31, I = 1306
| 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |  1306>=128, encode(154), I=1306/128
| 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |  10<128, encode(10), done
+---+---+---+---+---+---+---+---+

C.1.3 例 3: オクテット境界で開始する 42 のエンコーディング

値 42 はオクテット境界から開始しエンコードされます。これは 8 ビットプレフィックスが使用されることを示します。

  • 42 は 255 (2^8 - 1) 以下であり 8 ビットプレフィックスを用いて表現されます。
  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |   42 stored on 8 bits
+---+---+---+---+---+---+---+---+

C.2 ヘッダフィールド表現の例

この節では幾つかの個々の表現の例を掲載します。

C.2.1 インデックスを伴うリテラルヘッダフィールド

ヘッダフィールド表現はリテラル名とリテラル値を使用します。ヘッダフィールドは動的テーブルに追加されます。

エンコードするヘッダリスト:

custom-key: custom-header

エンコードされたデータの 16 進数ダンプ:

400a 6375 7374 6f6d 2d6b 6579 0d63 7573 | @.custom-key.cus
746f 6d2d 6865 6164 6572                | tom-header

デコード処理:

40                                      | == Literal indexed ==
0a                                      |   Literal name (len = 10)
6375 7374 6f6d 2d6b 6579                | custom-key
0d                                      |   Literal value (len = 13)
6375 7374 6f6d 2d68 6561 6465 72        | custom-header
                                        | -> custom-key:
                                        |   custom-header

動的テーブル (デコード後):

[  1] (s =  55) custom-key: custom-header
      Table size:  55

デコードされたヘッダリスト:

custom-key: custom-header

C.2.2 インデックスを伴わないリテラルヘッダフィールド

ヘッダフィールド表現はリテラル名とリテラル値を使用します。ヘッダフィールドは動的テーブルに追加されません。

エンコードするヘッダリスト:

:path: /sample/path

エンコードされたデータの 16 進数ダンプ:

040c 2f73 616d 706c 652f 7061 7468      | ../sample/path

デコード処理:

04                                      | == Literal not indexed ==
                                        |   Indexed name (idx = 4)
                                        |     :path
0c                                      |   Literal value (len = 12)
2f73 616d 706c 652f 7061 7468           | /sample/path
                                        | -> :path: /sample/path

動的テーブル (デコード後): 空

デコードされたヘッダリスト:

:path: /sample/path

C.2.3 インデックスされないリテラルヘッダフィールド

ヘッダフィールド表現はリテラル名とリテラル値を使用します。ヘッダフィールドは動的テーブルに追加されず、中継者に再エンコードされる場合同じ表現を使わなければなりません。

エンコードするヘッダリスト:

password: secret

エンコードされたデータの 16 進数ダンプ:

1008 7061 7373 776f 7264 0673 6563 7265 | ..password.secre
74                                      | t

デコード処理:

10                                      | == Literal never indexed ==
08                                      |   Literal name (len = 8)
7061 7373 776f 7264                     | password
06                                      |   Literal value (len = 6)
7365 6372 6574                          | secret
                                        | -> password: secret

動的テーブル (デコード後): 空

デコードされたヘッダリスト:

password: secret

C.2.4 インデックスヘッダフィールド

このヘッダフィールド表現は静的テーブルにインデックスされたヘッダフィールドを使用します。

エンコードするヘッダリスト:

:method: GET

エンコードされたデータの 16 進ダンプ:

82                                      | .

デコード処理:

82                                      | == Indexed - Add ==
                                        |   idx = 2
                                        | -> :method: GET

動的テーブル (デコード後): 空

デコードされたヘッダリスト:

:method: GET

C.3 ハフマン符号化を伴わないリクエストの例

この節は同じコネクションにおける HTTP リクエストに対応した幾つかの連続したヘッダリストを示します。

C.3.1 一個目のリクエスト

エンコードするヘッダリスト:

:method: GET
:scheme: http
:path: /
:authority: www.example.com

エンコードされたデータの 16 進数ダンプ:

8286 8441 0f77 7777 2e65 7861 6d70 6c65 | ...A.www.example
2e63 6f6d                               | .com

デコード処理:

82                                      | == Indexed - Add ==
                                        |   idx = 2
                                        | -> :method: GET
86                                      | == Indexed - Add ==
                                        |   idx = 6
                                        | -> :scheme: http
84                                      | == Indexed - Add ==
                                        |   idx = 4
                                        | -> :path: /
41                                      | == Literal indexed ==
                                        |   Indexed name (idx = 1)
                                        |     :authority
0f                                      |   Literal value (len = 15)
7777 772e 6578 616d 706c 652e 636f 6d   | www.example.com
                                        | -> :authority: 
                                        |   www.example.com

動的テーブル (デコード後):

[  1] (s =  57) :authority: www.example.com
      Table size:  57

デコードされたヘッダリスト:

:method: GET
:scheme: http
:path: /
:authority: www.example.com

C.3.2 二個目のリクエスト

エンコードするヘッダリスト:

:method: GET
:scheme: http
:path: /
:authority: www.example.com
cache-control: no-cache

エンコードされたデータの 16 進数ダンプ:

8286 84be 5808 6e6f 2d63 6163 6865      | ....X.no-cache

デコード処理:

82                                      | == Indexed - Add ==
                                        |   idx = 2
                                        | -> :method: GET
86                                      | == Indexed - Add ==
                                        |   idx = 6
                                        | -> :scheme: http
84                                      | == Indexed - Add ==
                                        |   idx = 4
                                        | -> :path: /
be                                      | == Indexed - Add ==
                                        |   idx = 62
                                        | -> :authority:
                                        |   www.example.com
58                                      | == Literal indexed ==
                                        |   Indexed name (idx = 24)
                                        |     cache-control
08                                      |   Literal value (len = 8)
6e6f 2d63 6163 6865                     | no-cache
                                        | -> cache-control: no-cache

動的テーブル (デコード後):

[  1] (s =  53) cache-control: no-cache
[  2] (s =  57) :authority: www.example.com
      Table size: 110

デコードされたヘッダリスト:

:method: GET
:scheme: http
:path: /
:authority: www.example.com
cache-control: no-cache

C.3.3 三個目のリクエスト

エンコードするヘッダリスト:

:method: GET
:scheme: https
:path: /index.html
:authority: www.example.com
custom-key: custom-value

エンコードされたデータの 16 進数ダンプ:

8287 85bf 400a 6375 7374 6f6d 2d6b 6579 | ....@.custom-key
0c63 7573 746f 6d2d 7661 6c75 65        | .custom-value

デコード処理:

82                                      | == Indexed - Add ==
                                        |   idx = 2
                                        | -> :method: GET
87                                      | == Indexed - Add ==
                                        |   idx = 7
                                        | -> :scheme: https
85                                      | == Indexed - Add ==
                                        |   idx = 5
                                        | -> :path: /index.html
bf                                      | == Indexed - Add ==
                                        |   idx = 63
                                        | -> :authority:
                                        |   www.example.com
40                                      | == Literal indexed ==
0a                                      |   Literal name (len = 10)
6375 7374 6f6d 2d6b 6579                | custom-key
0c                                      |   Literal value (len = 12)
6375 7374 6f6d 2d76 616c 7565           | custom-value
                                        | -> custom-key:
                                        |   custom-value

動的テーブル (デコード後):

[  1] (s =  54) custom-key: custom-value
[  2] (s =  53) cache-control: no-cache
[  3] (s =  57) :authority: www.example.com
      Table size: 164

デコードされたヘッダリスト:

:method: GET
:scheme: https
:path: /index.html
:authority: www.example.com
custom-key: custom-value

C.4 ハフマン符号化を伴うリクエストの例

この節では前節と同じ例を示しますが、リテラル値にハフマン符号化を行います。

C.4.1 一個目のリクエスト

エンコードするヘッダリスト:

:method: GET
:scheme: http
:path: /
:authority: www.example.com

エンコードされたデータの 16 進数ダンプ:

8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4 | ...A......:k....
ff                                      | .

デコード処理:

82                                      | == Indexed - Add ==
                                        |   idx = 2
                                        | -> :method: GET
86                                      | == Indexed - Add ==
                                        |   idx = 6
                                        | -> :scheme: http
84                                      | == Indexed - Add ==
                                        |   idx = 4
                                        | -> :path: /
41                                      | == Literal indexed ==
                                        |   Indexed name (idx = 1)
                                        |     :authority
8c                                      |   Literal value (len = 12)
                                        |     Huffman encoded:
f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
                                        |     Decoded:
                                        | www.example.com
                                        | -> :authority:
                                        |   www.example.com

動的テーブル (デコード後):

[  1] (s =  57) :authority: www.example.com
      Table size:  57

デコードされたヘッダリスト:

:method: GET
:scheme: http
:path: /
:authority: www.example.com

C.4.2 二個目のリクエスト

エンコードするヘッダリスト:

:method: GET
:scheme: http
:path: /
:authority: www.example.com
cache-control: no-cache

エンコードされたデータの 16 進数ダンプ:

8286 84be 5886 a8eb 1064 9cbf           | ....X....d..

デコード処理:

82                                      | == Indexed - Add ==
                                        |   idx = 2
                                        | -> :method: GET
86                                      | == Indexed - Add ==
                                        |   idx = 6
                                        | -> :scheme: http
84                                      | == Indexed - Add ==
                                        |   idx = 4
                                        | -> :path: /
be                                      | == Indexed - Add ==
                                        |   idx = 62
                                        | -> :authority:
                                        |   www.example.com
58                                      | == Literal indexed ==
                                        |   Indexed name (idx = 24)
                                        |     cache-control
86                                      |   Literal value (len = 6)
                                        |     Huffman encoded:
a8eb 1064 9cbf                          | ...d..
                                        |     Decoded:
                                        | no-cache
                                        | -> cache-control: no-cache

動的テーブル (デコード後):

[  1] (s =  53) cache-control: no-cache
[  2] (s =  57) :authority: www.example.com
      Table size: 110

デコードされたヘッダリスト:

:method: GET
:scheme: http
:path: /
:authority: www.example.com
cache-control: no-cache

C.4.3 三個目のリクエスト

エンコードするヘッダリスト:

:method: GET
:scheme: https
:path: /index.html
:authority: www.example.com
custom-key: custom-value

エンコードされたデータの 16 進数ダンプ:

8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925 | ....@.%.I.[.}..%
a849 e95b b8e8 b4bf                     | .I.[....

デコード処理:

82                                      | == Indexed - Add ==
                                        |   idx = 2
                                        | -> :method: GET
87                                      | == Indexed - Add ==
                                        |   idx = 7
                                        | -> :scheme: https
85                                      | == Indexed - Add ==
                                        |   idx = 5
                                        | -> :path: /index.html
bf                                      | == Indexed - Add ==
                                        |   idx = 63
                                        | -> :authority:
                                        |   www.example.com
40                                      | == Literal indexed ==
88                                      |   Literal name (len = 8)
                                        |     Huffman encoded:
25a8 49e9 5ba9 7d7f                     | %.I.[.}.
                                        |     Decoded:
                                        | custom-key
89                                      |   Literal value (len = 9)
                                        |     Huffman encoded:
25a8 49e9 5bb8 e8b4 bf                  | %.I.[....
                                        |     Decoded:
                                        | custom-value
                                        | -> custom-key:
                                        |   custom-value

動的テーブル (デコード後):

[  1] (s =  54) custom-key: custom-value
[  2] (s =  53) cache-control: no-cache
[  3] (s =  57) :authority: www.example.com
      Table size: 164

デコードされたヘッダリスト:

:method: GET
:scheme: https
:path: /index.html
:authority: www.example.com
custom-key: custom-value

C.5 ハフマン符号化を伴わないレスポンスの例

この節は同じコネクションにおける HTTP レスポンスに対応した幾つかの連続したヘッダリストを示します。 HTTP/2 設定パラメータ SETTINGS_HEADER_TABLE_SIZE は幾つかの削除を起こすため、 256 オクテットの値で設定されています。

C.5.1 一個目のレスポンス

エンコードするヘッダリスト:

:status: 302
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

エンコードされたデータの 16 進数ダンプ:

4803 3330 3258 0770 7269 7661 7465 611d | H.302X.privatea.
4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
2032 303a 3133 3a32 3120 474d 546e 1768 |  20:13:21 GMTn.h
7474 7073 3a2f 2f77 7777 2e65 7861 6d70 | ttps://www.examp
6c65 2e63 6f6d                          | le.com

デコード処理:

48                                      | == Literal indexed ==
                                        |   Indexed name (idx = 8)
                                        |     :status
03                                      |   Literal value (len = 3)
3330 32                                 | 302
                                        | -> :status: 302
58                                      | == Literal indexed ==
                                        |   Indexed name (idx = 24)
                                        |     cache-control
07                                      |   Literal value (len = 7)
7072 6976 6174 65                       | private
                                        | -> cache-control: private
61                                      | == Literal indexed ==
                                        |   Indexed name (idx = 33)
                                        |     date
1d                                      |   Literal value (len = 29)
4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
2032 303a 3133 3a32 3120 474d 54        |  20:13:21 GMT
                                        | -> date: Mon, 21 Oct 2013
                                        |   20:13:21 GMT
6e                                      | == Literal indexed ==
                                        |   Indexed name (idx = 46)
                                        |     location
17                                      |   Literal value (len = 23)
6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam
706c 652e 636f 6d                       | ple.com
                                        | -> location:
                                        |   https://www.example.com

動的テーブル (デコード後):

[  1] (s =  63) location: https://www.example.com
[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
[  3] (s =  52) cache-control: private
[  4] (s =  42) :status: 302
      Table size: 222

デコードされたヘッダリスト:

:status: 302
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

C.5.2 二個目のレスポンス

(":status", "307") ヘッダフィールドの追加を行える領域を解放するため (":status", "302") ヘッダフィールドは動的テーブルから削除されます。

エンコードするヘッダリスト:

:status: 307
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

エンコードされたデータの 16 進数ダンプ:

4803 3330 37c1 c0bf                     | H.307...

デコード処理:

48                                      | == Literal indexed ==
                                        |   Indexed name (idx = 8)
                                        |     :status
03                                      |   Literal value (len = 3)
3330 37                                 | 307
                                        | - evict: :status: 302
                                        | -> :status: 307
c1                                      | == Indexed - Add ==
                                        |   idx = 65
                                        | -> cache-control: private
c0                                      | == Indexed - Add ==
                                        |   idx = 64
                                        | -> date: Mon, 21 Oct 2013
                                        |   20:13:21 GMT
bf                                      | == Indexed - Add ==
                                        |   idx = 63
                                        | -> location:
                                        |   https://www.example.com

動的テーブル (デコード後):

[  1] (s =  42) :status: 307
[  2] (s =  63) location: https://www.example.com
[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
[  4] (s =  52) cache-control: private
      Table size: 222

デコードされたヘッダリスト:

:status: 307
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

C.5.3 三個目のレスポンス

このヘッダリストの処理中幾つかのヘッダフィールドが動的テーブルから削除されます。

エンコードするヘッダリスト:

:status: 200
cache-control: private
date: Mon, 21 Oct 2013 20:13:22 GMT
location: https://www.example.com
content-encoding: gzip
set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1

エンコードされたデータの 16 進数ダンプ:

88c1 611d 4d6f 6e2c 2032 3120 4f63 7420 | ..a.Mon, 21 Oct
3230 3133 2032 303a 3133 3a32 3220 474d | 2013 20:13:22 GM
54c0 5a04 677a 6970 7738 666f 6f3d 4153 | T.Z.gzipw8foo=AS
444a 4b48 514b 425a 584f 5157 454f 5049 | DJKHQKBZXOQWEOPI
5541 5851 5745 4f49 553b 206d 6178 2d61 | UAXQWEOIU; max-a
6765 3d33 3630 303b 2076 6572 7369 6f6e | ge=3600; version
3d31                                    | =1

デコード処理:

88                                      | == Indexed - Add ==
                                        |   idx = 8
                                        | -> :status: 200
c1                                      | == Indexed - Add ==
                                        |   idx = 65
                                        | -> cache-control: private
61                                      | == Literal indexed ==
                                        |   Indexed name (idx = 33)
                                        |     date
1d                                      |   Literal value (len = 29)
4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
2032 303a 3133 3a32 3220 474d 54        |  20:13:22 GMT
                                        | - evict: cache-control:
                                        |   private
                                        | -> date: Mon, 21 Oct 2013
                                        |   20:13:22 GMT
c0                                      | == Indexed - Add ==
                                        |   idx = 64
                                        | -> location: 
                                        |   https://www.example.com
5a                                      | == Literal indexed ==
                                        |   Indexed name (idx = 26)
                                        |     content-encoding
04                                      |   Literal value (len = 4)
677a 6970                               | gzip
                                        | - evict: date: Mon, 21 Oct 
                                        |    2013 20:13:21 GMT
                                        | -> content-encoding: gzip
77                                      | == Literal indexed ==
                                        |   Indexed name (idx = 55)
                                        |     set-cookie
38                                      |   Literal value (len = 56)
666f 6f3d 4153 444a 4b48 514b 425a 584f | foo=ASDJKHQKBZXO
5157 454f 5049 5541 5851 5745 4f49 553b | QWEOPIUAXQWEOIU;
206d 6178 2d61 6765 3d33 3630 303b 2076 |  max-age=3600; v
6572 7369 6f6e 3d31                     | ersion=1
                                        | - evict: location:
                                        |   https://www.example.com
                                        | - evict: :status: 307
                                        | -> set-cookie: foo=ASDJKHQ
                                        |   KBZXOQWEOPIUAXQWEOIU; ma
                                        |   x-age=3600; version=1

動的テーブル (デコード後):

[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;
                 max-age=3600; version=1
[  2] (s =  52) content-encoding: gzip
[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT
      Table size: 215

デコードされたヘッダリスト:

:status: 200
cache-control: private
date: Mon, 21 Oct 2013 20:13:22 GMT
location: https://www.example.com
content-encoding: gzip
set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1

C.6 ハフマン符号化を伴うレスポンスの例

この節は同じコネクションにおける HTTP レスポンスに対応した幾つかの連続したヘッダリストを示します。 HTTP/2 設定パラメータ SETTINGS_HEADER_TABLE_SIZE は幾つかの削除を起こすため、 256 オクテットの値で設定されています。削除メカニズムはデコードされたリテラル値の長さを使用するため、前節と同じ削除処理が起こります。

C.6.1 一個目のレスポンス

エンコードするヘッダリスト:

:status: 302
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

エンコードされたデータの 16 進数ダンプ:

4882 6402 5885 aec3 771a 4b61 96d0 7abe | H.d.X...w.Ka..z.
9410 54d4 44a8 2005 9504 0b81 66e0 82a6 | ..T.D. .....f...
2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8 | -..n..)...c.....
e9ae 82ae 43d3                          | ....C.

デコード処理:

48                                      | == Literal indexed ==
                                        |   Indexed name (idx = 8)
                                        |     :status
82                                      |   Literal value (len = 2)
                                        |     Huffman encoded:
6402                                    | d.
                                        |     Decoded:
                                        | 302
                                        | -> :status: 302
58                                      | == Literal indexed ==
                                        |   Indexed name (idx = 24)
                                        |     cache-control
85                                      |   Literal value (len = 5)
                                        |     Huffman encoded:
aec3 771a 4b                            | ..w.K
                                        |     Decoded:
                                        | private
                                        | -> cache-control: private
61                                      | == Literal indexed ==
                                        |   Indexed name (idx = 33)
                                        |     date
96                                      |   Literal value (len = 22)
                                        |     Huffman encoded:
d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f
e082 a62d 1bff                          | ...-..
                                        |     Decoded:
                                        | Mon, 21 Oct 2013 20:13:21
                                        | GMT
                                        | -> date: Mon, 21 Oct 2013
                                        |   20:13:21 GMT
6e                                      | == Literal indexed ==
                                        |   Indexed name (idx = 46)
                                        |     location
91                                      |   Literal value (len = 17)
                                        |     Huffman encoded:
9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C
d3                                      | .
                                        |     Decoded:
                                        | https://www.example.com
                                        | -> location:
                                        |   https://www.example.com

動的テーブル (デコード後):

[  1] (s =  63) location: https://www.example.com
[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
[  3] (s =  52) cache-control: private
[  4] (s =  42) :status: 302
      Table size: 222

デコードされたヘッダリスト:

:status: 302
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

C.6.2 二個目のレスポンス

(":status", "307") ヘッダフィールドの追加を行える領域を解放するため (":status", "302") ヘッダフィールドは動的テーブルから削除されます。

エンコードするヘッダリスト:

:status: 307
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

エンコードされたデータの 16 進数ダンプ:

4883 640e ffc1 c0bf                     | H.d.....

デコード処理:

48                                      | == Literal indexed ==
                                        |   Indexed name (idx = 8)
                                        |     :status
83                                      |   Literal value (len = 3)
                                        |     Huffman encoded:
640e ff                                 | d..
                                        |     Decoded:
                                        | 307
                                        | - evict: :status: 302
                                        | -> :status: 307
c1                                      | == Indexed - Add ==
                                        |   idx = 65
                                        | -> cache-control: private
c0                                      | == Indexed - Add ==
                                        |   idx = 64
                                        | -> date: Mon, 21 Oct 2013
                                        |   20:13:21 GMT
bf                                      | == Indexed - Add ==
                                        |   idx = 63
                                        | -> location:
                                        |   https://www.example.com

動的テーブル (デコード後):

[  1] (s =  42) :status: 307
[  2] (s =  63) location: https://www.example.com
[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
[  4] (s =  52) cache-control: private
      Table size: 222

デコードされたヘッダリスト:

:status: 307
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

C.6.3 三個目のレスポンス

このヘッダリストの処理中幾つかのヘッダフィールドが動的テーブルから削除されます。

エンコードするヘッダリスト:

:status: 200
cache-control: private
date: Mon, 21 Oct 2013 20:13:22 GMT
location: https://www.example.com
content-encoding: gzip
set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1

エンコードされたデータの 16 進数ダンプ:

88c1 6196 d07a be94 1054 d444 a820 0595 | ..a..z...T.D. ..
040b 8166 e084 a62d 1bff c05a 839b d9ab | ...f...-...Z....
77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b | w..........5...[
3960 d5af 2708 7f36 72c1 ab27 0fb5 291f | 9`..'..6r..'..).
9587 3160 65c0 03ed 4ee5 b106 3d50 07   | ..1`e...N...=P.

デコード処理:

88                                      | == Indexed - Add ==
                                        |   idx = 8
                                        | -> :status: 200
c1                                      | == Indexed - Add ==
                                        |   idx = 65
                                        | -> cache-control: private
61                                      | == Literal indexed ==
                                        |   Indexed name (idx = 33)
                                        |     date
96                                      |   Literal value (len = 22)
                                        |     Huffman encoded:
d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f
e084 a62d 1bff                          | ...-..
                                        |     Decoded:
                                        | Mon, 21 Oct 2013 20:13:22
                                        | GMT
                                        | - evict: cache-control:
                                        |   private
                                        | -> date: Mon, 21 Oct 2013 
                                        |   20:13:22 GMT
c0                                      | == Indexed - Add ==
                                        |   idx = 64
                                        | -> location:
                                        |   https://www.example.com
5a                                      | == Literal indexed ==
                                        |   Indexed name (idx = 26)
                                        |     content-encoding
83                                      |   Literal value (len = 3)
                                        |     Huffman encoded:
9bd9 ab                                 | ...
                                        |     Decoded:
                                        | gzip
                                        | - evict: date: Mon, 21 Oct
                                        |    2013 20:13:21 GMT
                                        | -> content-encoding: gzip
77                                      | == Literal indexed ==
                                        |   Indexed name (idx = 55)
                                        |     set-cookie
ad                                      |   Literal value (len = 45)
                                        |     Huffman encoded:
94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9`
d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)...
3160 65c0 03ed 4ee5 b106 3d50 07        | 1`e...N...=P.
                                        |     Decoded:
                                        | foo=ASDJKHQKBZXOQWEOPIUAXQ
                                        | WEOIU; max-age=3600; versi
                                        | on=1
                                        | - evict: location:
                                        |   https://www.example.com
                                        | - evict: :status: 307
                                        | -> set-cookie: foo=ASDJKHQ
                                        |   KBZXOQWEOPIUAXQWEOIU; ma
                                        |   x-age=3600; version=1

動的テーブル (デコード後):

[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;
                 max-age=3600; version=1
[  2] (s =  52) content-encoding: gzip
[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT
      Table size: 215

デコードされたヘッダリスト:

:status: 200
cache-control: private
date: Mon, 21 Oct 2013 20:13:22 GMT
location: https://www.example.com
content-encoding: gzip
set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1

D. 謝辞

この仕様は下記の個人から得た有益な情報を含んでいます:

著者連絡先

Roberto Peon
Google, Inc
Email: fenix@google.com

Herve Ruellan
Canon CRF
Email: herve.ruellan@crf.canon.fr