フレーム (HTTP/2)

[2] フレーム (frame) は、HTTP/2接続中の通信の最小単位です。フレームヘッダーと可変長のオクテット列で構成されます。 >>1

仕様書

構文

[4] フレームは、9バイトヘッダーと、 可変長のpayload で構成されます >>3

[5] フレームヘッダーは、次の欄で構成されます >>3

長さ (Length)
payload の長さを符号無し24ビット整数 (ネットワークバイト順 >>1) で表現したものです。 >>3
(Type)
フレームの種類を表す8ビットの値です。 フレームの形式と意味が指定されます。 >>3
フラグ群 (Flags)
フレーム型依存の boolean フラグ用の 8ビットの欄です。 >>3
R
予約された1ビットの欄です。意味は定義されていません。値は 0 です。 受信者は無視することになっています。 >>3
ストリーム識別子 (Stream Identifier)
ストリーム識別子符号無し31ビット整数 (ネットワークバイト順 >>1) として表したものです。 >>3 接続全体を表す 0x0 を指定することもできますが、 フレーム型によっては認められていません。
Frame Payload
フレーム型に依存したデータです >>3。 長さは「長さ」欄で指定され、0のこともあります。

width
32:
  1. 24 Length
  2. 8 Type
  3. 8 Flags
  4. 1 R
  5. 31 ストリーム識別子
  6. 24... Frame Payload

フレーム型

[51] フレーム (Type) は、フレームの種類を表す8ビットの値です >>3

[52] フレームの形式と意味はフレーム型によって指定されます。 >>3

フレーム型の項を参照。

[46] 次のフレーム型があります。

[45] 0xf0-0xff は、実験用に予約されています >>43

[44] IANA登録簿 >>63 があります >>43

[62] 送信者は未知のフレーム型フレームを送ってはならないと思われますし、 送る必要もないはずです。

[7] 受信者は、未知のフレーム型フレームを無視し、捨てなければなりません >>3, >>29

[12] 無視とはいえ、フレームとしてのエラー (長さの問題など) の検証は行わなければならないと思われます。また、ヘッダーリストを構成するフレーム間では、 未知のフレーム型フレームはエラーとなります。
[61] ストリームの状態遷移の項も参照。

payload の長さ

[53] フレーム長さ (Length) 欄は、 payload の長さを符号無し24ビット整数 (ネットワークバイト順 >>1) で表現したものです >>3。単位はバイトです。 フレームの長さは、本欄に示された payload の長さの値 (とフレームヘッダーの 9 バイト) により決まります。

[54] payload の長さは、 0 以上の値です。

[6] payload の長さは、設定 SETTINGS_MAX_FRAME_SIZE の値よりも大きな値としてはなりません >>3

[55] 実際には、フレーム型依存の制約があるかもしれません。 各フレーム型の項を参照してください。

[32] 設定 SETTINGS_MAX_FRAME_SIZE (0x5) は、送信者受信する意志のある最大のフレームpayload の長さをバイト単位で表します >>31, >>3

[33]設定の初期値は 214 です >>31

[15] 本設定の値は、 214 以上、 224-1 以下でなければなりません >>3, >>31。 範囲外の値は、接続エラー PROTOCOL_ERROR としなければなりません >>31

[16] すべての実装は、 214 バイト以下payload を扱うことができなければなりません >>3

[17] payload の長さには、フレームヘッダーの長さ 9 は含まれていません。
[18] PING のように、フレーム型依存の payload の長さの制約が別にあるかもしれません。

[67] ChromeFirefox も、値域外の値が指定された時を含め、 完全に無視しているように見えます。少なくても接続エラーにはなりません。

[19] エンドポイントは、次の場合に FRAME_SIZE_ERROR エラー符号を送信しなければなりません >>3

[23] 接続全体の状態を変えてしまい得るフレームの長さのエラーは、 接続エラーとなければなりません >>3。これには次のものが含まれます。

[10] それ以外の場合は、ストリームエラーで良いものと思われます。

[39] SETTINGS_MAX_FRAME_SIZE を超える値だとしても、 接続エラーでなくストリームエラーとする場合、 次のフレームを正しく処理できるよう、 指定された長さ分通常通り読む (読み飛ばす) 必要があります。

[40] FirefoxDATA フレームであっても SETTINGS_MAX_FRAME_SIZE を超える長さの時、 接続エラー PROTOCOL_ERROR とするようです。 更に大量のデータを受信している場合には GOAWAY を送信せずすぐに接続を閉じるようです。

[42] ChromeDATASETTINGS_MAX_FRAME_SIZE の検査をしないようです。

[64] FirefoxChrome も、HEADERS の payload は 218 までエラーとはしません。 218+1 以上のヘッダーを受信すると、 214 まで受信を待ちます。 その後 Firefox接続エラー PROTOCOL_ERRORChrome接続エラー FRAME_SIZE_ERROR とします。ただしその後更にデータを受信した場合は、 GOAWAY を送信せずに直ちに接続を閉じるようです (閾値は payload のサイズが Chrome で 214Firefox で 215 弱のようです)。

[11] RST_STREAM フレームWINDOW_UPDATE フレームの長さのエラーも、 接続エラーとなります。

それぞれの項を参照。

[34] FRAME_SIZE_ERROR (0x6) は、 非妥当なサイズのフレームを受信したことを示します >>13

[49] 実際のデータの長さより長い payload の長さが指定された時にどうするべきかは不明です。

[50] フレームを受信し終える前に接続が閉じられた場合や、 HTTP2-Settings: ヘッダーの値が不完全な場合があり得ます。

フラグ

[56] フレームフラグ群 (Flags) は、 boolean フラグ用の8ビットの欄です。 >>3

[57] 8つのビットごとに、フレーム型に依存 >>3 した意味が定義されているか、 未定義のままとされています。

[60] 次のフラグがあります。ただしすべてのフレーム型で定義されているわけではありませんし、 第0ビットはフレーム型により異なる意味が割り当てられています。

width
8
  1. 1 END_STREAM / ACK
  2. 1 0
  3. 1 END_HEADERS
  4. 1 PADDED
  5. 1 0
  6. 1 PRIORITY
  7. 1 0
  8. 1 0

フレーム型の項を参照。

[8] 送信者は、フレーム型によりフラグ群の意味が定義されていない場合、 0 を設定しなければなりません >>3

[9] 受信者は、フレーム型によりフラグ群の意味が定義されていない場合、 無視しなければなりません >>3

[65] Chrome は未定義のフラグを受信したら、 接続エラー PROTOCOL_ERROR とします。 Firefox は無視します。

文脈

[47] フレームは、ストリーム上のバイト列として送受信されます。

[48] SETTINGS フレームは、 HTTP/1.1 HTTP2-Settings: ヘッダー内に含まれることがあります。

処理

[27] フレームの送受信は、ストリームの状態を変化させます。 状態によっては、受信したらエラーとしなければならないフレーム型もあります。

[28] フレームの処理は、フレーム型によって異なります。

フレーム型の項も参照。

[58] 小さなフレームpayload が空のフレームは、 無駄な処理をさせるために濫用できます。 エンドポイントは利用状況を監視して制限するべきです接続エラー ENHANCE_YOUR_CALM としても構いません。 >>59

[35] ただし DATA など空や小サイズでも正当な場合も多々あります。

[66] ChromeFirefox も、フレームの途中まで受信した時に残りを受信するまでの特別なタイムアウトは用意していないように見えます。 Firefox は定期的に PING を送信するので、それに応答がないことにより接続が閉じられます。

実装

[36] ChromeFirefox も、 FRAME_SIZE_ERROR ではなく PROTOCOL_ERROR を使っているようです。

[37] Chrome はフレームのヘッダー部分を読んだ時点でエラーを検査しているように見えます。 Firefox は payload まですべて読んでから検査しているように見えます。

[38] ChromeSETTINGS_MAX_FRAME_SIZE を超えていないかの検査をしていないように見えます。

[41] フレームのヘッダーの途中や payload として指定された長さに満たずに接続が閉じられた場合、 Firefox は (正常終了なら) GOAWAY (NO_ERROR) を送信し、 Chrome はそのまま、接続を閉じるようです。 どちらも要求ネットワークエラーになります。

[68] Firefox接続序文SETTINGS_MAX_FRAME_SIZE に 214 を設定しますが、これは初期値と同じです。

[69] The ORIGIN HTTP/2 Frame () http://httpwg.org/http-extensions/origin-frame.html

[70] draft-hoffman-dns-in-existing-http2-00 - Running DNS in Existing HTTP/2 Connections () https://tools.ietf.org/html/draft-hoffman-dns-in-existing-http2-00

[71] 無職転生Ⅱ ~異世界行ったら本気だす~ 13話上映会 - 2024/4/11(木) 0:00開始 - ニコニコ生放送 () https://live.nicovideo.jp/watch/lv344746642