4. HTTP Frames (HTTPフレーム)
HTTP/2接続が確立されると、エンドポイントはフレームの交換を開始できます。
4.1. Frame Format (フレーム形式)
すべてのフレームは、固定の9オクテットヘッダーで始まり、その後に可変長のフレームペイロード (Frame Payload) が続きます。
HTTP Frame {
Length (24),
Type (8),
Flags (8),
Reserved (1),
Stream Identifier (31),
Frame Payload (..),
}
図1: フレームレイアウト
フレームヘッダーのフィールドは次のように定義されます:
Length (長さ): フレームペイロードの長さ。オクテット単位で符号なし24ビット整数として表現されます。受信者がSETTINGS_MAX_FRAME_SIZEにより大きな値を設定していない限り、2^14 (16,384) より大きい値を送信してはなりません (MUST NOT)。
フレームヘッダーの9オクテットはこの値に含まれません。
Type (タイプ): フレームの8ビットタイプ。フレームタイプは、フレームの形式とセマンティクスを決定します。本文書で定義されているフレームはセクション6にリストされています。実装は、未知のタイプのフレームを無視して破棄しなければなりません (MUST)。
Flags (フラグ): フレームタイプ固有のブール値フラグ用に予約された8ビットフィールド。
フラグには、示されたフレームタイプに固有のセマンティクスが割り当てられます。未使用のフラグとは、特定のフレームタイプに対して定義されたセマンティクスを持たないフラグです。未使用のフラグは、受信時に無視されなければならず (MUST)、送信時には未設定 (0x00) のままにしなければなりません (MUST)。
Reserved (予約済み): 予約済みの1ビットフィールド。このビットのセマンティクスは未定義であり、送信時には未設定 (0x00) のままにしなければならず (MUST)、受信時には無視されなければなりません (MUST)。
Stream Identifier (ストリーム識別子): ストリーム識別子 (セクション5.1.1参照)。符号なし31ビット整数として表現されます。値0x00は、個々のストリームではなく、接続全体に関連付けられたフレーム用に予約されています。
フレームペイロードの構造と内容は、フレームタイプに完全に依存します。
4.2. Frame Size (フレームサイズ)
フレームペイロードのサイズは、受信者がSETTINGS_MAX_FRAME_SIZE設定で通知する最大サイズによって制限されます。この設定は、2^14 (16,384) から2^24-1 (16,777,215) オクテットまでの任意の値を持つことができます (両端を含む)。
すべての実装は、最大2^14オクテットの長さのフレーム、および9オクテットのフレームヘッダー (セクション4.1) を受信し、最低限処理できなければなりません (MUST)。フレームサイズを記述する際、フレームヘッダーのサイズは含まれません。
注意: PING (セクション6.7) などの特定のフレームタイプは、許可されるフレームペイロードデータの量に追加の制限を課します。
フレームがSETTINGS_MAX_FRAME_SIZEで定義されたサイズを超える場合、フレームタイプに定義された制限を超える場合、または必須のフレームデータを含むには小さすぎる場合、エンドポイントはFRAME_SIZE_ERRORのエラーコードを送信しなければなりません (MUST)。接続全体の状態を変更する可能性のあるフレームでのフレームサイズエラーは、接続エラー (Connection Error, セクション5.4.1) として扱わなければなりません (MUST)。これには、フィールドブロック (Field Block, セクション4.3) を運ぶ任意のフレーム (すなわち、HEADERS、PUSH_PROMISE、CONTINUATION)、SETTINGSフレーム、およびストリーム識別子が0の任意のフレームが含まれます。
エンドポイントは、フレーム内のすべての利用可能なスペースを使用する義務はありません。許可された最大サイズより小さいフレームを使用することで、応答性を向上させることができます。大きなフレームを送信すると、時間に敏感なフレーム (RST_STREAM、WINDOW_UPDATE、PRIORITYなど) の送信に遅延が生じる可能性があり、大きなフレームの送信によってブロックされると、パフォーマンスに影響を与える可能性があります。
4.3. Field Section Compression and Decompression (フィールドセクションの圧縮と解凍)
フィールドセクション圧縮 (Field Section Compression) は、フィールド行のセット ([HTTP] のセクション5.2) を圧縮してフィールドブロック (Field Block) を形成するプロセスです。フィールドセクション解凍 (Field Section Decompression) は、フィールドブロックをフィールド行のセットにデコードするプロセスです。HTTP/2フィールドセクションの圧縮と解凍の詳細は [COMPRESSION] で定義されており、歴史的な理由から、これらのプロセスをヘッダー圧縮および解凍と呼んでいます。
各フィールドブロックは、単一のフィールドセクションのすべての圧縮されたフィールド行を運びます。ヘッダーセクションには、フィールド行と同じ形式を使用する疑似ヘッダーフィールド (Pseudo-Header Fields, セクション8.3) の形式でメッセージに関連付けられた制御データも含まれます。
注意: RFC 7540 [RFC7540] は、より汎用的な "フィールドブロック (Field Block)" の代わりに "ヘッダーブロック (Header Block)" という用語を使用していました。
フィールドブロックは、リクエスト、レスポンス、約束されたリクエスト、およびプッシュされたレスポンスの制御データとヘッダーセクションを運びます (セクション8.4参照)。これらのメッセージはすべて、暫定レスポンスとPUSH_PROMISE (セクション6.6) フレームに含まれるリクエストを除いて、トレーラーセクション (Trailer Section) を運ぶフィールドブロックをオプションで含めることができます。
フィールドセクションは、フィールド行のコレクションです。フィールドブロック内の各フィールド行は、単一の値を運びます。シリアライズされたフィールドブロックは、その後、フィールドブロックフラグメント (Field Block Fragments) と呼ばれる1つ以上のオクテットシーケンスに分割されます。最初のフィールドブロックフラグメントは、HEADERS (セクション6.2) またはPUSH_PROMISE (セクション6.6) のフレームペイロード内で送信され、それぞれの後に後続のフィールドブロックフラグメントを運ぶCONTINUATION (セクション6.10) フレームが続くことがあります。
Cookieヘッダーフィールド [COOKIE] は、HTTPマッピングによって特別に扱われます (セクション8.2.3参照)。
受信エンドポイントは、フラグメントを連結してフィールドブロックを再構築し、次にブロックを解凍してフィールドセクションを再構築します。
完全なフィールドセクションは、次のいずれかで構成されます:
-
END_HEADERSフラグが設定された単一のHEADERSまたはPUSH_PROMISEフレーム、または
-
END_HEADERSフラグが設定されていないHEADERSまたはPUSH_PROMISEフレームと、1つ以上のCONTINUATIONフレーム。最後のCONTINUATIONフレームにはEND_HEADERSフラグが設定されています。
各フィールドブロックは、個別の単位として処理されます。フィールドブロックは、他のタイプのフレームまたは他のストリームからのフレームが介在することなく、連続したフレームのシーケンスとして送信されなければなりません (MUST)。HEADERSまたはCONTINUATIONフレームのシーケンスの最後のフレームには、END_HEADERSフラグが設定されています。PUSH_PROMISEまたはCONTINUATIONフレームのシーケンスの最後のフレームには、END_HEADERSフラグが設定されています。これにより、フィールドブロックは論理的に単一のフレームと同等になります。
フィールドブロックフラグメントは、これらのフレームが受信者が維持する圧縮コンテキストを変更できるデータを運ぶため、HEADERS、PUSH_PROMISE、またはCONTINUATIONフレームのフレームペイロードとしてのみ送信できます。HEADERS、PUSH_PROMISE、またはCONTINUATIONフレームを受信するエンドポイントは、フレームが破棄される場合でも、フィールドブロックを再構築し、解凍を実行する必要があります。受信者がフィールドブロックを解凍しない場合、COMPRESSION_ERRORタイプの接続エラー (セクション5.4.1) で接続を終了しなければなりません (MUST)。
フィールドブロック内のデコードエラーは、COMPRESSION_ERRORタイプの接続エラー (セクション5.4.1) として扱わなければなりません (MUST)。
4.3.1. Compression State (圧縮状態)
フィールド圧縮はステートフルです。各エンドポイントには、接続上のすべてのフィールドブロックのエンコードとデコードに使用されるHPACKエンコーダーコンテキスト (HPACK Encoder Context) とHPACKデコーダーコンテキスト (HPACK Decoder Context) があります。[COMPRESSION] のセクション4は、各コンテキストの主要な状態である動的テーブル (Dynamic Table) を定義しています。
動的テーブルには、HPACKデコーダーによって設定される最大サイズがあります。エンドポイントは、SETTINGS_HEADER_TABLE_SIZE設定を使用して、HPACKデコーダーコンテキストが選択したサイズを通信します。セクション6.5.2を参照してください。接続が確立されると、両方のエンドポイントのHPACKデコーダーとエンコーダーの動的テーブルサイズは、SETTINGS_HEADER_TABLE_SIZE設定の初期値である4,096バイトから開始します。
SETTINGS_HEADER_TABLE_SIZEを使用して設定された最大値への変更は、エンドポイントが設定を確認したときに有効になります (セクション6.5.3)。そのエンドポイントのHPACKエンコーダーは、デコーダーが設定した最大値までの任意のサイズに動的テーブルを設定できます。HPACKエンコーダーは、動的テーブルサイズ更新命令 (Dynamic Table Size Update Instruction, [COMPRESSION] のセクション6.3) で動的テーブルのサイズを宣言します。
エンドポイントがSETTINGS_HEADER_TABLE_SIZEの変更を確認し、最大値が動的テーブルの現在のサイズを下回るように減少すると、そのHPACKエンコーダーは、動的テーブルを減少した最大値以下のサイズに設定する動的テーブルサイズ更新命令で次のフィールドブロックを開始しなければなりません (MUST)。[COMPRESSION] のセクション4.2を参照してください。最大動的テーブルサイズの削減の確認に続くフィールドブロックが、準拠した動的テーブルサイズ更新命令で開始されない場合、エンドポイントはそれをCOMPRESSION_ERRORタイプの接続エラー (セクション5.4.1) として扱わなければなりません (MUST)。
注意: 実装者は、SETTINGS_HEADER_TABLE_SIZEの値を減らすことは広く相互運用可能ではないことに注意してください。接続プリフェイスを使用して値を初期値4,096未満に減らすことは、いくらかサポートされていますが、一部の実装では失敗する可能性があります。