WebTransport using HTTP/2
2021-04-20 時点での DeepL Pro による翻訳。
HTTP/2を使ったWebTransport
概要
WebTransport [概要] は、Web セキュリティモデルの制約を受けるクライアントが、安全な多重トランスポートを使用してリモートサーバーと通信できるようにするプロトコルフレームワークです。このドキュメントでは、HTTP/2 [RFC7540] をベースにした WebTransport プロトコルについて説明しています。このプロトコルでは、同じ HTTP/2 接続内で多重化された一方向ストリーム、双方向ストリーム、データグラムをサポートしています。
1. はじめに
現在、HTTP/2 におけるサーバーからクライアントへの通信の仕組みは、サーバープッシュのみです。つまり、サーバーはクライアントに対して一方的なプッシュプロミスストリームを開始することができますが、クライアントはそれに応答することができず、受け入れるか破棄するかしかできません。さらに、経路上の仲介者は異なるサーバープッシュポリシーを持っている可能性があり、プッシュプロミスされたストリームを下流のクライアントに転送しないかもしれません。このようなベストエフォート型のメカニズムでは、サーバーからクライアントにメッセージを確実に配信するには不十分であり、チャットメッセージや通知など、サーバーからクライアントへのユースケースが制限されてしまいます。
これらの制限を回避するために、ロングポーリング(RFC6202)、WebSocket(RFC8441)、CONNECTメソッドによるトンネリングなどの技術が開発されてきました。これらの手法にはいずれも限界があります。
本ドキュメントでは、WebTransport プロトコルの要件とセマンティクス [概要] に準拠した方法で、HTTP/2 で非 HTTP データを多重化するメカニズムを定義しています。ここで説明するメカニズムを使用すると、複数の WebTransport インスタンスを、同じ HTTP/2 接続上の通常の HTTP トラフィックと同時に多重化することができます。
1.1. 用語の説明
本文書のキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「NOT RECOMMENDED」、「MAY」、「OPTIONAL」は、ここに示すようにすべて大文字で表示されている場合に限り、BCP 14 [RFC2119] [RFC8174]に記載されているとおりに解釈される。
本文書は,[OVERVIEW]の1.2節で定義された用語に従っている。この文書では、WebTransport サーバーと HTTP/2 サーバーを区別していることに注意してください。HTTP/2 サーバーとは、HTTP/2 接続を終了するサーバーであり、WebTransport サーバーとは、HTTP/2 サーバーを介してアクセスできる WebTransport セッションを受け入れるアプリケーションです。
2. プロトコルの概要
WebTransport サーバーは、オーソリティ値とパス値のペアで識別されます (対応する [RFC3986] セクション 3.2 および 3.3 で定義されています)。
HTTP/2 接続が確立すると、クライアントとサーバーの両方が HTTP/2 上の WebTransport をサポートしていることを示すために、SETTINGS_ENABLE_WEBTRANSPORT 設定を送信する必要があります。
WebTransport セッションは、クライアントが拡張 CONNECT リクエスト [RFC8441] を送信することで、HTTP/2 コネクション内で開始されます。サーバーがリクエストを受け入れると、WebTransport セッションが確立されます。生成されたストリームは、CONNECT ストリームと呼ばれ、そのストリーム ID は接続内の WebTransport セッションを一意に識別するために使用されます。あるWebTransportセッションを確立したCONNECTストリームのIDは、さらに「セッションID」と呼ばれます。
セッションの確立後、ピアは以下のメカニズムでデータを交換できます。
- クライアントとサーバーの両方が、新しい HTTP/2 拡張フレーム(WT_STREAM)を使用して、双方向または単方向のストリームを作成できます。
- データグラムは、新しい HTTP/2 拡張フレーム WT_DATAGRAM を使用して送信できます。
WebTransport セッションは、セッションを作成した CONNECT ストリームが閉じられると終了します。
3. セッションの確立
3.1. トランスポート対応の HTTP/2 接続の確立
WebTransport のサポートを示すために、クライアントとサーバーは SETTINGS フレームで SETTINGS_ENABLE_WEBTRANSPORT の値を "1" に設定して送信しなければなりません (MUST)。エンドポイントは、このパラメータがネゴシエートされていない限り、WebTransport 関連の機能を使用してはなりません (MUST NOT)。
3.2. HTTP/2 の拡張 CONNECT
SETTINGS_ENABLE_CONNECT_PROTOCOL パラメーターで有効になる拡張 CONNECT メソッドを [RFC8441] はセクション 4 で定義しています。エンドポイントは SETTINGS_ENABLE_CONNECT_PROTOCOL と SETTINGS_ENABLE_WEBTRANSPORT の両方を送信する必要はなく、SETTINGS_ENABLE_WEBTRANSPORT の設定はエンドポイントが拡張 CONNECT をサポートしていることを意味します。
3.3. 新しいセッションの作成
WebTransport のセッションは HTTP/2 で確立されるので、https URI スキーム [RFC7230] を使って識別されます。
新しい WebTransport セッションを作成するには、クライアントは HTTP CONNECT リクエストを送信します。:protocol 疑似ヘッダフィールド ([RFC8441]) は webtransport に設定しなければなりません (セクション 7.1 [WEBTRANSPORT-H3])。:schemeフィールドはhttpsでなければなりません。また、:authority と :path の両方が設定されていなければなりません(これらのフィールドは希望する WebTransport サーバを示します)。リクエストにはOriginヘッダ[RFC6454]が含まれていなければなりません。
protocol フィールドに webtransport が設定された拡張 CONNECT リクエストを受信すると、HTTP/2 サーバーは指定された :authority と :path の値に関連付けられた WebTransport サーバーがあるかどうかを確認できます。存在しない場合は、ステータスコード404(セクション6.5.4, [RFC7231])で応答するべきです(SHOULD)。そうでない場合は、ステータスコード200で応答してセッションを受け入れてもよい(MAY)。WebTransport サーバは、Origin ヘッダを検証して、指定されたオリジンが当該サーバへのアクセスを許可されていることを確認しなければなりません(MUST)。
クライアントから見ると、200 のレスポンスを受信した時点で WebTransport セッションが確立されます。サーバ側から見ると、200レスポンスを送信した時点でセッションが確立されます。どちらのエンドポイントも、セッションが確立する前に、特定のセッションでストリームを開いたり、データグラムを送信したりしてはいけません(MUST NOT)。
3.4. 同時セッション数の制限
WebTransport のセッションは、HTTP CONNECT リクエストで確立されるため、フロー制御の観点からは、通常の HTTP リクエストと同様に、ストリームのフロー制御にカウントされます。このドキュメントでは、セッション用に別のフロー制御メカニズムを導入したり、HTTP リクエストを WebTransport データ ストリームから分離したりすることはしていません。サーバーが受信するリクエストの速度を制限する必要がある場合は、別のメカニズムを使用できます。
- RFC7540] で定義されている HTTP_STREAM_REFUSED エラーコードは、受信側の HTTP/2 スタックに、リクエストが何らかの形で処理されなかったことを示します。
- HTTP ステータスコード 429 は、レート制限 [RFC6585] によりリクエストが拒否されたことを示します。前述の方法とは異なり、このシグナルはアプリケーションに直接伝わります。
4. WebTransport の機能
HTTP/2 上の WebTransport は、[概要] に記載されている以下の機能を提供します: どちらかのエンドポイントから開始される一方向ストリーム、双方向ストリーム、データグラム。
セッション ID は、異なる WebTransport セッションに属するストリームとデータグラムを分断するために使用されます。ワイヤー上では、セッションIDは31ビットの整数フィールドを使ってエンコードされます。
4.1. WT_STREAM フレーム
どちらかのエンドポイントがWebTransportストリームを確立するために、WT_STREAMと呼ばれる新しいHTTP/2フレームが導入されます。WT_STREAM フレームは、"idle"、"reserved (local)"、"open"、または "half-closed (remote) "状態のストリームで送信することができます。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+
|Pad Length? (8)|
+-+-------------+-----------------------------------------------+
|R| Session ID (31) |
+-+-------------------------------------------------------------+
| Padding (*) ...
+---------------------------------------------------------------+
図1:WT_STREAMフレームフォーマット
WT_STREAMフレームでは、以下のフィールドが定義されています。
パッド長。WT_STREAMフレームでは以下のフィールドが定義されています: Pad Length: オクテット単位のフレームパディングの長さを含む8ビットのフィールド。このフィールドは条件付きで、PADDEDフラグが設定されている場合にのみ存在します(図中の「?」で示される)。
セッションID。このWebトランスポートストリームのストリーム・コネクトストリームを識別する符号なしの31ビット整数。セッションIDは、"webtransport "の:protocol値を持つ拡張CONNECTプロトコルを介してネゴシエートされたオープンストリームでなければならない(MUST)。
WT_STREAMフレームでは、以下のフラグが定義されています。
UNIDIRECTIONAL(0x1)。UNIDIRECTIONAL (0x1): 設定されていると、ストリームは送信側では「half-closed (remote)」状態で始まり、受信側では「half-closed (local)」状態になります。
すべての HTTP/2 ストリームと同様に、クライアントが開始した WebTransport ストリームは奇数のストリーム ID を持ち、サーバーが開始したストリームは偶数のストリーム ID を持ちます。
指定されたWebTransport接続ストリームが存在しない場合、"webtransport "プロトコルを使用するために拡張CONNECTで確立されたストリームではない場合、またはストリームの状態が "closed "または "half-closed (remote) "である場合、受信者はWT_STREAM_ERROR型のストリームエラーで応答しなければなりません(MUST)。
4.2. WT_DATAGRAM フレーム
いずれかのエンドポイントがデータグラムを送信するために、WT_DATAGRAM と呼ばれる新しい HTTP/2 フレームが導入されます。WT_DATAGRAM フレームは Stream Identifier 0 で送信されます。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+
|Pad Length? (8)|
+-+-------------+-----------------------------------------------+
|R| Session ID (31) |
+-+-------------------------------------------------------------+
| Data (*) ...
+---------------------------------------------------------------+
| Padding (*) ...
+---------------------------------------------------------------+
図2:WT_DATAGRAMフレームフォーマット
WT_DATAGRAMフレームは以下のフィールドを定義する。
パッド長。Pad Length: オクテット単位のフレームパディングの長さを含む8ビットのフィールドです。このフィールドは条件付きであり(図中の「?
セッションID。このWebトランスポートストリームのストリーム・コネクトストリームを識別する符号なしの31ビット整数。セッションIDは、拡張CONNECTプロトコルでネゴシエートされたオープンストリームでなければならず(MUST)、 :protocolの値は「webtransport」でなければならない。
データ。アプリケーションのデータです。データ量は、存在する他のフィールドの長さを差し引いたフレームペイロードの残りです。
WT_DATAGRAM フレームはフラグを定義していません。
受信者は、指定されたWebTransport Connect Streamが存在しない場合、"webtransport "プロトコルを使用するためにextended CONNECTを介して確立されたストリームではない場合、またはストリームの状態が "closed "または "half-closed (remote) "である場合、WT_STREAM_ERRORタイプのストリームエラーで応答してもよい。
WT_DATAGRAMフレーム内のデータは、フロー制御の対象ではありません。受信者は、バッファするのに十分なスペースがない場合、このデータを破棄してもよい(MAY)。
仲介者はWT_DATAGRAMフレーム内のデータをHTTP/3上のWebTransportなどの別のプロトコルで転送することができます。QUICでは、データグラムフレームは最大でも1つのパケットにしかなりません。そのため、アプリケーションは送信可能なデータグラムの最大サイズを知る必要があります。しかし、データグラムをプロキシする場合、ホップごとのMTUは変動する可能性があります。
5. セッションの終了
HTTP/2 上の WebTransport セッションは、どちらかのエンドポイントが、セッションを開始した CONNECT リクエストに関連するストリームを閉じると終了します。セッションが終了したことを知ると、エンドポイントは新しいデータグラムの送信を停止し、セッションに関連するすべてのストリームをリセットしなければなりません(MUST)。
6. トランスポート・プロパティ
WebTransport フレームワーク [OVERVIEW] では、すべての WebTransport プロトコルで利用可能な共通のプロパティ・セットを超えて、さらなる最適化を可能にする機能の存在をクライアントが判断するために使用できる、オプションのトランスポート・プロパティ・セットを定義しています。以下は、これらのプロパティに対するHttp2Transportのサポートについての詳細です。
ストリームの独立性。
HTTP/2 には本質的に head of line blocking があるため、Http2Transport はストリームの独立性をサポートしません。
部分的な信頼性。
HTTP/2 は失われたデータを再送するため、Http2Transport は部分的な信頼性をサポートしません。つまり、Http2Transportを介して送信されたデータグラムは、アプリケーションの優先順位に関わらず再送されます。しかし、バッファリングできない場合、受信者はデータグラムをドロップすることができます。
プーリングのサポート。
Http2Transportはプーリングをサポートしています。Http2Transportを使用する複数のトランスポートは、同じHTTP/2接続を共有することができるため、輻輳コントローラやその他のトランスポート・コンテキストを共有することができます。
接続のモビリティ。
MPTCP [RFC7540]のようなマルチパスやマイグレーションをサポートするトランスポートプロトコルがHTTP/2やTLSの下で使用されている場合を除き、Http2Transportはコネクションモビリティをサポートしません。このようなサポートがなければ、Http2Transport の接続はネットワークの移行に耐えられません。
7. セキュリティに関する考察
HTTP/2 上の WebTransport は、[OVERVIEW] で WebTransport プロトコルに課されたセキュリティ要件をすべて満たしているため、クライアントが潜在的に信頼されていない場合でも、クライアント-サーバ間の通信に安全なフレームワークを提供します。
HTTP/2 上の WebTransport は、HTTP SETTINGS を用いた明示的なオプトインを必要とします。これにより、HTTP/2 サーバーが明示的にサポートしていることを確認し、潜在的なプロトコルコンフュージョン攻撃を回避します。また、Origin ヘッダーを使用することで、信頼できるオリジンから発信されていないウェブベースのクライアントからのアクセスを拒否する機能をサーバーに提供します。
HTTP/2 を経由する HTTP トラフィックと同様に、WebTransport は 1 つの接続内で異なるオリジンへのトラフィックをプールします。異なるオリジンは異なる信頼ドメインを意味し、実装は各トランスポートを同じ接続上の他のトランスポートに対して潜在的に敵対的なものとして扱う必要があります。すべてのトランスポートが輻輳制御とフロー制御のコンテクストを共有しているので、単一のクライアントが積極的にリソースを使い切ると、他のトランスポートがストールする原因になる。したがって、ユーザーエージェントは、接続内の各トランスポートが制御されたリソースの妥当なシェアを得ることを保証する公平性のスキームを実装すべきである(これは、データの送信と新しいストリームのオープンの両方に適用される)。
8. IANAの考慮事項
8.1. HTTP/2 SETTINGS パラメーター登録
RFC7540]で確立された「HTTP/2 Settings」レジストリに、以下のエントリが追加されます。
SETTINGS_ENABLE_WEBTRANSPORT パラメーターは、指定された HTTP/2 接続が WebTransport 対応であることを示します。
設定名は
有効_ウェブトランスポート
値の説明
0x2b603742
デフォルトです。
0
仕様です。
このドキュメント
8.2. フレームタイプの登録
RFC7540] によって確立された "HTTP/2 Frame Type" レジストリに、以下のエントリが追加されました。
WT_STREAM フレームは、HTTP/2 のクライアントおよびサーバーが開始した一方向および双方向のストリームを WebTransport で使用できるようにします。
コードを
0xTBD
フレームタイプ。
WebTransport_Stream
仕様です。
このドキュメント
WT_DATAGRAM フレームは、HTTP/2 クライアントとサーバーが WebTransport によって使用されるデータグラムを交換することを可能にします。
コードを
0xTBD
フレームタイプ。
WebTransport_Datagram
仕様です。
このドキュメント
8.3. HTTP/2 エラーコードレジストリ
RFC7540] の 11.2 節で制定された "HTTP/2 Error Code" レジストリに、以下のエントリが追加されました。
名前は次のとおりです。
WT_STREAM_ERROR
コード
0xTBD
説明
WT_STREAMフレームの無効な使用
仕様です。
RFCエディターです。この値には、この文書のRFC番号を記入してください。
8.4. 例
HTTP/2 接続における WebTransport Stream のネゴシエーションの例を以下に示します。この例は、[RFC8441]のセクション5.1の例を忠実に踏襲し、この文書で定義されている違いを説明するためのものです。
[[ From Client ]] [[ From Server ]]
SETTINGS
SETTINGS_ENABLE_WEBTRANSPORT = 1
SETTINGS
SETTINGS_ENABLE_WEBTRANSPORT = 1
HEADERS + END_HEADERS
Stream ID = 3
:method = CONNECT
:protocol = webtransport
:scheme = https
:path = /
:authority = server.example.com
origin: server.example.com
HEADERS + END_HEADERS
Stream ID = 3
:status = 200
WT_STREAM
Stream ID = 5
Session ID = 3
DATA
Stream ID = 5
WebTransport Data
DATA + END_STREAM
Stream ID = 5
WebTransport Data
DATA + END_STREAM
Stream ID = 5
WebTransport Data
サーバがWebTransport Streamを開始する例を以下に示します。ここでは、最初のWT_STREAMフレームを送信するエンドポイントが異なるだけです。
[[ From Client ]] [[ From Server ]]
SETTINGS
SETTINGS_ENABLE_WEBTRANSPORT = 1
SETTINGS
SETTINGS_ENABLE_WEBTRANSPORT = 1
HEADERS + END_HEADERS
Stream ID = 3
:method = CONNECT
:protocol = webtransport
:scheme = https
:path = /
:authority = server.example.com
origin: server.example.com
HEADERS + END_HEADERS
Stream ID = 3
:status = 200
WT_STREAM
Stream ID = 2
Session ID = 3
DATA
Stream ID = 2
WebTransport Data
DATA + END_STREAM
Stream ID = 2
WebTransport Data
DATA + END_STREAM
Stream ID = 2
WebTransport Data