メインコンテンツまでスキップ

3. カプセル (Capsules)

HTTP を拡張する1つのメカニズムは、新しい HTTP アップグレードトークン (HTTP upgrade tokens) を導入することです ([HTTP] のセクション 16.7 を参照)。HTTP/1.x では、これらのトークンはアップグレードメカニズム (Upgrade mechanism) を介して使用されます ([HTTP] のセクション 7.8 を参照)。HTTP/2 および HTTP/3 では、これらのトークンは拡張 CONNECT メカニズム (Extended CONNECT mechanism) を介して使用されます ([EXT-CONNECT2] および [EXT-CONNECT3] を参照)。

本仕様では、カプセルプロトコル (Capsule Protocol) を導入します。カプセルプロトコルは、新しい HTTP アップグレードトークンの定義が使用することを選択できる、型-長さ-値 (type-length-value) タプルのシーケンスです。これにより、HTTP 中継者 (HTTP intermediaries) が存在する場合でも、エンドポイントは HTTP リクエストストリーム上でリクエスト関連情報をエンドツーエンドで確実に通信できます。カプセルプロトコルは、HTTP データグラムを交換するために使用できます。これは、HTTP が QUIC DATAGRAM フレームをサポートしないトランスポート上で実行されている場合に必要です。カプセルプロトコルは、HTTP/3 データグラムが使用されている場合でも、データグラムベースのプロトコルに関連する信頼性のある双方向制御メッセージを通信するためにも使用できます。

3.1. HTTP データストリーム (HTTP Data Streams)

本仕様では、HTTP リクエストの「データストリーム (data stream)」を、リクエストメッセージのヘッダーセクションと、成功 (2xx) またはアップグレード (101) のいずれかである最終レスポンスメッセージに続く、双方向のバイトストリームとして定義します。

HTTP/1.x では、データストリームは、リクエストヘッダーセクションまたは最終レスポンスヘッダーセクションのいずれかを終了する空白行に続く、接続上のすべてのバイトで構成されます。その結果、HTTP/1.x 接続上の最後の HTTP リクエストのみがカプセルプロトコルを開始できます。

HTTP/2 および HTTP/3 では、特定の HTTP リクエストのデータストリームは、対応するストリーム ID を持つ DATA フレームで送信されるすべてのバイトで構成されます。

データストリームの概念は、ヘッダーの後に HTTP メッセージコンテンツがない CONNECT などのメソッドに特に関連します。

データストリームは、ストリームまたはリクエストの優先順位付けに適した任意の手段を使用して優先順位付けできます。例えば、[PRIORITY] のセクション 11 を参照してください。

データストリームは、基盤となる層のフロー制御メカニズムの対象となります。例としては、HTTP/2 ストリームフロー制御、HTTP/2 接続フロー制御、TCP フロー制御などがあります。

3.2. カプセルプロトコル (The Capsule Protocol)

新しい HTTP アップグレードトークンの定義は、関連するリクエストのデータストリームがカプセルプロトコルを使用することを述べることができます。そうする場合、関連するリクエストのデータストリームの内容は次の形式を使用します:

Capsule Protocol {
Capsule (..) ...,
}

図 2: カプセルプロトコルストリーム形式

Capsule {
Capsule Type (i),
Capsule Length (i),
Capsule Value (..),
}

図 3: カプセル形式

Capsule Type (カプセルタイプ): カプセルのタイプを示す可変長整数です。IANA レジストリがカプセルタイプの割り当てを管理するために使用されます (セクション 5.4 を参照)。

Capsule Length (カプセル長): このフィールドに続く Capsule Value フィールドの長さ (バイト単位) であり、可変長整数としてエンコードされます。このフィールドはゼロの値を持つことができることに注意してください。

Capsule Value (カプセル値): このカプセルのペイロードです。そのセマンティクスは、Capsule Type フィールドの値によって決定されます。

中継者 (intermediary) は、Capsule-Protocol ヘッダーフィールドの存在 (セクション 3.4) を通じて、または選択された HTTP アップグレードトークンを理解することによって、カプセルプロトコルの使用を識別できます。

新しいプロトコルまたは拡張機能が新しいカプセルタイプを定義する可能性があるため、将来の拡張性を許可したい中継者は、使用中のカプセルタイプの定義が追加の中継者処理を指定しない限り、カプセルを変更せずに転送すべきです (SHOULD)。そのようなカプセルタイプの1つは DATAGRAM カプセルです (セクション 3.5 を参照)。特に、中継者は未知のカプセルタイプを持つカプセルを変更せずに転送すべきです (SHOULD)。

未知のカプセルタイプを持つカプセルを受信したエンドポイントは、そのカプセルを黙って破棄し、それをスキップして次のカプセルを解析しなければなりません (MUST)。

データストリームの定義により:

  • カプセルプロトコルは、レスポンスに 2xx (成功) または 101 (プロトコル切り替え) ステータスコードが含まれない限り、使用されません。

  • カプセルプロトコルが使用されている場合、関連する HTTP リクエストとレスポンスは HTTP コンテンツを運びません。将来の拡張機能は、HTTP コンテンツを運ぶ新しいカプセルタイプを定義してもよい (MAY) です。

カプセルプロトコルは、新しい HTTP アップグレードトークンの定義にのみ適用されます。したがって、HTTP/2 および HTTP/3 では、CONNECT メソッドでのみ使用できます。したがって、両方のエンドポイントがカプセルプロトコルの使用に同意すると、ストリームのフレーム使用要件が [HTTP/2] のセクション 8.5 および [HTTP/3] のセクション 4.4 で指定されているように変更されます。

カプセルプロトコルは、Content-Length、Content-Type、または Transfer-Encoding ヘッダーフィールドを含むメッセージで使用してはなりません (MUST NOT)。さらに、HTTP ステータスコード 204 (No Content)、205 (Reset Content)、および 206 (Partial Content) は、カプセルプロトコルを使用するレスポンスで送信してはなりません (MUST NOT)。これらの要件の違反を観察した受信者は、HTTP メッセージを不正な形式として扱わなければなりません (MUST)。

カプセルを処理する際、受信者は、それを処理する前にデータストリーム内の Capsule Value フィールドの全長を蓄積したくなるかもしれません。このアプローチは、基盤となる層のフロー制御を消費する可能性があり、カプセルデータがフロー制御ウィンドウを使い果たすとデッドロックにつながる可能性があるため、避けるべきです (SHOULD)。

3.3. エラー処理 (Error Handling)

受信者がカプセルプロトコルの処理中にエラーに遭遇した場合、受信者は、不正な形式または不完全な HTTP メッセージを受信した場合と同じように扱わなければなりません (MUST)。HTTP/3 の場合、不正な形式のメッセージの処理は [HTTP/3] のセクション 4.1.2 に記載されています。HTTP/2 の場合、不正な形式のメッセージの処理は [HTTP/2] のセクション 8.1.1 に記載されています。HTTP/1.x の場合、不完全なメッセージの処理は [HTTP/1.1] のセクション 8 に記載されています。

各カプセルのペイロードは、その説明で識別されたフィールドを正確に含んでいなければなりません (MUST)。識別されたフィールドの後に追加のバイトを含むカプセルペイロード、または識別されたフィールドの終わりの前に終了するカプセルペイロードは、不正な形式または不完全なメッセージであるかのように扱わなければなりません (MUST)。特に、冗長な長さエンコーディングは、自己一貫性があることを検証しなければなりません (MUST)。

カプセルを運ぶストリームの受信側がクリーンに終了され (例えば、HTTP/3 では、これは FIN ビットが設定された QUIC STREAM フレームを受信することとして定義されています)、ストリーム上の最後のカプセルが切り捨てられた場合、これは不正な形式または不完全なメッセージであるかのように扱わなければなりません (MUST)。

3.4. Capsule-Protocol ヘッダーフィールド (The Capsule-Protocol Header Field)

「Capsule-Protocol」ヘッダーフィールドは、アイテム構造化フィールド (Item Structured Field) です ([STRUCTURED-FIELDS] のセクション 3.3 を参照)。その値はブール値でなければなりません (MUST)。その他の値タイプは、受信者によってフィールドが存在しないかのように処理されなければなりません (MUST) (例えば、このフィールドが複数回含まれている場合、そのタイプはリストになり、フィールドは無視されます)。本文書は、Capsule-Protocol ヘッダーフィールド値のパラメータを定義していませんが、将来の文書がパラメータを定義する可能性があります。受信者は未知のパラメータを無視しなければなりません (MUST)。

エンドポイントは、true 値の Capsule-Protocol ヘッダーフィールドを送信することにより、データストリームでカプセルプロトコルが使用されていることを示します。false 値の Capsule-Protocol ヘッダーフィールドは、ヘッダーが存在しない場合と同じセマンティクスを持ちます。

中継者は、未知の HTTP アップグレードトークンの HTTP データグラムの処理を許可するために、このヘッダーフィールドを使用してもよい (MAY) です。これは、HTTP アップグレードまたは拡張 CONNECT の場合にのみ可能であることに注意してください。

Capsule-Protocol ヘッダーフィールドは、101 (プロトコル切り替え) とは異なり、2xx (成功) 範囲外のステータスコードを持つ HTTP レスポンスで使用してはなりません (MUST NOT)。

カプセルプロトコルを使用する場合、HTTP エンドポイントは、中継者の処理を簡素化するために Capsule-Protocol ヘッダーフィールドを送信すべきです (SHOULD)。カプセルプロトコルを使用する新しい HTTP アップグレードトークンの定義は、この推奨事項を変更してもよい (MAY) です。

3.5. DATAGRAM カプセル (The DATAGRAM Capsule)

本文書は、DATAGRAM (0x00) カプセルタイプを定義します。このカプセルにより、カプセルプロトコルを使用してストリーム上で HTTP データグラムを送信できます。これは、HTTP が QUIC DATAGRAM フレームをサポートしないトランスポート上で実行されている場合に特に有用です。

Datagram Capsule {
Type (i) = 0x00,
Length (i),
HTTP Datagram Payload (..),
}

図 4: DATAGRAM カプセル形式

HTTP Datagram Payload (HTTP データグラムペイロード): データグラムのペイロードであり、そのセマンティクスは HTTP データグラムを使用している拡張機能によって定義されます。このフィールドは空でもよい (MAY) ことに注意してください。

DATAGRAM カプセルを使用して送信される HTTP データグラムは、QUIC DATAGRAM フレームで送信されるものと同じセマンティクスを持ちます。特に、HTTP データグラムを送信することが許可されるタイミングとそれらを処理する方法に関する制限 (セクション 2.1 から) は、DATAGRAM カプセルを使用して送信および受信される HTTP データグラムにも適用されます。

中継者は、HTTP データグラムを転送する際に再エンコードできます。言い換えれば、中継者は、QUIC DATAGRAM フレームで受信された HTTP データグラムを転送するために DATAGRAM カプセルを送信してもよく (MAY)、その逆も可能です。中継者は、対応するリクエストストリームでカプセルプロトコルの使用を識別していない限り、この再エンコードを実行してはなりません (MUST NOT) (セクション 3.2 を参照)。

ストリーム上で送信される DATAGRAM カプセルは順序どおりに確実に配信されますが、中継者がメッセージを転送する際に DATAGRAM カプセルを QUIC DATAGRAM フレームに再エンコードできるため、損失または順序変更が発生する可能性があることに注意してください。

中継者が QUIC DATAGRAM フレームで HTTP データグラムを受信し、QUIC DATAGRAM フレームをサポートする接続で転送している場合、中継者はその HTTP データグラムを DATAGRAM カプセルに変換すべきではありません (SHOULD NOT)。HTTP データグラムが DATAGRAM フレームに収まるには大きすぎる場合 (例えば、その QUIC 接続のパス MTU (PMTU) が低すぎるため、またはその接続で通知された最大 UDP ペイロードサイズが低すぎるため)、中継者は、それを DATAGRAM カプセルに変換する代わりに、HTTP データグラムを破棄すべきです (SHOULD)。これにより、データグラムパケット化レイヤー PMTU ディスカバリー (DPLPMTUD) などのメソッドが依存するエンドツーエンドの非信頼性特性が保持されます [DPLPMTUD]。QUIC DATAGRAM フレームを DATAGRAM カプセルに変換する中継者は、HTTP データグラムを損失なしで任意に大きくすることを許可します。これにより、真のパス特性が誤って表現され、DPLPMTUD などのメソッドが無効になる可能性があります。

DATAGRAM カプセルは理論的には長さ 2^62-1 のペイロードを運ぶことができますが、HTTP データグラムを使用するほとんどの HTTP 拡張機能には、実用的なデータグラムペイロードサイズに独自の制限があります。実装は、DATAGRAM カプセルを解析する際にこれらの制限を考慮すべきです (SHOULD)。受信 DATAGRAM カプセルの長さが使用できないほど大きいことがわかっている場合、実装は、その内容をメモリにバッファリングせずにカプセルを破棄すべきです (SHOULD)。

QUIC DATAGRAM フレームは QUIC パケット内に収まる必要があるため、DATAGRAM カプセルを QUIC DATAGRAM フレームに再エンコードする実装は、再エンコードする前にストリーム内のカプセル全体を蓄積したくなるかもしれません。これは、フロー制御の問題を引き起こす可能性があるため、避けるべきです (SHOULD) (セクション 3.2 を参照)。

HTTP 拡張機能が、カプセルプロトコルを使用せずに HTTP データグラムを使用することは可能であることに注意してください。例えば、HTTP データグラムを使用する HTTP 拡張機能が QUIC DATAGRAM フレームをサポートするトランスポート上でのみ定義されている場合、ストリームエンコーディングは必要ないかもしれません。さらに、HTTP 拡張機能は、独自のデータストリームプロトコルで HTTP データグラムを使用できます。ただし、HTTP データグラムを使用したい新しい HTTP 拡張機能は、カプセルプロトコルを使用すべきです (SHOULD)。そうしないと、HTTP 拡張機能が HTTP/3 以外のバージョンの HTTP をサポートすることが難しくなり、カプセルプロトコルのみをサポートする中継者との相互運用性が妨げられます。