[40] [DFN[[CODE(HTTP)@en[[[HEADERS]]]]]] [[フレーム]]は、最初の[[ヘッダーブロック素片]]を表します。

* 仕様書

[REFS[
- [26] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-2.2>
- [27] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-4.1>
- [29] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-4.2>
- [31] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-5.1>
- [23] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-6.1>
- [1] '''[CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-6.2>'''
]REFS]

* 意味

[2] [CODE[[[HEADERS]]]] [[フレーム]] ([[フレーム型]] [CODE[[[0x1]]]])
は、[[ストリーム]]を開き、 [[header block fragment]] を伝送するものです [SRC[>>1]]。

* 構文

[18] [[ストリーム識別子]]欄は、[[フレーム]]を関連付ける[[ストリーム]]を表します。
[[ストリーム]]に関連付けなければ[['''なりません''']] [SRC[>>1]]。
[[ストリーム識別子]] [CODE[[[0x0]]]] を指定することはできません。

;; 選択方法は、[[ストリーム識別子]]を参照。

[11] 次の[[フラグ]]があります。
[FIG(list members)[
:[12] [CODE[[[END_STREAM]]]] ([CODE[[[0x1]]]] = 第0ビット):
設定されていれば、[[送信者]]が当該[[ストリーム]]で送信する最後の[[フレーム]]であることを表します
[SRC[>>1]]。
ただし設定されていても、 [CODE[[[CONTINUATION]]]] [[フレーム]]は同じ[[ストリーム]]で続いて送信できます [SRC[>>1]]。
:[14] [CODE[[[END_HEADERS]]]] ([CODE[[[0x4]]]] = 第2ビット):
設定されていれば、[[header block]] 全体が含まれており [CODE[[[CONTINUATION]]]]
[[フレーム]]が次に来ないことを表します [SRC[>>1]]。
[13] [CODE[[[END_HEADERS]]]] フラグが設定されていなければ、
同じ[[ストリーム]]で [CODE[[[CONTINUATION]]]] [[フレーム]]が来なければ[['''なりません''']]。
[SRC[>>1]]
:[16] [CODE[[[PADDED]]]] ([CODE[[[0x8]]]] = 第3ビット):
設定されていれば、[[詰め長]]と[[詰め]]の欄が存在することを表します [SRC[>>1]]。
:[17] [CODE[[[PRIORITY]]]] ([CODE[[[0x20]]]] = 第5ビット):
排他的 (E) フラグ、ストリーム依存性の欄、重みの欄が存在することを表します。 [SRC[>>1]]
]FIG]

[28] 他の[[フラグ]]は、0 でなければ[['''なりません''']]。
[[受信者]]は、無視しなければ[['''なりません''']]。 [SRC[>>27]]

[FIG(packet)[
:width:8

= 1 [CODE[[[END_STREAM]]]]
= 1 0
= 1 [CODE[[[END_HEADERS]]]]
= 1 [CODE[[[PADDED]]]]
= 1 0
= 1 [CODE[[[PRIORITY]]]]
= 1 0
= 1 0
]FIG]

[4] [[payload]] は次の欄で構成されます。
[FIG(list members)[
:[5] [RUBYB[[[詰め長]]]@en[Pad Length]]:
[[詰め]]の長さを[[バイト]]単位で表す8ビット欄です。
この欄は [CODE[[[PADDED]]]] フラグが設定されている時のみ存在します。 [SRC[>>1]]
値は0でも構いません。値が実際の[[詰め]]の長さを超えることは禁止されていませんが、
当然正しく処理できませんし、[[payload]] から固定長の部分の長さを引いた長さを超えるなら[[接続エラー]]となります。
:[6] [[E]] ([RUBYB[排他的]@en[Exclusive]]):
[[ストリーム依存性]]が[[排他的]]かどうかを表す1ビットのフラグです。
[CODE[[[PRIORITY]]]] フラグが設定されている時だけ存在します。 [SRC[>>1]]
:[7] [RUBYB[ストリーム依存性]@en[Stream Dependency]]:
[[ストリーム]]が依存する[[ストリーム]]の[[ストリーム識別子]]を表す31ビットの欄
([[ネットワークバイト順]] [SRC[>>26]]) です。
[CODE[[[PRIORITY]]]] フラグが設定されている時だけ存在します。 [SRC[>>1]]
:[8] [RUBYB[重み]@en[Weight]]:
[[ストリーム]]の[[優先度]]の[[重み]]を表す[[符号無し]]8ビット[[整数]]です。
重みは 1 [[以上]] 256 [[以下]]で、ここで指定するのはそれより 1 小さい値です。
[CODE[[[PRIORITY]]]] フラグが設定されている時だけ存在します。 [SRC[>>1]]
:[9] [RUBYB[ヘッダーブロック素片]@en[Header Block Fragment]]:
[[ヘッダーブロック素片]]です [SRC[>>1]]。[[payload]] の残りの部分です。
:[10] [RUBYB[詰め]@en[Padding]]:
詰めバイト列です [SRC[>>1]]。
詰め[[メッセージ]]の長さを隠すための[[セキュリティー]]機能です [SRC[>>23]]。
[[送信者]]は、すべて 0 の[[オクテット]]にしなければ[['''なりません''']] [SRC[>>23]]。
詰め長の長さより、詰めの最大長は、255バイトです。
]FIG]

[FIG(packet)[
:width:32

= 8 詰め長
= 1 E
= 31 ストリーム依存性
= 8 重み
= 48... header block fragment
= 32... 詰め
]FIG]

* 文脈

[3] [CODE[[[HEADERS]]]] [[フレーム]]は、[[ストリーム]]の状態が
[[idle]], [[reserved (local)]], [[open]], [[half-closed (remote)]]
のいずれかの時に送信できます [SRC[>>1]]。

[33] [CODE(HTTP)@en[[[HEADERS]]]] [[フレーム]]を [[idle]] 状態の[[ストリーム]]で送信すると、
[[open]] 状態に遷移します [SRC[>>31]]。 [CODE[[[END_STREAM]]]]
フラグも設定されていれば、そのまま更に [[half-closed (local)]]
状態に遷移します [SRC[>>31]]。

[34] [CODE(HTTP)@en[[[HEADERS]]]] [[フレーム]]を [[reserved (local)]] 状態の[[ストリーム]]で送信すると、
[[half-closed (remote)]] 状態に遷移します [SRC[>>31]]。

[36] [CODE[[[END_STREAM]]]] フラグが設定されている [CODE(HTTP)@en[[[HEADERS]]]] 
[[フレーム]]を [[open]] 状態の[[ストリーム]]で送信すると、 [[half-closed (local)]]
状態に遷移します [SRC[>>31]]。

[39] [CODE[[[END_STREAM]]]] フラグが設定されている [CODE(HTTP)@en[[[HEADERS]]]] 
[[フレーム]]を [[half-closed (remote)]] 状態の[[ストリーム]]で送信すると、 [[closed]]
状態に遷移します [SRC[>>31]]。

* 処理

[19] [[受信者]]は、[[ストリーム識別子]]が [CODE[[[0x0]]]] なら、
[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]] としなければ[['''なりません''']] [SRC[>>1]]。

[30] [[受信者]]は、[[payload]] が短すぎるか、[[設定]] [CODE[[[SETTINGS_MAX_FRAME_SIZE]]]]
より長いなら、[[接続エラー]] [CODE[[[FRAME_SIZE_ERROR]]]] としなければ[['''なりません''']]
[SRC[>>29]]。

[25] [[受信者]]は、詰め長が [[payload]] から固定長の部分を除いた長さより大きければ、
[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]] としなければ[['''なりません''']] [SRC[>>1]]。

[24] [[受信者]]は、[[詰め]]に 0 以外があれば[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]]
としても構いません。 [SRC[>>23]] 

[15] [CODE[[[END_HEADERS]]]] フラグが設定されていて次の[[フレーム]]が
[CODE[[[CONTINUATION]]]] [[フレーム]]以外だったり、
他の[[ストリーム]]だったりした場合は、[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]]
としなければ[['''なりません''']] [SRC[>>1]]。

[32] [CODE(HTTP)@en[[[HEADERS]]]] [[フレーム]]を [[idle]] 状態の[[ストリーム]]で受信すると、
[[open]] 状態に遷移します [SRC[>>31]]。 [CODE[[[END_STREAM]]]]
フラグも設定されていれば、そのまま更に [[half-closed (remote)]]
状態に遷移します [SRC[>>31]]。

[35] [CODE(HTTP)@en[[[HEADERS]]]] [[フレーム]]を [[reserved (remote)]] 状態の[[ストリーム]]で受信すると、
[[half-closed (local)]] 状態に遷移します [SRC[>>31]]。[CODE[[[END_STREAM]]]]
フラグも設定されていれば、そのまま更に [[closed]]
状態に遷移します [SRC[>>31]]。

[37] [CODE[[[END_STREAM]]]] フラグが設定されている [CODE(HTTP)@en[[[HEADERS]]]] 
[[フレーム]]を [[open]] 状態の[[ストリーム]]で受信すると、 [[half-closed (remote)]]
状態に遷移します [SRC[>>31]]。

[38] [CODE[[[END_STREAM]]]] フラグが設定されている [CODE(HTTP)@en[[[HEADERS]]]] 
[[フレーム]]を [[half-closed (local)]] 状態の[[ストリーム]]で受信すると、 [[closed]]
状態に遷移します [SRC[>>31]]。

[20] [[HTTPストリーム]]の状態遷移の項、[[ヘッダーリスト]]の項を参照。