[32] [[HTTP/2]] [DFN[[CODE(HTTP)@en[[[DATA]]]]]] [[フレーム]]は、
[[HTTPメッセージ]]の [[payload body]] を転送するための[[フレーム]]です。
[[payload body]] は、1個[[以上]]の [CODE(HTTP)@en[[[DATA]]]]
[[フレーム]]によって表します。

* 仕様書

[REFS[
- [21] [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>
- [24] [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>
- [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-5.1>
- [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.2.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.1>'''
- [19] [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.9>
]REFS]

* 意味

[2] [CODE[[[DATA]]]] [[フレーム]] ([[フレーム型]] [CODE[[[0x0]]]]) は、
[[ストリーム]]に関連付けられた任意の可変長の[[バイト列]]を伝送するものです [SRC[>>1]]。

[14] [CODE[[[DATA]]]] [[フレーム]]は、[[フロー制御]]の対象となります [SRC[>>1, >>31, >>19]]。

[15] [CODE[[[DATA]]]] [[フレーム]]は、[[ストリーム]]の状態が [[open]]
か [[half-closed (remote)]] の場合のみ送信できます [SRC[>>1]]。

* 構文

[12] [CODE[[[DATA]]]] [[フレーム]]は、[[ストリーム]]と関連付けなければ[['''なりません''']]
[SRC[>>1]]。[[ストリーム識別子]]が [CODE[[[0x0]]]] であってはなりません。

[8] [CODE[[[DATA]]]] [[フレーム]]は、次の[[フラグ]]を持ちます。
[FIG(list members)[
:[9] [CODE[[[END_STREAM]]]] ([CODE[[[0x1]]]] = 第0ビット):
設定されていれば当該[[ストリーム]]の当該[[送信者]]からの最後の[[フレーム]]であることを表します。 [SRC[>>1]]
[[ストリーム]]の状態遷移の項も参照。
:[10] [CODE[[[PADDED]]]] ([CODE[[[0x8]]]] = 第3ビット):
設定されていれば詰め長と詰めの欄が含まれることを表します。 [SRC[>>1]]
]FIG]

[22] その他の[[フラグ]]は、 0 に設定しなければ[['''なりません''']]。
[[受信者]]は無視しなければ[['''なりません''']]。 [SRC[>>21]]

[FIG(packet)[
:width:8

= 1 [CODE[[[END_STREAM]]]]
= 1 0
= 1 0
= 1 [CODE[[[PADDED]]]]
= 1 0
= 1 0
= 1 0
= 1 0
]FIG]

[5] [CODE[[[DATA]]]] [[フレーム]]の [[payload]] は、次の欄で構成されます。
[FIG(list members)[
:[6] [RUBYB[[[詰め長]]]@en[Pad Length]]:
[[詰め]]の長さを[[バイト]]単位で8ビットで表したものです。
[CODE[[[PADDED]]]] フラグが設定されている場合のみ存在します。 [SRC[>>1]]
値は0でも構いません。値が実際の[[詰め]]の長さを超えることは禁止されていませんが、
:[7] [RUBYB[データ]@en[Data]]:[[応用データ]]です。
データは、[[フレーム]]の [[payload]] から詰め長と詰めを除去したものです。 [SRC[>>1]]
当然正しく処理できませんし、[[payload]] の長さを超えるなら[[接続エラー]]となります。
:[4] [RUBYB[[[詰め]]]@en[Padding]]:
[[メッセージ]]の長さを隠すための[[セキュリティー]]機能です。
[[送信者]]は、すべて 0 の[[オクテット]]にしなければ[['''なりません''']]。 [SRC[>>1]]
詰め長の長さより、詰めの最大長は、255バイトです。
]FIG]

[FIG(packet)[
:width:32

= 8 詰め長
= 88... データ
= 32... 詰め
]FIG]

;; [16] [[フロー制御]]の対象となるのは [[payload]] 全体であり、[[詰め]]も含まれます
[SRC[>>1]]。

* 文脈

[3] [[HTTP要求]]や [[HTTP応答]]の [[payload]] の転送に、1つ[[以上]]の
[CODE[[[DATA]]]] [[フレーム]]を使うことができます [SRC[>>1]]。

;; [[HTTPメッセージ]]も参照。

[25] [CODE[[[END_STREAM]]]] フラグが設定されている [CODE(HTTP)@en[[[DATA]]]] 
[[フレーム]]を [[open]] 状態の[[ストリーム]]で送信すると、 [[half-closed (local)]]
状態に遷移します [SRC[>>26]]。

[29] [CODE[[[END_STREAM]]]] フラグが設定されている [CODE(HTTP)@en[[[DATA]]]] 
[[フレーム]]を [[half-closed (remote)]] 状態の[[ストリーム]]で送信すると、 [[closed]]
状態に遷移します [SRC[>>26]]。

* 処理

[36] [[フレーム]]の処理の項も参照。

[13] [[受信者]]は、[CODE[[[DATA]]]] [[フレーム]]の[[ストリーム識別子]]が [CODE[[[0x0]]]]
なら、[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]] としなければ[['''なりません''']]
[SRC[>>1]]。

;; [20] [[Chrome]] はこの検査をしていないようです。 [[Firefox]]
は仕様通りエラーとします。 [TIME[2015-09-28T07:35:56.00Z]]

[23] [[受信者]]は、[[payload]] が短すぎるか、[[設定]] [CODE[[[SETTINGS_MAX_FRAME_SIZE]]]]
より長いなら、[[エラー]] [CODE[[[FRAME_SIZE_ERROR]]]] としなければ[['''なりません''']]
[SRC[>>24]] (おそらく[[ストリームエラー]])。

;; [35] [CODE[[[PADDED]]]] フラグが設定されているのに payload の長さが0の時、
[[Chrome]] はデータの長さが0として扱います。 [[Firefox]] は続きを待ち続けるように見えます。
[TIME[2015-09-28T08:03:32.900Z]]

[17] [[受信者]]は、[[ストリーム]]の状態が [[open]] か [[half-closed (local)]]
でなければ、[[ストリームエラー]] [CODE[[[STREAM_CLOSED]]]] としなければ[['''なりません''']]
[SRC[>>1]]。
ただし場合によっては [[closed]] で受信しても無視します [SRC[>>26]]。

[30] [[closed]] で無視する場合でも、状況によっては[[フロー制御窓]]の計算には算入します
[SRC[>>26]]。

;; [[ストリーム]]の状態遷移の項を参照。

[27] [CODE[[[END_STREAM]]]] フラグが設定されている [CODE(HTTP)@en[[[DATA]]]] 
[[フレーム]]を [[open]] 状態の[[ストリーム]]で受信すると、 [[half-closed (remote)]]
状態に遷移します [SRC[>>26]]。

[28] [CODE[[[END_STREAM]]]] フラグが設定されている [CODE(HTTP)@en[[[DATA]]]] 
[[フレーム]]を [[half-closed (remote)]] 状態の[[ストリーム]]で受信すると、 [[closed]]
状態に遷移します [SRC[>>26]]。

[11] [[受信者]]は、[[詰め]]に 0 以外があれば[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]]
としても構いません。 [SRC[>>1]] 

;; [33] [[Chrome]] も [[Firefox]] もこの検査をしないようです。 [TIME[2015-09-28T07:49:09.000Z]]

[18] [[受信者]]は、詰め長が [[payload]] の長さ[[以上]]なら、
[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]] としなければ[['''なりません''']] [SRC[>>1]]。

;; [34] [[Chrome]] はこれを検査しますが、 [[Firefox]] はしないようです
(データが長さ0になります)。
[TIME[2015-09-28T07:49:31.800Z]]