WebTransport

W3C 作業草案,

この文書の詳細情報
このバージョン:
https://www.w3.org/TR/2025/WD-webtransport-20251217/
最新公開バージョン:
https://www.w3.org/TR/webtransport/
編集者ドラフト:
https://w3c.github.io/webtransport/
履歴:
https://www.w3.org/standards/history/webtransport/
フィードバック:
public-webtransport@w3.org 件名 “[webtransport] … メッセージのトピック …” (アーカイブ)
GitHub
仕様内でインライン
編集者:
Nidhi Jaju (Google)
Victor Vasiliev (Google)
Jan-Ivar Bruaroey (Mozilla)
以前の編集者:
Bernard Aboba (Microsoft Corporation)
Peter Thatcher (Google)
Robin Raymond (Optical Tone Ltd.)
Yutaka Hirano (Google)

概要

この文書は、ブラウザとサーバー間でデータの送受信を可能にするためのECMAScript APIセットをWebIDLで定義し、[WEB-TRANSPORT-OVERVIEW]を利用します。 この仕様は、IETF WEBTRANSワーキンググループによって策定されているプロトコル仕様と連携して開発されています。

この文書のステータス

このセクションは、公開時点でのこの文書のステータスについて説明します。最新のW3C出版物の一覧やこの技術報告書の最新版は、W3C技術報告書インデックスに掲載されています。

この文書は、WebTransportワーキンググループ によって、勧告トラックを用いて作業草案として公開されました。この文書はW3C勧告になることを目指しています。

この文書へのフィードバックやコメントは歓迎します。イシューを提出 するか、GitHubリポジトリをご利用ください。

作業草案としての公開は、W3Cおよびその会員による支持を意味するものではありません。この文書は草案であり、随時更新、差し替え、または廃止される可能性があります。進行中の作業以外として引用するのは不適切です。

この文書はW3C特許ポリシーの下で活動するグループによって作成されました。 W3Cは、グループの成果物に関して行われた特許開示の公開リストを維持しています。 そのページには特許開示方法の案内も含まれています。 個人が本質的な請求項Essential Claim(s)を含むと考える特許について実際に知っている場合は、W3C特許ポリシー第6節に従って情報を開示する必要があります。

この文書は、2025年8月18日W3Cプロセス文書に従って管理されています。

1. はじめに

このセクションは規範的ではありません。

この仕様は、[WEB-TRANSPORT-OVERVIEW]を使用して、サーバーへのデータ送信およびサーバーからのデータ受信を行います。WebSocketsのように使用できますが、複数ストリーム、単方向ストリーム、順不同配信、信頼性のある転送および信頼性のない転送のサポートがあります。

注: 本仕様で示されているAPIは、IETF WEBTRANS WGで進行中の作業に基づく暫定案です。[WEB-TRANSPORT-HTTP3] および [WEB-TRANSPORT-HTTP2] の仕様は進行中であるため、今後プロトコルやAPIが大きく変更される可能性があります。

2. 適合性

規範的でないと明記されたセクションだけでなく、著者向けガイドライン、図、例、および本仕様書内の注記も全て非規範的です。それ以外は全て規範的です。

「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「NOT RECOMMENDED」「MAY」「OPTIONAL」といったキーワードは、[RFC2119] および [RFC8174] の定義に従い、ここで示されるように全て大文字で現れる場合のみ、同様に解釈されます。

本仕様は、ここに含まれるインターフェースを実装するユーザーエージェント製品単体に適用される適合性基準を定義します。

アルゴリズムや具体的な手順として記述された適合要件は、最終結果が同等である限り、どのような方法で実装してもかまいません。(特に、本仕様で定義されているアルゴリズムは理解しやすいように意図されており、性能面を考慮しているものではありません。)

本仕様で定義されるAPIをECMAScriptを用いて実装する場合、Web IDL仕様 [WEBIDL] で定義されるECMAScriptバインディングと用語に従い、一貫した方法で実装しなければなりません。

3. プロトコルの概念

WebTransportの主要なプロトコル概念は「セッション」と「ストリーム」の2つです。各WebTransportセッションは複数のWebTransportストリームを含むことができます。

これらは、アプリケーションレベルのAPI構造であるプロトコル名と混同しないでください。

3.1. WebTransportセッション

WebTransportセッションは、HTTP/3またはHTTP/2の基盤となるコネクション上のWebTransportのセッションです。 プーリングが有効な場合、1つのコネクション上に複数のWebTransportセッションが存在することがあります。

WebTransportセッションには、[WEB-TRANSPORT-OVERVIEW]で定義された以下の機能があります:

機能 定義
データグラムを送信する [WEB-TRANSPORT-OVERVIEW] セクション4.2
データグラムを受信する [WEB-TRANSPORT-OVERVIEW] セクション4.2
送信単方向ストリームを作成する [WEB-TRANSPORT-OVERVIEW] セクション4.3
双方向ストリームを作成する [WEB-TRANSPORT-OVERVIEW] セクション4.3
受信単方向ストリームを受信する [WEB-TRANSPORT-OVERVIEW] セクション4.3
双方向ストリームを受信する [WEB-TRANSPORT-OVERVIEW] セクション4.3

WebTransportセッション sessionは、排出中となります。これは、CONNECTストリームがサーバーによって正常に閉じるよう要求された場合であり、詳細は [WEB-TRANSPORT-OVERVIEW] セクション4.1で説明されています。

終了するには、WebTransportセッション sessionに任意の整数 codeと任意のバイト列 reasonを指定し、[WEB-TRANSPORT-OVERVIEW] セクション4.1に従ってください。

WebTransportセッション sessionは、任意の整数 codeバイト列 reasonとともに、CONNECTストリームがサーバーによって閉じられたときに 終了済みとなります。詳細は [WEB-TRANSPORT-OVERVIEW] セクション4.1で説明されています。

3.2. WebTransportストリーム

WebTransportストリームは、WebTransportセッション上の信頼性のある順序どおりのバイトストリームの概念であり、[WEB-TRANSPORT-OVERVIEW] セクション4.3で説明されています。

WebTransportストリームは、受信単方向送信単方向または双方向のいずれかです。

WebTransportストリームには以下の機能があります:

機能 定義 受信単方向 送信単方向 双方向
バイト送信(FIN付きの場合あり) [WEB-TRANSPORT-OVERVIEW] セクション4.3 いいえ はい はい
バイト受信(FIN付きの場合あり) [WEB-TRANSPORT-OVERVIEW] セクション4.3 はい いいえ はい
受信の中止WebTransportストリームで) [WEB-TRANSPORT-OVERVIEW] セクション4.3 はい いいえ はい
送信の中止WebTransportストリームで) [WEB-TRANSPORT-OVERVIEW] セクション4.3 いいえ はい はい

WebTransportストリームには以下のシグナルがあります:

イベント 定義 受信単方向 送信単方向 双方向
受信中止 [WEB-TRANSPORT-OVERVIEW] セクション4.3 いいえ はい はい
送信中止 [WEB-TRANSPORT-OVERVIEW] セクション4.3 はい いいえ はい
フロー制御 [WEB-TRANSPORT-OVERVIEW] セクション4.3 いいえ はい はい

4. WebTransportDatagramsWritable インターフェース

WebTransportDatagramsWritableは、WritableStream であり、 データグラムの送信のための送信ストリーミング機能を提供します。

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportDatagramsWritable : WritableStream {
  attribute WebTransportSendGroup? sendGroup;
  attribute long long sendOrder;
};

4.1. 内部スロット

WebTransportDatagramsWritable オブジェクトは以下の内部スロットを持ちます。

内部スロット 説明 (非規範的)
[[OutgoingDatagramsQueue]] 送信用データグラム、タイムスタンプ、およびデータグラムが送信または破棄されたときに解決される Promise のタプルのキュー。
[[Transport]] この WebTransport が所有する WebTransportDatagramsWritable
[[SendGroup]] オプションの WebTransportSendGroup、 または null。
[[SendOrder]] オプションの送信順序番号。デフォルトは 0。
WebTransportDatagramsWritableWebTransport transportsendGroupsendOrder を与えて生成するには、以下の手順を行う。
  1. stream を、以下を持つ 新しい WebTransportDatagramsWritable とする:

    [[OutgoingDatagramsQueue]]

    空のキュー

    [[Transport]]

    transport

    [[SendGroup]]

    sendGroup

    [[SendOrder]]

    sendOrder

  2. writeDatagramsAlgorithm を、writeDatagramstransportstream で実行するアクションとする。

  3. セットアップ streamwriteAlgorithmwriteDatagramsAlgorithm に設定する。

  4. stream を返す。

4.2. 属性

sendGroup, WebTransportSendGroup, null可能

ゲッター手順:

  1. this[[SendGroup]] を返す。

セッター手順(valueを与える):

  1. valueがnullでなく、かつ value.[[Transport]]this.[[Transport]] でない場合、InvalidStateErrorをスローする。

  2. this.[[SendGroup]]valueに設定する。

sendOrder, long long

ゲッター手順:

  1. this[[SendOrder]] を返す。

セッター手順(valueを与える):

  1. this.[[SendOrder]]valueに設定する。

4.3. 手順

writeDatagrams アルゴリズムはtransportおよびwritableをパラメータ、dataを入力とし、次の手順で定義されます:

  1. timestampを現在を表すタイムスタンプとする。

  2. dataBufferSource オブジェクトでなければ、TypeErrorでrejectされたpromiseを返す。

  3. datagramstransport.[[Datagrams]]とする。

  4. datagrams.[[OutgoingMaxDatagramSize]]dataの[[ByteLength]]より小さい場合、undefinedでresolveされたpromiseを返す。

  5. promiseを新しいpromiseとする。

  6. bytesdataが表すバイトのコピーとする。

  7. chunkbytestimestamppromiseのタプルとする。

  8. writable.[[OutgoingDatagramsQueue]]chunkをエンキューする。

  9. writable.[[OutgoingDatagramsQueue]] の長さが datagrams.[[OutgoingDatagramsHighWaterMark]] 未満なら、promiseをundefinedで解決する

  10. promiseを返す。

注: 関連するWritableStream は、そのストリームでwriteDatagramsによって返されたpromiseが全て解決されたときのみwriteDatagramsを呼び出します。したがって、タイムスタンプと有効期限は、ウェブ開発者が WritableStreamDefaultWriter.ready に注意を払う場合のみ適切に動作します。

sendDatagrams するには、WebTransport オブジェクトtransportWebTransportDatagramsWritable オブジェクトwritableで、ネットワークタスクをキューし transportで以下のステップを実行します:

  1. queuewritable.[[OutgoingDatagramsQueue]] のコピーとする。

    注: 上記のコピーおよびネットワークタスクのキューは最適化できます。

  2. maxSizetransport.[[Datagrams]].[[OutgoingMaxDatagramSize]] とする。

  3. durationtransport.[[Datagrams]].[[OutgoingDatagramsExpirationDuration]] とする。

  4. durationがnullなら、duration実装定義値に設定する。

  5. 次のステップを並行して実行:

    1. queueが空でない間:

      1. bytestimestamppromisequeueの先頭要素から取得する。

      2. timestampからdurationミリ秒以上経過している場合:

        1. queueの先頭要素を削除する。

        2. ネットワークタスクをキューしtransportpromiseをundefinedで解決する。

      3. それ以外の場合、このループを終了する。

    2. transport.[[State]]"connected"でなければ、何もせず終了する。

    3. queueが空でない間:

      1. bytestimestamppromisequeueの先頭要素から取得する。

      2. bytesの長さがmaxSize以下の場合:

        1. bytesを即座にネットワークに送信できない場合、このループを終了する。

        2. データグラムの送信transport.[[Session]]bytesで行う。

      3. queueの先頭要素を削除する。

      4. ネットワークタスクをキューし transportpromiseをundefinedで解決する。

ユーザーエージェントは、WebTransport オブジェクトのうち [[State]]"connecting"または"connected"のものについて、関連するWebTransportDatagramsWritable オブジェクトの部分集合(送信順ルールにより決定)に対してsendDatagramsを実行しなければならず、アルゴリズムが進捗できる場合は合理的な範囲ですぐに実行するべきです。

送信順ルールは、送信は一般に、このトランスポート上で以前にキューされたストリームやデータグラムの送信、および今後キューされるストリームやデータグラムの送信とインターリーブされてもよいですが、送信は、同じ [[SendGroup]] かつより高い [[SendOrder]] を持つストリームやデータグラム(エラー状態でもフロー制御でブロックされているものでもない)が全て送信されるまで、優先的に待機しなければなりません。

注: トランスポートの[[State]]"connecting"の間、データグラムの書き込みは許可されます。 データグラムは[[OutgoingDatagramsQueue]] に格納され、"connected"状態の時と同様に破棄される可能性があります。トランスポートの[[State]]"connected"になると、キューされたデータグラムの送信が開始されます。

5. WebTransportDatagramDuplexStream インターフェース

WebTransportDatagramDuplexStreamは、汎用的なデュプレックスストリームです。

[Exposed=(Window,Worker), SecureContext]
interface WebTransportDatagramDuplexStream {
  WebTransportDatagramsWritable createWritable(
      optional WebTransportSendOptions options = {});
  readonly attribute ReadableStream readable;

  readonly attribute unsigned long maxDatagramSize;
  attribute unrestricted double? incomingMaxAge;
  attribute unrestricted double? outgoingMaxAge;
  attribute unrestricted double incomingHighWaterMark;
  attribute unrestricted double outgoingHighWaterMark;
};

5.1. 内部スロット

WebTransportDatagramDuplexStream オブジェクトは以下の内部スロットを持ちます。

内部スロット 説明 (非規範的)
[[Transport]] このWebTransport が所有するWebTransportDatagramDuplexStream
[[Readable]] 受信データグラム用の ReadableStream
[[ReadableType]] 受信データグラムで使用される ReadableStreamType
[[Writables]] 順序付き集合WebTransportDatagramsWritable ストリーム、 初期状態は空。
[[IncomingDatagramsQueue]] 受信データグラムとタイムスタンプのペアのキュー。
[[IncomingDatagramsPullPromise]] pullDatagramsによって設定される、受信データグラムを待つためのpromise。
[[IncomingDatagramsHighWaterMark]] unrestricted double で表される受信データグラムの high water mark
[[IncomingDatagramsExpirationDuration]] unrestricted double で表される受信データグラムの有効期限(ミリ秒単位)、または null。
[[OutgoingDatagramsHighWaterMark]] unrestricted double で表される送信データグラムの high water mark
[[OutgoingDatagramsExpirationDuration]] unrestricted double 値で表される送信データグラムの有効期限(ミリ秒単位)、または null。
[[OutgoingMaxDatagramSize]] 送信データグラムの最大サイズを表す整数。
最大データグラムサイズは使用中のプロトコルによって異なります。 HTTP/3 [WEB-TRANSPORT-HTTP3] では、この値はパスの MTU の見積りに関係し、 実装依存の量だけ減少してオーバーヘッドを考慮します。 HTTP/2 [WEB-TRANSPORT-HTTP2] では、同様の制限はありません。

データグラムの処理は通常、全体をメモリに保持するため、 実装ではサイズ制限があります。 将来のプロトコル拡張により、すべてのプロトコルバリエーションで これらのサイズ制限の通知を可能にできます。

ユーザーエージェントは、[[OutgoingMaxDatagramSize]]WebTransport オブジェクトの [[State]]"connecting" または "connected" である場合に更新してもよい。

WebTransportDatagramDuplexStreamWebTransport transportreadablereadableType を与えて生成するには、以下の手順を行う。
  1. stream を、以下を持つ 新しい WebTransportDatagramDuplexStream とする:

    [[Transport]]

    transport

    [[Readable]]

    readable

    [[ReadableType]]

    readableType

    [[Writables]]

    空の順序付き集合

    [[IncomingDatagramsQueue]]

    空のキュー

    [[IncomingDatagramsPullPromise]]

    null

    [[IncomingDatagramsHighWaterMark]]

    実装依存の値

    [[IncomingDatagramsExpirationDuration]]

    null

    [[OutgoingDatagramsHighWaterMark]]

    実装依存の値

    この実装依存の値は、十分なスループットを確保しつつ、送信データの即時性を損ねないよう調整されるべきです。

    [[OutgoingDatagramsExpirationDuration]]

    null

    [[OutgoingMaxDatagramSize]]

    実装依存の整数。

  2. stream を返す。

5.2. メソッド

createWritable()

WebTransportDatagramsWritableを作成する。

createWritable() メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:
  1. transportthis に関連付けられている WebTransport オブジェクトとする。

  2. もし transport.[[State]]"closed" または "failed" であれば、 throw を行い、InvalidStateErrorとする。

  3. sendGroupoptionssendGroup とする。

  4. もし sendGroup が null でなく、かつ sendGroup.[[Transport]]this.[[Transport]] でない場合、 throw を行い、InvalidStateErrorとする。

  5. sendOrderoptionssendOrder とする。

  6. transportsendGroupsendOrder を用いて 作成される WebTransportDatagramsWritable の結果を返す。

5.3. 属性

readable, of type ReadableStream, readonly

ゲッター手順は以下の通り:

  1. this.[[Readable]] を返す。

incomingMaxAge, of type unrestricted double, nullable

ゲッター手順は以下の通り:

  1. this.[[IncomingDatagramsExpirationDuration]] を返す。

セッター手順(value が与えられた場合):

  1. もし value が負または NaN なら、throw し、 RangeError とする。

  2. もし value0 なら、value を null に設定する。

  3. this.[[IncomingDatagramsExpirationDuration]]value を設定する。

maxDatagramSize, of type unsigned long, readonly

WebTransportDatagramsWritable に渡せる最大データサイズ。 ゲッター手順は、this.[[OutgoingMaxDatagramSize]] を返す。

outgoingMaxAge, of type unrestricted double, nullable

ゲッター手順は以下の通り:

  1. this[[OutgoingDatagramsExpirationDuration]] を返す。

セッター手順(value が与えられた場合):

  1. もし value が負または NaN なら、throw し、 RangeError とする。

  2. もし value0 なら、value を null に設定する。

  3. this.[[OutgoingDatagramsExpirationDuration]]value を設定する。

incomingHighWaterMark, of type unrestricted double

ゲッター手順は以下の通り:

  1. this.[[IncomingDatagramsHighWaterMark]] を返す。

セッター手順(value が与えられた場合):

  1. もし value が負または NaN なら、throw し、 RangeError とする。

  2. もし value1 未満なら、value1 に設定する。

  3. this.[[IncomingDatagramsHighWaterMark]]value を設定する。

outgoingHighWaterMark, of type unrestricted double

ゲッター手順は以下の通り:

  1. this.[[OutgoingDatagramsHighWaterMark]] を返す。

セッター手順(value が与えられた場合):

  1. もし value が負または NaN なら、throw し、 RangeError とする。

  2. もし value1 未満なら、value1 に設定する。

  3. this.[[OutgoingDatagramsHighWaterMark]]value を設定する。

5.4. 手順

pullDatagrams するには、 WebTransport オブジェクト transport を与えて次の手順を実行する:

  1. datagramstransport.[[Datagrams]]とする。

  2. アサート:datagrams.[[IncomingDatagramsPullPromise]] はnull。

  3. queuedatagrams.[[IncomingDatagramsQueue]]とする。

  4. もしqueueが空なら、

    1. datagrams.[[IncomingDatagramsPullPromise]] に新しいpromiseを設定する。

    2. datagrams.[[IncomingDatagramsPullPromise]]を返す。

  5. datagramtimestampqueueからデキュー queueした結果とする。

  6. もしdatagrams.[[ReadableType]]"bytes"なら:

    1. もしdatagrams.[[Readable]]current BYOB request viewが nullでなければ:

      1. viewdatagrams.[[Readable]]current BYOB request viewとする。

      2. もしviewbyte lengthdatagramのサイズより小さいなら、 promise rejected(失敗promise)RangeErrorで返す。

      3. typed array constructors tableview.[[TypedArrayName]]で指定されたelement sizeをelementSizeとする。viewが [[TypedArrayName]]の内部スロットを持たない場合(DataViewの場合)、elementSizeは0とする。

      4. もしelementSizeが1でなければ promise rejected(失敗promise)TypeErrorで返す。

    2. Pull from bytesdatagramdatagrams.[[Readable]]にpullする。

  7. それ以外:

    1. chunkUint8Arraydatagramを表現した新規オブジェクトとする。

    2. Enqueuechunktransport.[[Datagrams]].[[Readable]]にenqueueする。

  8. promise resolved(成功promise)でundefinedを返す。

receiveDatagrams するには、 WebTransport オブジェクト transport を与えて次の手順を実行する:

  1. timestampを現在時刻とする。

  2. queuedatagrams.[[IncomingDatagramsQueue]]とする。

  3. durationdatagrams.[[IncomingDatagramsExpirationDuration]]とする。

  4. もしdurationがnullなら、duration実装依存の値を設定する。

  5. sessiontransport.[[Session]]とする。

  6. session利用可能な受信データグラムがある間:

    1. datagramdatagram受信の結果とする。

    2. timestampを現在時刻とする。

    3. chunkdatagramtimestampのペアとする。

    4. Enqueuechunkqueueにenqueueする。

  7. toBeRemovedqueueの長さからdatagrams.[[IncomingDatagramsHighWaterMark]]を引いた値とする。

  8. もしtoBeRemovedが正なら、queueからデキューするqueuetoBeRemoved 回(切り捨て)繰り返す。

  9. queueが空でない間:

    1. bytestimestampqueueの先頭要素とする。

    2. もしtimestampからdurationミリ秒より長く経過していたら、queueからデキューする。

    3. それ以外は、このループをbreakする。

  10. もしqueueが空でなく、かつdatagrams.[[IncomingDatagramsPullPromise]] が非nullなら:

    1. bytestimestampqueueからデキューした結果とする。

    2. promisedatagrams.[[IncomingDatagramsPullPromise]]とする。

    3. datagrams.[[IncomingDatagramsPullPromise]] をnullに設定する。

    4. Queue a network tasktransportで次の手順を実行:

      1. chunkUint8Arraybytesを表現した新規オブジェクトとする。

      2. Enqueuechunkdatagrams.[[Readable]]にenqueueする。

      3. promise resolvepromiseをundefinedで解決する。

receiveDatagramsは、 WebTransport オブジェクトの [[State]]"connected" の場合、アルゴリズムが進行可能になり次第、速やかに呼び出すべきである。

6. WebTransport インターフェース

WebTransportは、[WEB-TRANSPORT-OVERVIEW]で定義された基盤となるトランスポート機能へのAPIを提供します。

[Exposed=(Window,Worker), SecureContext]
interface WebTransport {
  constructor(USVString url, optional WebTransportOptions options = {});

  Promise<WebTransportConnectionStats> getStats();
  [NewObject] Promise<ArrayBuffer> exportKeyingMaterial(BufferSource label, optional BufferSource context);
  readonly attribute Promise<undefined> ready;
  readonly attribute WebTransportReliabilityMode reliability;
  readonly attribute WebTransportCongestionControl congestionControl;
  [EnforceRange] attribute unsigned short? anticipatedConcurrentIncomingUnidirectionalStreams;
  [EnforceRange] attribute unsigned short? anticipatedConcurrentIncomingBidirectionalStreams;
  readonly attribute DOMString protocol;

  readonly attribute Promise<WebTransportCloseInfo> closed;
  readonly attribute Promise<undefined> draining;
  undefined close(optional WebTransportCloseInfo closeInfo = {});

  readonly attribute WebTransportDatagramDuplexStream datagrams;

  Promise<WebTransportBidirectionalStream> createBidirectionalStream(
      optional WebTransportSendStreamOptions options = {});
  /* a ReadableStream of WebTransportBidirectionalStream objects */
  readonly attribute ReadableStream incomingBidirectionalStreams;

  Promise<WebTransportSendStream> createUnidirectionalStream(
      optional WebTransportSendStreamOptions options = {});
  /* a ReadableStream of WebTransportReceiveStream objects */
  readonly attribute ReadableStream incomingUnidirectionalStreams;
  WebTransportSendGroup createSendGroup();

  static readonly attribute boolean supportsReliableOnly;
};

enum WebTransportReliabilityMode {
  "pending",
  "reliable-only",
  "supports-unreliable",
};

6.1. 内部スロット

A WebTransport オブジェクトは以下の内部スロットを持つ。

内部スロット 説明 (非規範的)
[[SendStreams]] このWebTransportが所有する WebTransportSendStream順序付き集合
[[ReceiveStreams]] この WebTransportが所有する WebTransportReceiveStream順序付き集合
[[IncomingBidirectionalStreams]] ReadableStream で、WebTransportBidirectionalStream オブジェクトで構成される。
[[IncomingUnidirectionalStreams]] ReadableStream で、WebTransportReceiveStreamで構成される。
[[State]] トランスポートの状態を示すenum。 "connecting", "connected", "draining", "closed", "failed"のいずれか。
[[Ready]] 関連するWebTransportセッション確立された際に fulfillされるpromise。確立処理が失敗した場合は rejectする。
[[Reliability]] WebTransportReliabilityMode で、最初のホップが信頼性なし(UDP)か、信頼性あり(TCPフォールバック)のどちらかを示す。 接続確立までは"pending"を返す。
[[CongestionControl]] WebTransportCongestionControl で、アプリによるスループット最適/低遅延最適の輻輳制御アルゴリズム要求がユーザーエージェントに満たされたか、"default"かを示す。
[[AnticipatedConcurrentIncomingUnidirectionalStreams]] アプリがサーバーによって生成されると予測する同時オープン 着信単方向ストリーム数、またはnull。
[[AnticipatedConcurrentIncomingBidirectionalStreams]] アプリがサーバーによって生成されると予測する同時オープン 双方向ストリーム数、またはnull。
[[Protocol]] サーバーによって選択されたアプリケーションレベルプロトコルを示す文字列。初期値は空文字列。
[[Closed]] 関連するWebTransport オブジェクトが正常にクローズされた場合にfulfill、異常終了/初期化失敗時にrejectされるpromise。
[[Draining]] 関連するWebTransportセッションdrainedのときにfulfillされるpromise。
[[Datagrams]] WebTransportDatagramDuplexStream
[[Session]] このWebTransportオブジェクトのWebTransportセッション、またはnull。
[[NewConnection]] "no"または"yes-and-dedicated"のいずれか。
[[RequireUnreliable]] UDPが必須かどうかを示すboolean。
[[ServerCertificateHashes]] リストで、0個以上の WebTransportHashオブジェクトを格納する。

6.2. コンストラクター

WebTransport() コンストラクターが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:
  1. baseURLthis関連設定オブジェクトAPI base URL を取得する。

  2. urlURLレコードパースした結果として、urlbaseURL を用いる。

  3. もし url が failure の場合、throwSyntaxError 例外。

  4. もし urlschemehttps でない場合、throwSyntaxError 例外。

  5. もし urlfragment が null でない場合、throwSyntaxError 例外。

  6. allowPoolingoptionsallowPooling を取得する。

  7. dedicatedallowPooling の否定値を設定する。

  8. serverCertificateHashesoptionsserverCertificateHashes とする。

  9. もし dedicated が false で serverCertificateHashes空でないなら、throwNotSupportedError 例外。

  10. newConnectiondedicated が false なら "no"、そうでなければ "yes-and-dedicated" を設定。

  11. requireUnreliableoptionsrequireUnreliable とする。

  12. congestionControloptionscongestionControl に設定。

  13. もし congestionControl"default" でなく、ユーザーエージェントが congestionControl に最適化した輻輳制御アルゴリズムをサポートしない場合([RFC9002] Section 7参照)、 congestionControl"default" に設定する。

  14. protocolsoptionsprotocols とする。

  15. もし protocols 内に同じ値が複数ある、要素がWebTransportプロトコルで規定された交渉アプリケーションプロトコル値の要件を満たさない、 isomorphic encode 長が0または512を超えるものがあれば、throwSyntaxError 例外。 [WEB-TRANSPORT-OVERVIEW] Section 3.1.

  16. anticipatedConcurrentIncomingUnidirectionalStreamsoptionsanticipatedConcurrentIncomingUnidirectionalStreams を設定。

  17. anticipatedConcurrentIncomingBidirectionalStreamsoptionsanticipatedConcurrentIncomingBidirectionalStreams を設定。

  18. datagramsReadableTypeoptionsdatagramsReadableType とする。

  19. incomingDatagrams新しい ReadableStreamとする。

  20. transport を新しく構築された WebTransport オブジェクトとし、以下の値を持つ:

    [[SendStreams]]

    空の 順序付き集合

    [[ReceiveStreams]]

    空の 順序付き集合

    [[IncomingBidirectionalStreams]]

    新しい ReadableStream

    [[IncomingUnidirectionalStreams]]

    新しい ReadableStream

    [[State]]

    "connecting"

    [[Ready]]

    新しい promise

    [[Reliability]]

    "pending"

    [[CongestionControl]]

    congestionControl

    [[AnticipatedConcurrentIncomingUnidirectionalStreams]]

    anticipatedConcurrentIncomingUnidirectionalStreams

    [[AnticipatedConcurrentIncomingBidirectionalStreams]]

    anticipatedConcurrentIncomingBidirectionalStreams

    [[Protocol]]

    空文字列

    [[Closed]]

    新しい promise

    [[Draining]]

    新しい promise

    [[Datagrams]]

    undefined

    [[Session]]

    null

    [[NewConnection]]

    newConnection

    [[RequireUnreliable]]

    requireUnreliable

    [[ServerCertificateHashes]]

    serverCertificateHashes

  21. transport.[[Datagrams]]WebTransportDatagramDuplexStream を生成した結果を設定し、 引数は transportincomingDatagramsdatagramsReadableType を用いる。

  22. pullDatagramsAlgorithmpullDatagramstransport で実行するアクションとする。

    Note: データグラムには 64 KiB バッファ利用が推奨される。なぜなら有効な最大WebTransportデータグラムフレームサイズはQUIC最大データグラムフレームサイズ(推奨64 KiB)が上限となるため。 [QUIC-DATAGRAM] Section 3 参照。 この値がバッファより大きいデータグラムでエラーが発生しないことを担保するため。

  23. もし datagramsReadableType"bytes" なら、バイト読み出しサポート付きセットアップincomingDatagramspullAlgorithmpullDatagramsAlgorithm、および highWaterMark を 0 でセットアップ。 それ以外の場合は セットアップpullAlgorithmpullDatagramsAlgorithmhighWaterMark に 0 を指定する。

  24. pullBidirectionalStreamAlgorithmpullBidirectionalStreamtransport で実行するアクションとする。

  25. セットアップtransport.[[IncomingBidirectionalStreams]]pullAlgorithmpullBidirectionalStreamAlgorithmhighWaterMark を 0 に設定して行う。

  26. pullUnidirectionalStreamAlgorithmpullUnidirectionalStreamtransport で実行するアクションとする。

  27. セットアップtransport.[[IncomingUnidirectionalStreams]]pullAlgorithmpullUnidirectionalStreamAlgorithmhighWaterMark を 0 に設定して行う。

  28. clienttransport関連設定オブジェクト を設定。

  29. originclientorigin を設定。

  30. request に新しい request を用意し、 URLurlclientclientservice-workers mode を "none"、 referrer を "no-referrer"、 mode を "webtransport"、 credentials mode を "omit"、 cache mode を "no-store"、 policy containerclientpolicy containerdestination を ""、 originoriginredirect mode を "error" に設定する。

    Note: リダイレクトはフォローされない。リダイレクトに起因するネットワークエラーは他のネットワークエラーと区別不能であることが意図的。 クロスオリジン環境では、これは通常CORSでブロックされる情報を漏らさないようにするため。同一オリジン環境では、ハンドシェイク悪用による情報漏洩を防ぐため。

  31. requestmethod を "CONNECT" に設定し、 method に紐付けた :protocol 疑似ヘッダー"webtransport" を設定する。

  32. protocols が空でない場合、(WT-Available-Protocols, structured header list のメンバーが protocols 内順番通りの structured header stringアイテムでできたもの)として 構造化フィールド値requestheader listに設定する。

  33. Fetchrequest を送信し、 useParallelQueue を true に、 processResponseresponse で次の手順とする:

    1. WebTransport fetch response を処理で、 引数は responseoriginprotocolscongestionControl

  34. transport を返す。

WebTransport connectionを取得するには、 ネットワークパーティションキー networkPartitionKey、およびrequest request が与えられた場合:
  1. transportWebTransport オブジェクトで request に関連付けられているものとする。

  2. urlrequestcurrent URL とする。

  3. newConnectiontransport.[[NewConnection]] とする。

  4. requireUnreliabletransport.[[RequireUnreliable]] とする。

  5. serverCertificateHashestransport.[[ServerCertificateHashes]] 内の値とする。

  6. connectionconnection を取得networkPartitionKeyurl、false、newConnectionrequireUnreliable を渡して得られた結果とする。 ただし serverCertificateHashes空でない場合、デフォルトの証明書検証アルゴリズムの代わりに カスタム証明書要件を満たし、 証明書ハッシュの検証serverCertificateHashesと一致する場合のみ証明書が有効と見なす。それ以外は failure とする。

  7. もし connection が failure なら failure を返す。

  8. connection が最初のSETTINGSフレームを受信するまで待機し、settings をその内容を表すディクショナリとする。

  9. もし settingsSETTINGS_ENABLE_CONNECT_PROTOCOL (0x08, Section 3 of [RFC8441] HTTP/2; 0x08, Section 3 of [RFC9220])が1で含まれないなら failure を返す。

  10. もし settings がWebTransportサポートを示さない場合、failure を返す。 [WEB-TRANSPORT-OVERVIEW] Section 4.1.

    Note: SETTINGS_WT_MAX_SESSIONSはIETFで仕様が流動的で、 SETTINGS_ENABLE_WEBTRANSPORTへ戻る可能性あり。

  11. connection を返す。

WebTransport fetch responseを処理する には、responsecongestionControl が与えられた場合、次の手順を実行:
  1. もし responsenetwork error なら、残りの手順を中止し、ネットワークタスクをキューして transport で以下を行う:

    1. もし transport.[[State]]"closed" または "failed" なら、この手順を中止する。

    2. error新規作成した WebTransportErrorsource"session"

    3. クリーンアップtransporterror を渡す。

  2. connectionresponse に紐付く接続とする。

  3. [WEB-TRANSPORT-OVERVIEW] Section 4.1 に従って WebTransport セッションの確立connection と サーバーの response で行う。

  4. session を直近で 確立された WebTransportセッションとする。 結果として得られる基盤トランスポートストリームをセッションの CONNECT stream と呼ぶ。

    Note: このステップで、[QUIC-DATAGRAM]で規定された トランスポートパラメータ交換も完了する。

  5. もし前ステップが失敗した場合、残りを中止し、ネットワークタスクをキューして transport で以下を実行:

    1. もし transport.[[State]]"closed" または "failed" なら中止。

    2. error新規作成した WebTransportErrorsource"session"

    3. クリーンアップtransporterror を渡す。

  6. もし複数の輻輳制御アルゴリズムをサポートしているなら、その congestionControl に相応しいものをこの connection のデータ送信に用いる。

  7. ネットワークタスクをキューして transport で以下を行う:

    1. アサート:this[[Datagrams]][[OutgoingMaxDatagramSize]] は整数である。

    2. もし transport.[[State]]"connecting" でなければ:

      1. 並列でsession終了session に対して実行する。

      2. この手順を中止する。

    3. transport.[[State]]"connected" に設定。

    4. transport.[[Session]]session を設定。

    5. transport.[[Protocol]] に、存在する場合は交渉済みアプリケーションプロトコルの文字列値を、なければ "" を設定 ([WEB-TRANSPORT-OVERVIEW] Section 3.1 参照)。

    6. もし接続が HTTP/3 なら、transport.[[Reliability]]"supports-unreliable"とする。

    7. もし接続が HTTP/2 ([WEB-TRANSPORT-HTTP2]) の場合は、 transport[[Reliability]]"reliable-only"とする。

    8. resolve transport.[[Ready]] を undefined で解決する。

pullBidirectionalStream は、WebTransport オブジェクト transport が与えられたとき、次の手順を実行する。
  1. もし transport.[[State]]"connecting" なら、次の手順を fulfillment後transport.[[Ready]] で実施する結果を返す:

    1. pullBidirectionalStreamtransport に実行した結果を返す。

  2. もし transport.[[State]]"connected" 以外なら、新しい rejected promise を InvalidStateError で返す。

  3. sessiontransport.[[Session]] とする。

  4. p を新しいpromiseとする。

  5. 次の手順を 並列 で実行:

    1. session利用可能な着信双方向ストリーム が現れるまで待つ。

    2. internalStreambidirectional stream の受信session で実行した結果とする。

    3. ネットワークタスクをキューして、 transport で次を実施:

      1. streamWebTransportBidirectionalStream の作成で、 引数は internalStream, transport

      2. Enqueuestreamtransport.[[IncomingBidirectionalStreams]] にenqueueする。

      3. resolvep を undefined で解決する。

  6. p を返す。

pullUnidirectionalStreamWebTransport オブジェクト transport が与えられたとき、次の手順を実行する:
  1. もし transport.[[State]]"connecting" なら、次の手順を fulfillment後transport.[[Ready]] で実施する結果を返す:

    1. pullUnidirectionalStreamtransport に実行した結果を返す。

  2. もし transport.[[State]]"connected" 以外なら、新しい rejected promise を InvalidStateError で返す。

  3. sessiontransport.[[Session]] とする。

  4. p を新しいpromiseとする。

  5. 次の手順を 並列 で実行:

    1. session利用可能な着信単方向ストリーム が現れるまで待つ。

    2. internalStreamincoming unidirectional stream の受信session で実行した結果とする。

    3. ネットワークタスクをキューして transport で次を実施:

      1. streamWebTransportReceiveStream の作成で、 引数は internalStream, transport

      2. Enqueuestreamtransport.[[IncomingUnidirectionalStreams]] にenqueueする。

      3. resolvep を undefined で解決する。

  6. p を返す。

6.3. 属性

ready, of type Promise<undefined>, readonly

取得時、this[[Ready]] を返す必要がある。

closed, of type Promise<WebTransportCloseInfo>, readonly

取得時、this[[Closed]] を返す必要がある。

draining, of type Promise<undefined>, readonly

取得時、this[[Draining]] を返す必要がある。

datagrams, of type WebTransportDatagramDuplexStream, readonly

このセッションでデータグラムの送受信を行うための単一のデュプレックスストリーム。 datagrams 属性のゲッター手順は次の通りとする:

  1. this[[Datagrams]] を返す。

incomingBidirectionalStreams, of type ReadableStream, readonly

ReadableStream で、サーバから受信したWebTransportBidirectionalStreamのストリームを返す。

Note: 着信ストリームに既にデータがあるかどうかはサーバの動作による。

incomingBidirectionalStreams 属性のゲッター手順は:

  1. this[[IncomingBidirectionalStreams]] を返す。

incomingUnidirectionalStreams, of type ReadableStream, readonly

サーバから受信した各WebTransportReceiveStream で表される単方向ストリームのReadableStream

Note: 着信ストリームに既にデータがあるかどうかはサーバの動作による。

incomingUnidirectionalStreamsのゲッター手順:

  1. this.[[IncomingUnidirectionalStreams]] を返す。

reliability, of type WebTransportReliabilityMode, readonly

このコネクションが信頼性なし(UDP経由)転送をサポートするか、信頼性あり(TCPフォールバック)転送のみサポートするか。 接続確立までは"pending"を返す。 ゲッター手順は this[[Reliability]]を返す。

congestionControl, of type WebTransportCongestionControl, readonly

アプリケーションがコンストラクタで指定し、ユーザーエージェントに満たされた場合はスループット最適化または低遅延最適化の輻輳制御アルゴリズムを示す。満たされない場合は値は"default"となる。 ゲッター手順は this[[CongestionControl]] を返す。

supportsReliableOnly, of type boolean, readonly

ユーザーエージェントがWebTransportセッション を信頼性のみのコネクション上でサポートする場合はtrue、そうでなければfalseを返す。

anticipatedConcurrentIncomingUnidirectionalStreams, of type unsigned short, nullable

アプリがサーバで同時オープンされると予測する 着信単方向ストリーム数を指定できる。 nullでなければ、ユーザーエージェントは [[AnticipatedConcurrentIncomingUnidirectionalStreams]] をサーバとのネゴシエーションで考慮しラウンドトリップ削減を試みるべきである。

ゲッター手順は this[[AnticipatedConcurrentIncomingUnidirectionalStreams]] を返す。

セッター手順(value 時)は this[[AnticipatedConcurrentIncomingUnidirectionalStreams]]value を設定する。

anticipatedConcurrentIncomingBidirectionalStreams, of type unsigned short, nullable

アプリがサーバで同時オープンされると予測する 双方向ストリーム数を指定できる。 nullでなければ、ユーザーエージェントは [[AnticipatedConcurrentIncomingBidirectionalStreams]] をサーバとのネゴシエーションで考慮しラウンドトリップ削減を試みるべきである。

ゲッター手順は this[[AnticipatedConcurrentIncomingBidirectionalStreams]] を返す。

セッター手順(value 時)は this[[AnticipatedConcurrentIncomingBidirectionalStreams]]value を設定する。

Note: anticipatedConcurrentIncomingUnidirectionalStreams または anticipatedConcurrentIncomingBidirectionalStreams を設定しても、アプリが予測する本数のストリームを必ず受信できる保証はない。

protocol, of type DOMString, readonly

WebTransportセッションが確立され、 protocols コンストラクタオプションが非空配列で指定された場合はサーバが選択したアプリケーションレベルプロトコル(存在する場合)を返す。そうでなければ空文字列を返す。 ゲッター手順は this[[Protocol]] を返す。

6.4. メソッド

close(closeInfo)

WebTransport オブジェクトに関連付けられたWebTransport セッションを終了する。

close が呼ばれたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. transportthis とする。

  2. もし transport.[[State]]"closed" または "failed" であれば、この手順を中止する。

  3. もし transport.[[State]]"connecting" であれば:

    1. error を新たに作成した WebTransportErrorsource"session" とする。

    2. Cleanuptransporterror を渡す。

    3. この手順を中止する。

  4. sessiontransport.[[Session]] とする。

  5. codecloseInfo.closeCode とする。

  6. reasonString を、コードユニット接頭辞のうち、 closeInfo.reason長さUTF-8 エンコードで 1024 を超えない最大の prefix とする。

  7. reasonreasonStringUTF-8 エンコードで取得する。

  8. 並列で、terminate sessioncode および reason を指定して実行する。

    Note: これにより 送信中止受信中止が、 transport.[[SendStreams]] および [[ReceiveStreams]] に含まれるWebTransport ストリーム上でも発生する。

  9. CleanuptransportAbortError および closeInfo を渡す。

getStats()

この WebTransport基盤コネクション の統計情報を収集し、非同期に結果を返す。

getStats が呼ばれたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. transportthis とする。

  2. p を新しい promise とする。

  3. もし transport.[[State]]"failed" であれば、 rejectpInvalidStateError で拒否し、この手順を中止する。

  4. 次の手順を 並列 で実行:

    1. もし transport.[[State]]"connecting" であれば、状態が変化するまで待機する。

    2. もし transport.[[State]]"failed" であれば、 ネットワークタスクをキューし、 transportreject pInvalidStateError で拒否してこの手順を中止する。

    3. もし transport.[[State]]"closed" であれば、 ネットワークタスクをキューtransportresolve p をコネクションの直近の統計値で解決し、この手順を中止する。統計値をどの時点で取得するかは実装依存

    4. gatheredStats を、リスト基盤コネクション固有の WebTransportConnectionStats および WebTransportDatagramStats辞書メンバを正確に埋めるのに必要な値とする。

    5. ネットワークタスクをキューtransport で以下を実行:

      1. stats新しい WebTransportConnectionStats オブジェクトとする。

      2. datagramStats新しい WebTransportDatagramStats オブジェクトとする。

      3. stats["datagrams"] に datagramStats を設定する。

      4. ユーザーエージェントが公開したい stats および datagramStatsmember ごとに、 setgatheredStats の対応する エントリを設定する。

      5. resolvepstats で解決する。

  5. p を返す。

exportKeyingMaterial(BufferSource label, optional BufferSource context)

この WebTransport基盤コネクションに一意に紐付く TLS セッションから TLS Keying Material Exporter を用いてキーをエクスポートする。

exportKeyingMaterial が呼ばれたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. transportthis とする。

  2. labelLengthlabelバイト長とする。

  3. もし labelLength が 255 より大きい場合、promise rejectedRangeError で返す。

  4. contextLength を 0 とする。

  5. もし context が指定されていれば、contextLengthcontextバイト長に設定する。

  6. もし contextLength が 255 より大きい場合、promise rejectedRangeError で返す。

  7. p を新しい promise とする。

  8. 次の手順を 並列で実行する。ただし、abort when transport[[State]]"closed" または "failed" になった場合は中止し、 代わりに ネットワークタスクをキューし、 transportreject pInvalidStateError で行う:

    1. keyingMaterial をエクスポートされた TLS キー情報として取得する([WEB-TRANSPORT-OVERVIEW] Section 4.1に従う)、labelLengthlabelcontextLengthcontext(ある場合)を使う。

    2. ネットワークタスクをキューtransportresolve pkeyingMaterial で解決する。

  9. p を返す。

createBidirectionalStream()

送信用の WebTransportBidirectionalStream オブジェクトを作成する。ストリームの作成だけではピアにはすぐに認識されず、データ送信を伴って初めて認識される。

Note: サーバはデータ送信があるまでこのストリームの存在を認識しない。

createBidirectionalStream が呼ばれたとき、ユーザーエージェントは次の手順を実行しなければならない:
  1. もし this.[[State]]"closed" または "failed" なら、 新しい rejected promise を InvalidStateError で返す。

  2. sendGroupoptionssendGroup とする。

  3. もし sendGroup が null でなく、 sendGroup.[[Transport]]this でない場合、throwInvalidStateError を返す。

  4. sendOrderoptionssendOrder とする。

  5. waitUntilAvailableoptionswaitUntilAvailable とする。

  6. p を新しい promise とする。

  7. transportthis とする。

  8. 次の手順を 並列で実行。ただし abort whentransport[[State]]"closed" または "failed" になった場合は ネットワークタスクをキューして、 transportreject pInvalidStateError で拒否する:

    1. streamIdtransport.[[Session]] に対して有効かつ一意な新しいストリームIDとし([QUIC] Section 19.11参照)、 すぐに取得できない場合、waitUntilAvailableがtrueなら待つ。falseなら ネットワークタスクをキューtransportreject pQuotaExceededError で拒否してこの手順を中止する。

    2. internalStreambidirectional stream の作成transport.[[Session]] および streamId を渡して得る。

    3. ネットワークタスクをキューtransport で以下を実行:

      1. もし transport.[[State]]"closed" または "failed" なら、 reject pInvalidStateError で拒否してこの手順を中止する。

      2. stream作成した WebTransportBidirectionalStreaminternalStream, transport, sendGroup, sendOrder渡す) とする。

      3. resolvepstream で解決する。

  9. p を返す。

createUnidirectionalStream()

送信用の WebTransportSendStream を作成する。ストリームの作成だけではサーバにはすぐに認識されず、データ送信で初めて認識される。

Note: サーバはデータ送信があるまでこのストリームの存在を認識しない。

createUnidirectionalStream() メソッドが呼ばれたとき、ユーザーエージェントは 次の手順を実行しなければならない:
  1. もし this.[[State]]"closed" または "failed" なら、 新しい rejected promise を InvalidStateError で返す。

  2. sendGroupoptionssendGroup とする。

  3. もし sendGroup が null でなく、 sendGroup.[[Transport]]this でない場合、throwInvalidStateError を返す。

  4. sendOrderoptionssendOrder とする。

  5. waitUntilAvailableoptionswaitUntilAvailable とする。

  6. p を新しい promise とする。

  7. transportthis とする。

  8. 次の手順を 並列で実行。ただし abort whentransport[[State]]"closed" または "failed" になった場合は ネットワークタスクをキューし、 transportreject pInvalidStateError で拒否する:

    1. streamIdtransport.[[Session]] に対して有効かつ一意な新しいストリームIDとし([QUIC] Section 19.11参照)、 すぐに取得できない場合、waitUntilAvailableがtrueなら待つ。falseなら ネットワークタスクをキューtransportreject pQuotaExceededError で拒否してこの手順を中止する。

    2. internalStream送信単方向ストリームの作成transport.[[Session]] および streamId を渡して得る。

    3. ネットワークタスクをキューtransport で以下を実行:

      1. もし transport.[[State]]"closed" または "failed" なら、 reject pInvalidStateError で拒否してこの手順を中止する。

      2. stream作成した WebTransportSendStreaminternalStream, transport, sendGroup, sendOrder渡す) とする。

      3. resolvepstream で解決する。

  9. p を返す。

createSendGroup()

WebTransportSendGroup を作成する。

createSendGroup() メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:
  1. もし this.[[State]]"closed" または "failed" であれば、 throwInvalidStateError を返す。

  2. 作成した WebTransportSendGroupthis 渡す)を返す。

6.5. 手順

WebTransport transporterror および オプションで closeInfo を用いて cleanup するには、次の手順を実行する:
  1. sendStreamstransport.[[SendStreams]] のコピーとする。

  2. receiveStreamstransport.[[ReceiveStreams]] のコピーとする。

  3. outgoingDatagramWritablestransport.[[Datagrams]].[[Writables]] とする。

  4. incomingDatagramstransport.[[Datagrams]].[[Readable]] とする。

  5. readytransport.[[Ready]] とする。

  6. closedtransport.[[Closed]] とする。

  7. incomingBidirectionalStreamstransport.[[IncomingBidirectionalStreams]] とする。

  8. incomingUnidirectionalStreamstransport.[[IncomingUnidirectionalStreams]] とする。

  9. transport.[[SendStreams]] に空の set を設定する。

  10. transport.[[ReceiveStreams]] に空の set を設定する。

  11. transport.[[Datagrams]].[[OutgoingDatagramsQueue]] に空の queue を設定する。

  12. transport.[[Datagrams]].[[IncomingDatagramsQueue]] に空の queue を設定する。

  13. もし closeInfo が渡された場合、transport.[[State]]"closed" に設定する。 そうでなければ transport.[[State]]"failed" に設定する。

  14. sendStreams の各 stream について、次の手順を実行:

    1. もし stream.[[PendingOperation]] が null でなければ、その stream.[[PendingOperation]]error で reject する。

    2. Errorstreamerror でエラーにする。

  15. receiveStreams の各 stream について、errorstreamerror でエラーにする。

    Note: スクリプト作成者はPromise解決時に同期的なコードを挿入できる。そのためここからは transport を触ってはならない。予測不可能な形で script により破壊されている場合がある。 この制約はこの手続きを呼び出すロジックにも適用される。

  16. もし closeInfo が渡された場合:

    1. ResolveclosedcloseInfo で解決する。

    2. Assert: readysettled である。

    3. CloseincomingBidirectionalStreams をクローズする。

    4. CloseincomingUnidirectionalStreams をクローズする。

    5. outgoingDatagramWritables の各 writable について、closewritable をクローズする。

    6. CloseincomingDatagrams をクローズする。

  17. それ以外:

    1. Rejectclosederror で拒否する。

    2. closed.[[PromiseIsHandled]] を true に設定する。

    3. Rejectreadyerror で拒否する。

    4. ready.[[PromiseIsHandled]] を true に設定する。

    5. ErrorincomingBidirectionalStreamserror でエラーにする。

    6. ErrorincomingUnidirectionalStreamserror でエラーにする。

    7. outgoingDatagramWritables の各 writable について、errorwritableerror でエラーにする。

    8. ErrorincomingDatagramserror でエラーにする。

WebTransport transport と 一連の steps で queue a network task するには、次の手順を実行する:

  1. グローバルタスクをキューし、 ネットワークタスクソースtransportrelevant global object を用いて steps を実行する。

6.6. クライアントによって開始されていないセッション終了

WebTransport セッションが、WebTransport transport に関連付けられていて オプションで codereasonBytes とともに 終了するときは、次の手順を実行:
  1. ネットワークタスクをキューtransport で次の手順を実行する:

    1. もし transport.[[State]]"closed" または "failed" なら、この手順を中止する。

    2. error を新たに 作成した WebTransportErrorsource"session"

    3. closeInfo新しい WebTransportCloseInfo とする。

    4. もし code が与えられていれば、closeInfocloseCodecode を設定する。

    5. もし reasonBytes が与えられていれば、closeInforeasonreasonBytesUTF-8 デコードした値で設定する。

      Note: reasonBytes には言語や方向のメタデータは含まれない。 表示時の方向には first-strong ヒューリスティクスを用いることができる。

    6. Cleanuptransport, error, closeInfo を渡す。

WebTransport transport基盤コネクション でコネクションエラーが発生した時は、次の手順を実行:
  1. ネットワークタスクをキューtransport で次の手順を実行する:

    1. もし transport.[[State]]"closed" または "failed" なら、この手順を中止する。

    2. error を新たに 作成した WebTransportErrorsource"session"

    3. Cleanuptransport, error を渡す。

6.7. コンテキストクリーンアップ手順

この仕様では、コンテキストクリーンアップ手順を以下の手順として定義する。 WebTransport transport が与えられた場合:

  1. もし transport.[[State]]"connected" なら、次を行う:

    1. transport.[[State]]"failed" に設定する。

    2. 並行してterminatetransport.[[Session]] に対して実行する。

    3. ネットワークタスクをキューに入れるtransport を与え、次の手順を実行する:

      1. error を、新たに 作成された WebTransportError とし、 その source"session" とする。

      2. Cleanuptransport に対して error を用いて行う。

  2. もし transport.[[State]]"connecting" なら、transport.[[State]]"failed" に設定する。

    これはワーカーでも実施する必要がある。次を参照: #127 および whatwg/html#6731

6.8. ガベージコレクション

WebTransport オブジェクトの [[State]]"connecting" の場合、[[IncomingBidirectionalStreams]][[IncomingUnidirectionalStreams]]、 いずれかの WebTransportReceiveStream、 または [[Datagrams]].[[Readable]]lockedされている場合、または readydrainingclosed promise が監視されている場合は、ガベージコレクションされてはならない。

WebTransport オブジェクトの [[State]]"connected" の場合、[[IncomingBidirectionalStreams]][[IncomingUnidirectionalStreams]]、 いずれかの WebTransportReceiveStream、 または [[Datagrams]].[[Readable]]lockedされている場合、またはdrainingclosed promise が監視されている場合は、ガベージコレクションされてはならない。

WebTransport オブジェクトの [[State]]"draining" の場合、[[IncomingBidirectionalStreams]][[IncomingUnidirectionalStreams]]、 いずれかの WebTransportReceiveStream、 または [[Datagrams]].[[Readable]]lockedされている場合、または closed promise が監視されている場合は、ガベージコレクションされてはならない。

確立済みWebTransport セッションを持ち、 ネットワークへ送信待ちのデータ([[Datagrams]].[[OutgoingDatagramsQueue]]内のデータグラムを含む)がある WebTransport オブジェクトは、ガベージコレクションされてはならない。

WebTransport オブジェクトが、基盤コネクション がまだ開いている間にガベージコレクションされた場合、 ユーザーエージェントは Application Error Code 0、Application Error Message "" でWebTransportセッションを終了 しなければならない。

6.9. 設定

dictionary WebTransportHash {
  required DOMString algorithm;
  required BufferSource value;
};

dictionary WebTransportOptions {
  boolean allowPooling = false;
  boolean requireUnreliable = false;
  sequence<WebTransportHash> serverCertificateHashes = [];
  WebTransportCongestionControl congestionControl = "default";
  [EnforceRange] unsigned short? anticipatedConcurrentIncomingUnidirectionalStreams = null;
  [EnforceRange] unsigned short? anticipatedConcurrentIncomingBidirectionalStreams = null;
  sequence<DOMString> protocols = [];
  ReadableStreamType datagramsReadableType;
};

enum WebTransportCongestionControl {
  "default",
  "throughput",
  "low-latency",
};

WebTransportOptions は、WebTransport セッションがどのように確立・利用されるかを決定するためのパラメータの辞書である。

allowPooling, of type boolean, defaulting to false

true の場合、WebTransport セッションはプール可能(複数 WebTransport セッション間で 基盤コネクション の共有が可能)となる。

requireUnreliable, of type boolean, defaulting to false

true の場合、HTTP/3 connection が不可の場合、WebTransport セッションは HTTP/2 connection 上では確立されない。

serverCertificateHashes, of type sequence<WebTransportHash>, defaulting to []

このオプションは専用コネクション利用時のみサポートされる。 この機能が未サポートのトランスポートプロトコルで本フィールドが空でない場合は NotSupportedError 例外がスローされる。

サポートされており非空の場合、ユーザーエージェントは 証明書ハッシュの検証serverCertificateHashes で一致し、カスタム証明書要件も満たす場合に限り サーバ証明書を信頼すべきである。未知のalgorithm のハッシュは無視される。 の場合は通常の fetch 操作時と同じ証明書検証を行う。

これは allowPooling と併用できない。

congestionControl, of type WebTransportCongestionControl, defaulting to "default"

データ送信時に利用する輻輳制御アルゴリズムについて、 スループット最適/低遅延最適どちらをアプリが好むかヒントとして指定できる。これはユーザーエージェントへのヒント。

この構成オプションは、低遅延最適アルゴリズムのブラウザー実装が当時存在しないため、リスクのあるフィーチャーとされている。

anticipatedConcurrentIncomingUnidirectionalStreams, of type unsigned short, nullable, defaulting to null

アプリがサーバで同時オープンされると予想する 着信単方向ストリーム数を指定できる。 ユーザーエージェントは初期状態で少なくとも100本の 着信単方向 ストリームを許可しなければならない。 nullでなければ、サーバとのネゴシエーション時に [[AnticipatedConcurrentIncomingUnidirectionalStreams]] を考慮してラウンドトリップ削減に努めるべきである。

anticipatedConcurrentIncomingBidirectionalStreams, of type unsigned short, nullable, defaulting to null

アプリがサーバで同時オープンされると予想する 双方向ストリーム数を指定できる。 ユーザーエージェントは初期状態でサーバに少なくとも100本の 双方向ストリーム作成を許可しなければならない。 nullでなければ、サーバとのネゴシエーション時に [[AnticipatedConcurrentIncomingBidirectionalStreams]] を考慮してラウンドトリップ削減に努めるべきである。

protocols, of type sequence<DOMString>, defaulting to []

アプリケーションレベルの プロトコル名 を格納する配列を省略可能で指定できる。サーバ側でプロトコル選択と通知は任意。 適切なプロトコルが指定されていなければサーバはリクエストを拒否することがある。

datagramsReadableType, of type ReadableStreamType

アプリの受信データグラム用に readable byte stream の利用を希望する場合に指定できる。 指定しなければデフォルトで readable stream が用いられる。

Note: readable stream はデータグラムセマンティクスに互換性があるが、 readable byte stream は互換性がない。 データグラムは長さ0以上の独立したメッセージで順不同で到着し、単なるバイト列ではない。空のデータグラムは失われ、 min ではメッセージ区切りが失われる。

証明書ハッシュを計算するために、certificate を与え、次の手順を実行する:

  1. certcertificate とし、[RFC5280] で定義される Certificate メッセージの DER エンコーディングとして表現する。

  2. cert の SHA-256 ハッシュを計算し、計算された値を返す。

証明書ハッシュを検証するために、certificate chain とハッシュ配列 hashes を与え、次の手順を実行する:

  1. certificatecertificate chain の最初の証明書(リーフ証明書)とする。

  2. referenceHash を、certificate を用いて証明書ハッシュを計算した結果とする。

  3. hashes 内のすべてのハッシュ hash について:

    1. もし hash.value が null でなく、かつ hash.algorithm が "sha-256" とASCII 大文字小文字非区別で一致するなら:

      1. hashValue を、hash.value が表すバイト列とする。

      2. もし hashValuereferenceHash に等しいなら、true を返す。

  4. false を返す。

カスタム証明書要件は次のとおりである: 証明書は[RFC5280]で定義される X.509v3 証明書でなければならず、 Subject Public Key フィールドで使用される鍵は許可された公開鍵アルゴリズムのいずれかでなければならない。 現在時刻は、[RFC5280] のセクション 4.1.2.5 で定義される証明書の有効期間内でなければならず、 有効期間の総期間は 2 週間を超えてはならない。ユーザーエージェントは証明書に対して追加の 実装定義の要件を課すことができる。

Subject Public Key Info フィールド(その結果として TLS の CertificateVerify メッセージにおいて)で使用される許可された公開鍵アルゴリズムの正確なリストは実装定義である。しかし、相互運用可能な既定とするために、secp256r1(NIST P-256)名前付きグループを用いた ECDSA([RFC3279]、 セクション 2.3.5;[RFC8422])を含めなければならない。 RSA 鍵([RFC3279]、 セクション 2.3.1)は含めてはならない。

6.10. WebTransportCloseInfo辞書

WebTransportCloseInfo辞書は、 終了処理時に WebTransportセッションのエラーコードと理由を設定するための情報を含みます。

dictionary WebTransportCloseInfo {
  unsigned long closeCode = 0;
  USVString reason = "";
};

この辞書は以下の属性を持ちます:

closeCode型:unsigned long、デフォルトは0

ピアに通知されるエラーコードです。

reason型:USVString、デフォルトは""

WebTransportを閉じる理由です。

6.11. WebTransportSendOptions辞書

WebTransportSendOptionsは、 createUnidirectionalStreamcreateBidirectionalStreamcreateWritable の振る舞いに影響を与える基本パラメータの辞書です。

dictionary WebTransportSendOptions {
  WebTransportSendGroup? sendGroup = null;
  long long sendOrder = 0;
};

この辞書は次の属性を持ちます:

sendGroup, WebTransportSendGroup、null可能、デフォルトはnull

作成されたストリームをグループ化するための任意のWebTransportSendGroup、またはnull。

sendOrder, long long、デフォルトは0

送信順序番号。指定すると作成されたストリームは厳密な順序付けに参加します。 現在厳密順序ストリームにキューされたバイトは、より小さい送信順序番号で作成された他の厳密順序ストリームにキューされたバイトよりも先に送信されます。

送信順序番号が指定されていない場合、他のストリームとの相対的な送信順は実装定義です。ただし、ユーザーエージェントは、低い順序番号で飢餓状態になっていない限り、すべてのストリーム間で帯域を公平に分配することが強く推奨されます。

注: これは送信側のデータ優先制御であり、受信順序を保証するものではありません。

6.12. WebTransportSendStreamOptions辞書

WebTransportSendStreamOptionsは、 WebTransportSendStreamの パラメータ辞書であり、 createUnidirectionalStream および createBidirectionalStream で生成されたストリームの振る舞いに影響します。

dictionary WebTransportSendStreamOptions : WebTransportSendOptions {
  boolean waitUntilAvailable = false;
};

この辞書は次の属性を持ちます:

waitUntilAvailable, boolean、デフォルトはfalse

trueの場合、 createUnidirectionalStreamcreateBidirectionalStream の呼び出しで返されるPromiseは、 settled されるまで、基盤となるコネクションがストリーム生成に十分なフロー制御クレジットを持つか あるいはコネクションが新たな送信ストリームを生成できない状態になるまで待機します。falseの場合、呼び出し時にフロー制御ウィンドウがなければPromiseは rejectedされます。

6.13. WebTransportConnectionStats辞書

WebTransportConnectionStats 辞書は、WebTransport セッション基盤の接続に関する WebTransport 固有の統計情報を含む。

Note: プーリングが使用される場合、同じ connection 上でプールされた複数の WebTransport セッション はすべて同じ情報を受け取る。つまり、同じ network partition key を保持するプールされた sessions 間で情報が開示される。

Note: 利用不能な統計は 欠落 として、WebTransportConnectionStats 辞書から省かれる。

dictionary WebTransportConnectionStats {
  unsigned long long bytesSent;
  unsigned long long bytesSentOverhead;
  unsigned long long bytesAcknowledged;
  unsigned long long packetsSent;
  unsigned long long bytesLost;
  unsigned long long packetsLost;
  unsigned long long bytesReceived;
  unsigned long long packetsReceived;
  DOMHighResTimeStamp smoothedRtt;
  DOMHighResTimeStamp rttVariation;
  DOMHighResTimeStamp minRtt;
  required WebTransportDatagramStats datagrams;
  unsigned long long? estimatedSendRate = null;
  boolean atSendCapacity = false;
};

この辞書は以下の属性を持つものとする:

bytesSent, unsigned long long

基盤コネクション を通じて送信されたペイロードバイト数(フレーミングオーバーヘッドおよび再送信を除く)。

bytesSentOverhead, unsigned long long

bytesSent のペイロードバイトを 基盤コネクションで送信した際のフレーミングおよび再送信のオーバーヘッド(バイト単位)。

bytesAcknowledged, unsigned long long

QUICのACK機構によりサーバに受信済みと確認されたペイロードバイト数(フレーミングを除く、基盤コネクション上)。

Note: 通常は bytesSent より遅れて増加するが、パケットロスのため永続的に小さい場合もある。

bytesAcknowledgedWebTransportConnectionStats でWorking Groupにより実装懸念のためリスクあり機能として識別されている。
packetsSent, unsigned long long

基盤コネクションで送信された全パケット数(ロスト扱いのものも含む)。

bytesLost, unsigned long long

基盤コネクション で失われたバイト数。 (ロスト扱いのパケットが後で受信される場合もあるため単調増加ではない。UDPやその外側のフレーミングは含まない)。

packetsLost, unsigned long long

基盤コネクション で失われたパケット数。 (ロスト扱いのパケットが後で受信される場合もあるため単調増加ではない)。

bytesReceived, unsigned long long

基盤コネクション で受信した全バイト数(ストリームの重複データを含む、UDPや外側のフレーミングは除く)。

packetsReceived, unsigned long long

基盤コネクション で受信した全パケット数(処理不可なパケットも含む)。

smoothedRtt, DOMHighResTimeStamp

コネクションで観測中の平滑化されたラウンドトリップタイム(RTT):[RFC9002] Section 5.3

rttVariation, DOMHighResTimeStamp

現在コネクションで観測中のラウンドトリップタイムサンプルの平均変動幅:[RFC9002] Section 5.3

minRtt, DOMHighResTimeStamp

コネクション全体で観測された最小ラウンドトリップタイム:[RFC9002] Section 5.2

estimatedSendRate, unsigned long long, nullable, 初期値 null

ユーザーエージェントがキューに投入されたデータを送信する推定レート(bps)。 この値は同じ WebTransportセッション を共有する全ストリーム・データグラムに適用され、輻輳制御アルゴリズム(congestionControlで選ばれうる)による。 フレーミングオーバーヘッドは含まない。アプリケーションペイロードが送信されうる速度を示す。 推定値が不明な場合はnull。過去にnullでなかった後にnullとなる場合もある。

atSendCapacity, boolean, 初期値 false

false の場合、estimatedSendRate はアプリケーション制限(輻輳制御が許可するよりはるかに少ないデータをアプリが送出している状態)を示している可能性がある。 アプリケーション制限中、使用可能なネットワーク容量の推定値は不正確となりうる。

true の場合、アプリケーションはネットワーク容量上限でデータを送信中であり、 estimatedSendRate はアプリの利用可能なネットワーク容量を反映する。

atSendCapacitytrue の場合、 estimatedSendRate は実効上限値となる。 アプリ送信レートが継続する限り、この値はネットワーク状況に適応する。ただし estimatedSendRateatSendCapacity が true のときでも null になりうる。

6.14. WebTransportDatagramStats辞書

WebTransportDatagramStats 辞書には 基盤コネクション 上のデータグラム送受信に関する統計が含まれる。

dictionary WebTransportDatagramStats {
  unsigned long long droppedIncoming;
  unsigned long long expiredIncoming;
  unsigned long long expiredOutgoing;
  unsigned long long lostOutgoing;
};

この辞書は以下の属性を持つものとする:

droppedIncoming, unsigned long long

アプリケーションがdatagramsreadable から読み出す前に、受信キューが新しいデータグラムであふれてしまったために廃棄された受信データグラムの数。

expiredIncoming, unsigned long long

incomingMaxAge よりも古くなったため、datagramsreadable から読み出される前に廃棄された受信データグラムの数。

expiredOutgoing, unsigned long long

送信待ちキュー内のデータグラムがoutgoingMaxAge よりも古くなったため送信される前に廃棄された数。

lostOutgoing, unsigned long long

送信済みデータグラムのうちロスト([RFC9002] Section 6.1参照)と判定された数。

7. インターフェイス WebTransportSendStream

WebTransportSendStream は、送信単方向または双方向WebTransportストリームを使った送信ストリーミング機能を提供する WritableStream です。

これはサーバーにデータを送信するために書き込み可能な WritableStream 型のUint8Array です。

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportSendStream : WritableStream {
  attribute WebTransportSendGroup? sendGroup;
  attribute long long sendOrder;
  Promise<WebTransportSendStreamStats> getStats();
  WebTransportWriter getWriter();
};

WebTransportSendStream は必ずcreate手続きによって作成されます。

WebTransportSendStream転送ステップおよび 転送受信ステップWritableStreamのものです。

7.1. 属性

sendGroup, WebTransportSendGroup, nullable

ゲッター手順:

  1. this[[SendGroup]] を返す。

セッター手順(value 与えられた場合):

  1. もし value が null でなく、 value.[[Transport]]this.[[Transport]] でなければ、 throwInvalidStateError を投げる。

  2. this[[SendGroup]]value を設定する。

sendOrder, long long

ゲッター手順:

  1. this[[SendOrder]] を返す。

セッター手順(value 与えられた場合):

  1. this[[SendOrder]]value を設定する。

7.2. メソッド

getStats()

このWebTransportSendStream のパフォーマンスに特化した統計情報を収集し、その結果を非同期に報告する。

getStatsが呼ばれたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. p を新しい promise とする。

  2. 次の手順を 並列 で実行する:

    1. gatheredStats を、この this WebTransportSendStream辞書メンバー WebTransportSendStreamStats を正確に埋めるのに必要な統計のリストとする。

    2. ネットワークタスクをキューとして transport で次の手順を実行する:

      1. stats新しい WebTransportSendStreamStats オブジェクトとする。

      2. ユーザーエージェントが公開したい statsmember ごとに、 setgatheredStats の 対応する entry を設定する。

      3. resolvepstats で解決する。

  3. p を返す。

getWriter()

このメソッドはgetWriterWritableStreamから継承) と同様に実装しなければならない。ただし WritableStreamDefaultWriter を作成する代わりに WebTransportWriterthis で作成しなければならない。

7.3. 内部スロット

WebTransportSendStream は以下の内部スロットを持つ。

内部スロット 説明 (非規範的)
[[InternalStream]] 送信単方向または双方向 WebTransport ストリーム
[[PendingOperation]] 書き込みまたはクローズ処理が保留中であればその promise、それ以外は null。
[[Transport]] この WebTransport を所有する WebTransportSendStream
[[SendGroup]] オプションの WebTransportSendGroup、 または null。
[[SendOrder]] オプションの送信順序番号。デフォルトは0。
[[AtomicWriteRequests]] 順序付き集合で、 基盤の sink にキューイングされた書き込みリクエストのうちアトミックなものを追跡するための promises。
[[BytesWritten]] このストリームに書き込まれたバイト数。
[[CommittedOffset]] ストリーム内でピアに配信されるバイト数を記録するオフセット。ストリームが送信中止 された場合でも有効。 [RELIABLE-RESET] 参照。

7.4. 手続き

生成するには、 WebTransportSendStream送信単方向または双方向WebTransportストリーム internalStreamWebTransport transportsendGroup、およびsendOrderを指定して、次の手順を実行する:

  1. streamnew WebTransportSendStream として以下のプロパティで作成:

    [[InternalStream]]

    internalStream

    [[PendingOperation]]

    null

    [[Transport]]

    transport

    [[SendGroup]]

    sendGroup

    [[SendOrder]]

    sendOrder

    [[AtomicWriteRequests]]

    空の順序付きセット(promise)。

    [[BytesWritten]]

    0

    [[CommittedOffset]]

    0

  2. writeAlgorithmを、chunkを与えられた時にstream書き込むアクションとして定義。

  3. closeAlgorithmを、stream閉じるアクションとして定義。

  4. abortAlgorithmを、reasonを与えられた時にstream中止するアクションとして定義。

  5. streamのセットアップを行い、 writeAlgorithmwriteAlgorithmに、 closeAlgorithmcloseAlgorithmに、 abortAlgorithmabortAlgorithmに設定する。

  6. abortSignalstreamの[[controller]].[[abortController]].[[signal]]とする。

  7. abortSignalに次のステップを追加

    1. pendingOperationstream.[[PendingOperation]]とする。

    2. pendingOperationがnullなら、これらのステップを中止。

    3. stream.[[PendingOperation]] をnullに設定。

    4. reasonabortSignal中止理由とする。

    5. streamの中止reason)の結果をpromiseとする。

    6. promiseがFulfilledになった時、 pendingOperationをreasonでrejectする。

  8. streamtransport.[[SendStreams]]追加

  9. streamを返す。

writechunkWebTransportSendStream stream に書き込むには、次の手順を実行する:
  1. transportstream.[[Transport]] とする。

  2. もし chunkBufferSource でなければ、promise rejected withTypeError を返す。

  3. promise を新しい promise とする。

  4. byteschunk が表す バイト列のコピーとする。

  5. stream.[[PendingOperation]]promise をセットする。

  6. inFlightWriteRequeststream.inFlightWriteRequest とする。

  7. atomic を、 stream.[[AtomicWriteRequests]]inFlightWriteRequest を含む場合に true、 それ以外は false とする。

  8. 次の手順を 並列で実行する:

    1. もし atomic が true で、現在の フロー制御ウィンドウが bytes 全体分の送信に小さすぎる場合は、 残りの手順を中止し、ネットワークタスクをキューし、 transport で次のサブステップを実行する:

      1. stream.[[PendingOperation]] に null をセットする。

      2. すべてのアトミック書き込みリクエストを中止stream で実施する。

    2. それ以外の場合、送信bytesstream.[[InternalStream]] に送り、操作完了まで待機する。 この送信は、すでにキューに入っているストリームやデータグラム、これからキューにされるストリームやデータグラムと インターリーブされる場合がある。

      ユーザーエージェントはパフォーマンス改善のためにバッファを用いることがある。このバッファにはバックプレッシャー反映のために固定上限を設けるべきである。 WebTransportSendStream の利用者にその情報が伝わるようにすべきである。

      この送信は、 同じ [[SendGroup]] かつ、より高い [[SendOrder]] を持ち、かつ エラー状態でなくフロー制御でブロックされていないストリーム全ての 送信待ちのバイトが送り終わるまでスターブ状態になること。

      ここで stream.[[SendOrder]]並列でアクセスがある。 ユーザーエージェントは送信中にこれら値の動的変更へ対応すべきであるが、 詳細は実装定義とする。

      注記: 再送の順序は 実装定義だが、 ユーザーエージェントはより高い [[SendOrder]] のデータ再送を優先することが強く推奨される。

      フロー制御やエラー以外の理由でスターブ状態になるべきではない。

      ユーザーエージェントはスターブでない全ストリーム間で帯域幅を公平に分配すべきである。

      注記: ここでの公平性の定義は実装定義である。

    3. 前のステップでネットワークエラーが生じたら、残りの手順を中止する。

      注記: ここで promise を reject しない。ネットワークエラーは本来別部分で処理され、stream.[[PendingOperation]] を reject する。

    4. それ以外の場合、ネットワークタスクをキューし、 transport で次の手順を実行する:

      1. stream.[[PendingOperation]] に null をセットする。

      2. stream.[[BytesWritten]]bytes の長さを加算する。

      3. もし stream.[[AtomicWriteRequests]]inFlightWriteRequest を含む場合、 inFlightWriteRequest を取り除く。

      4. resolvepromise に undefined を渡す。

  9. promise を返す。

注記: このアルゴリズムが返す promise (または write(chunk)) が fulfill されても、その chunk がサーバーに ack されたとは限らない。 バッファに追加されたのみの場合もある。 chunk がサーバーに届いたことを保証したい場合は、サーバー側アプリケーションレベルの ack メッセージ送信が必要である。

closeWebTransportSendStream stream を閉じるには、次を実行する:
  1. transportstream.[[Transport]] とする。

  2. promise を新しい promise とする。

  3. Removestreamtransport.[[SendStreams]] から取り除く。

  4. stream.[[PendingOperation]]promise をセットする。

  5. 次の手順を 並列で実行する:

    1. FIN を送信し、 stream.[[InternalStream]]で完了を待つ。

    2. stream.[[InternalStream]] が "all data committed" 状態に遷移するまで待機。[QUIC]

    3. ネットワークタスクをキューし、 transport で次の手順を実行:

      1. stream.[[PendingOperation]] に null をセットする。

      2. resolvepromise に undefined を渡す。

  6. promise を返す。

abortWebTransportSendStream streamreason 付きで中止するには、次の手順を実行する:
  1. transportstream.[[Transport]] とする。

  2. promise を新しい promise とする。

  3. code を 0 とする。

  4. Removestreamtransport.[[SendStreams]] から取り除く。

  5. もし reasonWebTransportError でありかつ reason.[[StreamErrorCode]] が null でなければ、その値を code にセットする。

  6. もし code < 0 なら、code を 0 にセットする。

  7. もし code > 4294967295 なら、code を 4294967295 にセットする。

  8. committedOffsetstream.[[CommittedOffset]] とする。

    注記: code の有効範囲は 0~4294967295。 基礎接続 が HTTP/3 の場合は コードは [0x52e4a40fa8db, 0x52e5ac983162] にエンコードされる。 [WEB-TRANSPORT-HTTP3] を参照。

  9. 次の手順を 並列で実行する:

    1. 送信中止stream.[[InternalStream]]code および committedOffset で行う。

    2. ネットワークタスクをキューし、 transportresolvepromise に undefined を渡す。

  10. promise を返す。

すべてのアトミック書き込みリクエストを中止WebTransportSendStream stream に対して行うには、次の手順を実行する:
  1. writeRequestsstream.writeRequests とする。

  2. requestsToAbortstream.[[AtomicWriteRequests]] とする。

  3. もし writeRequestsrequestsToAbort に含まれない promise を含む場合、 errorstreamAbortError を設定し、 この手順を中止する。

  4. Emptystream.[[AtomicWriteRequests]] を空にする。

  5. requestsToAbort の各 promise について、 rejectpromiseAbortError を渡す。

  6. 並列で requestsToAbortpromise について、その 送信 を中止する。

7.5. サーバーから送信された受信中止シグナルの受信

サーバーからreceiving aborted(受信中止)のシグナルを受け取ったとき、WebTransportSendStream stream に関連付けられたWebTransport streamに対し、次の手順を実行する:
  1. transportstream.[[Transport]] とする。

  2. code を、receiving aborted シグナルに付随するアプリケーションプロトコルのエラーコードとする。

    Note: code の有効な値は 0 から 4294967295(両端を含む)。underlying connection が HTTP/3 を使用している場合、コードは [WEB-TRANSPORT-HTTP3] に記載のとおり [0x52e4a40fa8db, 0x52e5ac983162] の範囲の数値にエンコードされる。

  3. Queue a network tasktransport で実行し、次の手順を行う:

    1. もし transport.[[State]]"closed" または "failed" なら、これらの手順を中止する。

    2. Remove を行い、transport.[[SendStreams]] から stream を取り除く。

    3. error を、新たに 作成された WebTransportError とし、 その source"stream"、かつ streamErrorCodecode とする。

    4. もし stream.[[PendingOperation]] が null でないなら、stream.[[PendingOperation]]error で reject する。

    5. Error を行い、streamerror でエラー状態にする。

7.6. WebTransportSendStreamStats辞書

WebTransportSendStreamStats辞書には、 1つのWebTransportSendStream に特有の統計情報が含まれます。

dictionary WebTransportSendStreamStats {
  unsigned long long bytesWritten;
  unsigned long long bytesSent;
  unsigned long long bytesAcknowledged;
};

この辞書は以下の属性を持つものとする:

bytesWritten, unsigned long long

アプリケーションがこの WebTransportSendStream に正常に書き込んだバイト数の合計。この値は増加のみ行われる。

bytesSent, unsigned long long

この WebTransportSendStream に書き込み済みのアプリケーションバイトのうち、少なくとも一度は送信されたものの進捗を示す指標。この値は増加のみ行われ、常に bytesWritten 以下となる。

Note: これは単一ストリームで送信されたアプリデータの進捗のみを示し、ネットワークのオーバーヘッドは含まない。

bytesAcknowledged, unsigned long long

この WebTransportSendStream に書き込み済みのアプリケーションバイトがサーバのQUIC ACK機構で送信・受信確認されたバイトの進捗指標。最初の未確認バイト未満までの連続したバイトのみをカウント。この値は増加のみ行われ、常に bytesSent 以下となる。

Note: この値はコネクションがHTTP/2の場合、 bytesSent と一致する。

8. インターフェイス WebTransportSendGroup

WebTransportSendGroup は多数の個別(通常は厳密順序WebTransportSendStream にまたがるデータ転送を追跡するためのオプションの管理オブジェクトです。

WebTransportSendStreamは、 生成時またはsendGroup属性の割り当てによって、 同時に最大1つのWebTransportSendGroupグループ化されることができます。デフォルトでは グループ化されていません

ユーザーエージェントは、WebTransportSendGroup 間の帯域分配を平等に扱います。 各WebTransportSendGroupsendOrder 番号評価の独立した数値空間も確立します。

[Exposed=(Window,Worker), SecureContext]
interface WebTransportSendGroup {
  Promise<WebTransportSendStreamStats> getStats();
};

WebTransportSendGroup は必ずcreate手続きによって作成されます。

8.1. メソッド

getStats()

この sendGroup に grouped されているすべての WebTransportSendStream の統計情報を集約し、非同期に結果を返す。

getStats が呼ばれたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. p を新しい promise とする。

  2. streamsWebTransportSendStream[[SendGroup]]this であるもの全てとする。

  3. 次の手順を 並列 で実行する:

    1. gatheredStatsstreams 内の全てのストリームから集約された統計のリストとし、WebTransportSendStreamStats辞書メンバーを正確に埋めるのに必要なものとする。

    2. ネットワークタスクをキューtransport で以下を実行する:

      1. stats新しい WebTransportSendStreamStats オブジェクトとする。

      2. ユーザーエージェントが公開したい statsmember ごとに、 setgatheredStats の 対応する entry を設定する。

      3. resolvepstats で解決する。

  4. p を返す。

8.2. 内部スロット

WebTransportSendGroup は以下の内部スロットを持つ。

内部スロット 説明 (非規範的)
[[Transport]] この WebTransport オブジェクトが所有する WebTransportSendGroup

8.3. 手続き

SendGroup を作成するには、 WebTransportSendGroupWebTransport transport を用いて、以下の手順を実行する:

  1. sendGroup新しい WebTransportSendGroup とし、次のように初期化する:

    [[Transport]]

    transport

  2. sendGroup を返す。

9. インターフェイス WebTransportReceiveStream

WebTransportReceiveStream は、受信単方向または双方向WebTransportストリームを用いて、受信ストリーミング機能を提供する ReadableStream です。

これはサーバーから受信したデータを消費するために読み取ることができる ReadableStream 型のUint8Array です。WebTransportReceiveStream読み取りバイトストリームであり、 利用者はBYOBリーダーだけでなくデフォルトリーダーも使用できます。

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportReceiveStream : ReadableStream {
  Promise<WebTransportReceiveStreamStats> getStats();
};

WebTransportReceiveStream は必ずcreate手続きによって作成されます。

WebTransportReceiveStream転送ステップおよび 転送受信ステップReadableStreamのものです。

9.1. メソッド

getStats()

この WebTransportReceiveStream の性能に特化した統計情報を収集し、 その結果を非同期に報告する。

getStats が呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない:

  1. p を新しい Promise とする。

  2. 次の手順を 並行して実行する:

    1. gatheredStats を、リストthis WebTransportReceiveStream に特化した統計)とし、WebTransportReceiveStreamStats辞書メンバーを正確に埋めるために必要なものとする。

    2. ネットワークタスクをキューに入れtransport を用いて次の手順を実行する:

      1. stats を、newWebTransportReceiveStreamStats オブジェクトとする。

      2. ユーザーエージェントが公開したい stats の各メンバー member について、set を行い、gatheredStats 内の対応するエントリに設定する。

      3. Resolve を行い、pstats で解決する。

  3. p を返す。

9.2. 内部スロット

WebTransportReceiveStream には以下の内部スロットがあります。

内部スロット 説明(非規範的
[[InternalStream]] 受信単方向または双方向WebTransportストリーム
[[Transport]] このWebTransport オブジェクトがこのWebTransportReceiveStreamを所有します。

9.3. 手続き

create を、 WebTransportReceiveStream に対して、incoming unidirectional または bidirectionalWebTransport stream internalStream と、WebTransport transport を用いて実行するには、次の手順を行う:

  1. stream を、newWebTransportReceiveStream とし、以下を持つものとする:

    [[InternalStream]]

    internalStream

    [[Transport]]

    transport

  2. pullAlgorithm を、pulls bytesstream から行うアクションとする。

  3. cancelAlgorithm を、cancelsstream に対して reason を与えて実行するアクションとし、 reason を与えた場合に stream をキャンセルするものとする。

  4. Set up with byte reading support を用いて stream をセットアップし、 pullAlgorithmpullAlgorithm に、 cancelAlgorithmcancelAlgorithm に設定する。

  5. Append を行い、streamtransport.[[ReceiveStreams]] に追加する。

  6. stream を返す。

pull bytesWebTransportReceiveStream stream から行うには、次の手順を実行する。

  1. transport を、stream.[[Transport]] とする。

  2. internalStream を、stream.[[InternalStream]] とする。

  3. promise を新しい promise とする。

  4. bufferoffsetmaxBytes を null とする。

  5. もし streamcurrent BYOB request viewstream に対して null でないなら:

    1. offset を、streamcurrent BYOB request view.[[ByteOffset]] に設定する。

    2. maxBytes を、streamcurrent BYOB request viewbyte length に設定する。

    3. buffer を、streamcurrent BYOB request viewunderlying buffer に設定する。

  6. それ以外の場合:

    1. offset を 0 に設定する。

    2. maxBytesimplementation-defined なサイズに設定する。

    3. buffer を、newArrayBuffer (サイズは maxBytes)に設定する。もし ArrayBuffer の割り当てに失敗した場合は、a promise rejected with を返し、RangeError とする。

  7. 次の手順を 並行して実行する:

    1. Write を行い、read されたバイトを internalStream から bufferoffset 位置へ、最大 maxBytes バイトまで書き込む。少なくとも 1 バイトが 読み込まれるか、FIN が受信されるまで待機する。read を読み込まれたバイト数、hasReceivedFIN を FIN が伴われたかどうかを示すものとする。

      ユーザーエージェントは転送性能を改善するためのバッファを有する場合がある。そのようなバッファは、サーバーへバックプレッシャー情報を伝えるため、固定の上限を持つべきである。

      Note: この操作は、buffer を完全に埋める前に返る場合がある。

    2. 前の手順が失敗した場合、残りの手順を中止する。

      Note: ここでは promise を reject しない。ネットワークエラーは別の場所で処理され、その手順で errorstream に対して発生し、この pull を待っている読み取り要求は拒否されるためである。

    3. Queue a network tasktransport で実行し、次の手順を行う:

      Note: 上で述べたバッファが、この手続きが実行されている event loop 内で利用可能な場合、以下の手順は直ちに実行されることがある。

      1. もし read > 0 なら:

        1. view を新しい Uint8Arraybufferoffsetread)に設定する。

        2. Enqueue を行い、viewstream に投入する。

      2. もし hasReceivedFIN が true なら:

        1. Remove を行い、streamtransport.[[ReceiveStreams]] から取り除く。

        2. Close を行い、stream を閉じる。

      3. Resolve を行い、promise を undefined で解決する。

  8. promise を返す。

cancelWebTransportReceiveStreamstream に対して reason を用いて行うための手順は次のとおり。

  1. transport を、stream.[[Transport]] とする。

  2. internalStream を、stream.[[InternalStream]] とする。

  3. promise を新しい promise とする。

  4. code を 0 とする。

  5. もし reasonWebTransportError であり、かつ reason.[[StreamErrorCode]] が null でないなら、codereason.[[StreamErrorCode]] に設定する。

  6. もし code < 0 なら、code を 0 に設定する。

  7. もし code > 4294967295 なら、code を 4294967295 に設定する。

    Note: code の有効な値は 0 から 4294967295(両端を含む)。underlying connection が HTTP/3 を使用している場合、コードは [WEB-TRANSPORT-HTTP3] に記載のとおり [0x52e4a40fa8db, 0x52e5ac983162] の範囲の数値にエンコードされる。

  8. Remove を行い、streamtransport.[[SendStreams]] から取り除く。

  9. 次の手順を 並行して実行する:

    1. Abort receivinginternalStream に対して code を用いて行う。

    2. Queue a network tasktransport で実行し、次の手順を行う:

      Note: 上で述べたバッファが、この手続きが実行されている event loop 内で利用可能な場合、以下の手順は直ちに実行されることがある。

      1. Remove を行い、streamtransport.[[ReceiveStreams]] から取り除く。

      2. Resolve を行い、promise を undefined で解決する。

  10. promise を返す。

9.4. サーバーから送信中止シグナルを受信した場合

サーバーからsending aborted(送信中止)のシグナルを受け取ったとき、WebTransportReceiveStream stream に関連付けられたWebTransport streamに対し、次の手順を実行する:
  1. transportstream.[[Transport]] とする。

  2. code を、sending aborted シグナルに付随するアプリケーションプロトコルのエラーコードとする。

    Note: code の有効な値は 0 から 4294967295(両端を含む)。underlying connection が HTTP/3 を使用している場合、コードは [WEB-TRANSPORT-HTTP3] に記載のとおり [0x52e4a40fa8db, 0x52e5ac983162] の範囲の数値にエンコードされる。

  3. Queue a network tasktransport で実行し、次の手順を行う:

    1. もし transport.[[State]]"closed" または "failed" なら、これらの手順を中止する。

    2. Remove を行い、transport.[[ReceiveStreams]] から stream を取り除く。

    3. error を、新たに 作成された WebTransportError とし、 その source"stream"、かつ streamErrorCodecode とする。

    4. Error を行い、streamerror でエラー状態にする。

9.5. WebTransportReceiveStreamStats辞書

WebTransportReceiveStreamStats辞書には、 1つのWebTransportReceiveStream に特有の統計情報が含まれます。

dictionary WebTransportReceiveStreamStats {
  unsigned long long bytesReceived;
  unsigned long long bytesRead;
};

この辞書は以下の属性を持ちます:

bytesReceived, unsigned long long

サーバアプリケーションがこの WebTransportReceiveStream に対して送信しようとしたバイトのうち、これまでに受信された進捗を示す指標。 連続している最初の欠損バイト直前までのバイトのみがカウントされる。この値は増加のみ行われる。

Note: これは単一ストリームで受信したアプリデータの進捗のみを示し、ネットワークのオーバーヘッドは含まない。

bytesRead, unsigned long long

アプリケーションがこの WebTransportReceiveStream から正常に読み出したバイトの合計。この値は増加のみ行われ、常に bytesReceived 以下となる。

10. インターフェイス WebTransportBidirectionalStream

[Exposed=(Window,Worker), SecureContext]
interface WebTransportBidirectionalStream {
  readonly attribute WebTransportReceiveStream readable;
  readonly attribute WebTransportSendStream writable;
};

10.1. 内部スロット

WebTransportBidirectionalStream は以下の内部スロットを持ちます。

内部スロット 説明 (非規範的)
[[Readable]] WebTransportReceiveStream
[[Writable]] WebTransportSendStream
[[Transport]] WebTransport オブジェクトがこの WebTransportBidirectionalStreamを所有する。

10.2. 属性

readable, WebTransportReceiveStream, 読み取り専用

ゲッター手順:this[[Readable]] を返す。

writable, WebTransportSendStream, 読み取り専用

ゲッター手順:this[[Writable]] を返す。

10.3. 手続き

create を、WebTransportBidirectionalStream に対して、 bidirectionalWebTransport stream internalStreamWebTransport オブジェクト transport、および sendOrder を用いて実行するには、次の手順を行う。
  1. readable を、creating により得られる、WebTransportReceiveStream とし、 internalStream および transport を用いる。

  2. writable を、creating により得られる、WebTransportSendStream とし、 internalStreamtransport、および sendOrder を用いる。

  3. stream を、newWebTransportBidirectionalStream とし、次の構成を持つものとする:

    [[Readable]]

    readable

    [[Writable]]

    writable

    [[Transport]]

    transport

  4. stream を返す。

11. WebTransportWriter インターフェイス

WebTransportWriterWritableStreamDefaultWriter のサブクラスであり、 2つのメソッドを追加します。

WebTransportWriter は必ずcreate 手続きによって作成されます。

[Exposed=*, SecureContext]
interface WebTransportWriter : WritableStreamDefaultWriter {
  Promise<undefined> atomicWrite(optional any chunk);
  undefined commit();
};

11.1. メソッド

atomicWrite(chunk)

atomicWrite メソッドは、与えられたchunkが送信時点でのフロー制御 ウィンドウ内で全て送信できない場合はrejectされます。 この動作は、フロー制御デッドロックに敏感な ニッチなトランザクション型アプリケーションに対応するためのものです([RFC9308] Section 4.4)。

注: atomicWrite は、一部データ送信後にrejectされる場合もあります。 フロー制御に対して原子的ですが、他のエラーが発生することがあります。 atomicWrite はデータをパケット間で分割したり、他のデータとインターリーブされるのを防ぐものではありません。 フロー制御クレジット不足による失敗は送信側のみが把握できます。

注: 原子的書き込みも非原子的書き込みの後ろに並ぶとブロックされる場合があります。 atomicWriteがrejectされた場合、その時点で後ろに並んでいた全てのリクエストもrejectされます。 このときrejectされた非原子的書き込みはストリームをエラー状態にします。 したがって、アプリケーションはatomicWriteのawaitを推奨します。

atomicWrite が呼ばれた際、ユーザーエージェントは以下の手順を実行します:

  1. pwrite(chunk)WritableStreamDefaultWriter に対してchunkを渡す)で得る。

  2. pstream[[AtomicWriteRequests]]追加

  3. promiseがsettledになった際に反応する以下のステップの結果を返す:

    1. もしstream[[AtomicWriteRequests]] にpが含まれていればpを削除する。

    2. もしpが理由rでrejectされた場合、rでrejectされたpromiseを返す。

    3. undefinedを返す。

commit()

commit メソッドは、ストリームの[[CommittedOffset]] を、そのストリームに書き込まれたバイト数([[BytesWritten]]) と一致するように更新します。 これにより、書き込みが中止されてストリームが送信中止された後でも、 それらのバイトがピアに確実に配信されることが保証されます。 この動作は[RELIABLE-RESET]で説明されている仕組みを利用します。

注: これは接続が失敗した場合の配信を保証するものではなく、 ストリームが送信中止された場合のみ保証されます。

commitstreamに対して呼ばれた際、ユーザーエージェントは以下の手順を実行します:

  1. transportstream[[Transport]]とする。

  2. stream[[CommittedOffset]]stream[[BytesWritten]] の値に設定する。

11.2. 手続き

createWebTransportWriter に対して、WebTransportSendStream stream を用いて実行するため、次の手順を行う:

  1. writer を、newWebTransportWriter とする。

  2. new WritableStreamDefaultWriter(stream) のコンストラクター手順を、this に writer、コンストラクター引数に stream を渡して実行する。

  3. writer を返す。

12. WebTransportError インターフェイス

WebTransportErrorDOMException のサブクラスであり、

[Exposed=(Window,Worker), Serializable, SecureContext]
interface WebTransportError : DOMException {
  constructor(optional DOMString message = "", optional WebTransportErrorOptions options = {});

  readonly attribute WebTransportErrorSource source;
  readonly attribute unsigned long? streamErrorCode;
};

dictionary WebTransportErrorOptions {
  WebTransportErrorSource source = "stream";
  [Clamp] unsigned long? streamErrorCode = null;
};

enum WebTransportErrorSource {
  "stream",
  "session",
};

12.1. 内部スロット

WebTransportError は以下の内部スロットを持ちます。

内部スロット 説明 (非規範的)
[[Source]] WebTransportErrorSource このエラーのソースを示します。
[[StreamErrorCode]] このエラーのアプリケーションプロトコルエラーコード、またはnull。

12.2. コンストラクタ

new WebTransportError(message, options) のコンストラクター手順は次のとおりである:

  1. thisname"WebTransportError" に設定する。

  2. thismessagemessage に設定する。

  3. this の内部スロットを次のように設定する:

    [[Source]]

    options.source

    [[StreamErrorCode]]

    options.streamErrorCode

    Note: この name はレガシーコードへの対応付けを持たないため、thiscode は 0 である。

12.3. 属性

source型:WebTransportErrorSource、読み取り専用

getterの手順は、this[[Source]]を返すこと。

streamErrorCode型:unsigned long、読み取り専用、nullable

getterの手順は、this[[StreamErrorCode]]を返すこと。

12.4. シリアライズ

WebTransportError オブジェクトはシリアライズ可能オブジェクトです。 そのシリアライズ手順valueserializedを与えて):

  1. DOMExceptionシリアライズ手順valueserializedで実行する。

  2. serialized.[[Source]]value.[[Source]]に設定。

  3. serialized.[[StreamErrorCode]]value.[[StreamErrorCode]]に設定。

そのデシリアライズ手順serializedvalueを与えて):

  1. DOMExceptionデシリアライズ手順serializedvalueで実行する。

  2. value.[[Source]]serialized.[[Source]]に設定。

  3. value.[[StreamErrorCode]] serialized.[[StreamErrorCode]]に設定。

13. プロトコルマッピング

この節は非規範的です。

この節では、[WEB-TRANSPORT-OVERVIEW] を用いて、本仕様で定義されるメソッドの基盤となるプロトコルの挙動を説明します。バッファリングにより、因果関係は即時でない場合があります。

WebTransportプロトコルの動作 APIの効果
セッションがdrained状態 await wt.draining

下層接続がHTTP/3の場合、[WEB-TRANSPORT-HTTP3]から以下のプロトコル挙動が適用されます。

WebTransportError エラーの application streamErrorCode は、httpErrorCode に変換され、またその逆も [WEB-TRANSPORT-HTTP3] Section 4.3 に従って行われます。

APIメソッド QUICプロトコル動作
writable.abort(error) 送信中止をSTREAMに対してhttpErrorCodeと、[[CommittedOffset]] (さらにストリームヘッダ分を加算)を使ってstreamで行う。詳細は[RELIABLE-RESET]
writable.close() 送信STREAM(FINビットがセット)
writable.getWriter().write(chunk)() 送信STREAM
writable.getWriter().close() 送信STREAM(FINビットがセット)
writable.getWriter().abort(error) 送信中止をSTREAMに対してhttpErrorCodeと、[[CommittedOffset]] (さらにストリームヘッダ分を加算)を使ってstreamで行う。詳細は[RELIABLE-RESET]
readable.cancel(error) 受信中止をSTREAMに対してhttpErrorCodeで行う
readable.getReader().cancel(error) 受信中止をSTREAMに対してhttpErrorCodeで行う
wt.close(closeInfo) セッションをcloseInfoで終了
QUICプロトコル動作 APIの効果
received STOP_SENDING with httpErrorCode writableをエラー状態にする writablestreamErrorCode付き)
STREAM受信 (await readable.getReader().read()).value
STREAM受信(FINビットセット) (await readable.getReader().read()).done
received RESET_STREAM with httpErrorCode readableをエラー状態にする readablestreamErrorCode付き)
セッションが正常に終了し、closeInfo
(await wt.closed).closeInfo, および エラー状態となるオープンストリーム
ネットワークエラー
(await wt.closed) がrejectし、 エラー状態となるオープンストリーム

注: [QUIC]の3.2節で述べられているように、 RESET_STREAMフレームやRESET_STREAM_ATフレーム([RELIABLE-RESET]) の受信は、必ずしもアプリケーションに通知されるわけではありません。 リセットの受信は即座にシグナルされ、 ストリームデータの配信が中断され、消費されていないデータは破棄されます。 ただし、即時のシグナルは必須ではありません。 特に、RESET_STREAM_ATフレームのReliable Sizeフィールドで指定されたデータの配信を許すため、 シグナルが遅延される場合があります。 ストリームデータが完全に受信されていて、 まだアプリケーションによって読み取られていない場合には、 送信中止シグナルが抑制されることがあります。 WebTransportは常にRESET_STREAM_ATフレームを使用し、 ストリームヘッダの確実な配信を保証します。 詳細は4.1節 および4.2節 [WEB-TRANSPORT-HTTP3]参照。

HTTP/3プロトコル動作 APIの効果
セッションがdrained await wt.draining

基盤接続がHTTP/2を使用している場合は、 [WEB-TRANSPORT-HTTP2]に記載されているプロトコル動作が適用されます。 HTTP/3の場合とは異なり、ストリームエラーコードをHTTPエラーコードに変換する必要はありませんし、逆も同様です。

APIメソッド HTTP/2プロトコル動作
writable.abort(error) 送信中止をWT_STREAMにerrorで行う
writable.close() 送信 WT_STREAM(FINビットセット)
writable.getWriter().write() 送信 WT_STREAM
writable.getWriter().close() 送信 WT_STREAM(FINビットセット)
writable.getWriter().abort(error) 送信中止をWT_STREAMにerrorで行う
readable.cancel(error) 受信中止をWT_STREAMにerrorで行う
readable.getReader().cancel(error) 受信中止をWT_STREAMにerrorで行う
wt.close(closeInfo) セッションをcloseInfoで終了
HTTP/2プロトコル動作 APIの効果
received WT_STOP_SENDING with error writableをエラー状態にする writablestreamErrorCode付き)
WT_STREAM受信 (await readable.getReader().read()).value
WT_STREAM受信(FINビットセット) (await readable.getReader().read()).done
received WT_RESET_STREAM with error readableをエラー状態にする readablestreamErrorCode付き)
セッションが正常に終了し、closeInfo
(await wt.closed).closeInfo, および エラー状態となるオープンストリーム
ネットワークエラー
(await wt.closed) がrejectし、 エラー状態となるオープンストリーム
セッションがdrained await wt.draining

14. プライバシーおよびセキュリティに関する考慮事項

この節は非規範的であり、新しい挙動は規定せず、他の仕様部分に既に存在する情報をまとめたものです。

14.1. 通信の機密性

ネットワークを監視できる攻撃者に対して、通信が行われている事実を隠すことはできないため、これは公開情報として扱う必要があります。

本書で説明する全てのトランスポートプロトコルはTLS [RFC8446] またはそれと同等の意味を持つプロトコルを利用し、TLSの全てのセキュリティ特性(通信の機密性と完全性含む)を提供します。WebTransport over HTTPは、外向きHTTPリクエストと同じ証明書検証メカニズムを使用するため、リモートサーバーの認証に同じ公開鍵基盤に依存します。WebTransportでは、証明書検証エラーは致命的であり、証明書検証を回避するインタースティシャル(警告画面)はありません。

14.2. 状態の永続性

WebTransport自体は新しい一意な識別子や新たな永続的状態保存方法を作成せず、既存の永続的状態をサーバーに自動的に公開することもありません。例えば、[WEB-TRANSPORT-HTTP3][WEB-TRANSPORT-HTTP2] では、Cookieの送信やHTTP認証、キャッシュ無効化機構はサポートされません。ただしTLSを利用するため、TLSセッションチケットなどTLSの永続的状態を継承します。これは受動的ネットワーク監視者からは見えませんが、サーバー側が同じクライアントからの複数接続を関連付けるために利用できる場合があります。

14.3. プロトコルセキュリティ

WebTransportは[WEB-TRANSPORT-OVERVIEW]で記述された一連の要件を課します。主なものは以下の通りです:

  1. リモートサーバーが WebTransport プロトコルの使用を認識していることを保証し、リモートサーバーが WebTransport プロトコルの使用に同意していることを確認する。[WEB-TRANSPORT-HTTP3] では、ALPN と [RFC7301]、 HTTP/3 の設定、そして WebTransport プロトコルを識別するための :protocol 擬似ヘッダーの組み合わせを用いる。[WEB-TRANSPORT-HTTP2] では、ALPN、HTTP/2 の設定、 そして WebTransport プロトコルを識別するための :protocol 擬似ヘッダーの組み合わせを用いる。

  2. トランスポートセッションを開始するリソースのオリジンに基づいて、サーバーが接続をフィルタリングできるようにする。セッション確立要求の Origin ヘッダー フィールドがこの情報を伝達する。

プロトコルのセキュリティ関連事項については、 セキュリティに関する考慮事項の章で説明されています。 [WEB-TRANSPORT-OVERVIEW]セクション6[WEB-TRANSPORT-HTTP3]セクション8、 そして[WEB-TRANSPORT-HTTP2]セクション9を参照してください。

ネットワークAPIはローカルネットワークの利用可能なホストをスキャンする用途にも使われることが多く、フィンガープリントやその他攻撃手法に利用される可能性があります。WebTransportはWebSocketのアプローチに従います:特定の接続エラーは、エンドポイントがWebTransportエンドポイントであることが検証されるまで返されません。つまりWebアプリケーションは、存在しないエンドポイントとWebからの接続受け入れ意思のないエンドポイントとを区別できません。

14.4. 証明書ハッシュによる認証

通常、ユーザーエージェントは、URLのサーバー名に対して提供されたTLSサーバー証明書の有効性を検証することで、TLS接続の認証を行います [RFC9525]。これは、ユーザーエージェントが管理する信頼できるアンカーに証明書チェーンをつなげることで達成されます。信頼アンカーは証明書内のサーバー名認証を担当します。この仕組みをWeb PKIと呼びます。

このAPIは、Webアプリケーションが、サーバー名ではなく特定のサーバー証明書で認証されたリモートネットワークエンドポイントに接続する機能を提供します。この仕組みは、長期証明書の取得が困難なエンドポイント(例:短命な仮想マシンや公開ルート不可なホスト)への接続を可能にします。この仕組みはWeb PKIベース認証の代替となるため、両者のセキュリティ特性を比較する必要があります。

リモートサーバーは、指定された証明書の公開鍵に対応する秘密鍵を保持している場合のみ、TLSハンドシェイクに成功できます。APIは証明書のハッシュで証明書を識別します。これは使用する暗号学的ハッシュ関数がセカンドプリイメージ耐性を持つ場合のみ安全です。本書で定義される唯一の関数はSHA-256であり、APIは複数のアルゴリズム-ハッシュペア指定により新たなハッシュ関数の導入手段を提供します。

Web PKIはサーバー名の信頼チェーン構築以外にも、証明書失効処理など追加のセキュリティ機構を提供します。証明書がエフェメラルな場合はこの機構は不要ですが、その他の場合は証明書ハッシュの導入方法(例:キャッシュされたHTTPリソースの場合、証明書が侵害により交換された際はキャッシュを無効化する必要がある)を検討する必要があります。Web PKIは、既知の弱い鍵を持つ証明書の拒否など、鍵生成に関する問題への対策も提供します。本仕様では特定の指針はありませんが、ブラウザは実装依存でこれらを拒否しても構いません。

Web PKIは証明書の有効期間制限を課します。これは鍵侵害の範囲を限定し、運用者が鍵ローテーションを設計・実行する仕組みとなります。WebTransportも同様の有効期間制限(最大2週間)を課します。2週間という制限は、鍵侵害の影響最小化と、デバイス間の時計ズレやクライアントとサーバー間での証明書同期コスト低減のバランスを考慮したものです。

WebTransport APIは、アプリケーションが複数の証明書ハッシュを同時に指定できるようにし、新しい証明書がロールアウトされる期間中クライアントが複数の証明書を受け入れられるようにします。

WebRTCの類似の仕組みと異なり、WebTransportのサーバー証明書ハッシュAPIはクライアント認証手段を提供しません。クライアントがサーバー証明書や接続方法を知っているだけでは十分ではなく、必要に応じてアプリケーションがバンド内でクライアントのアイデンティティを確立する必要があります。

14.5. フィンガープリントとトラッキング

このAPIはサイトにネットワーク活動を生成し、その効果を詳細に観察する能力を提供します。このように得られた情報は識別可能である可能性があります。

同様のネットワーク機能は他のWebプラットフォームAPI(例:fetch[webrtc])でも提供されているため、WebTransport追加によるプライバシーへの悪影響は最小限です。本節の考慮事項は他のネットワーク機能にも等しく適用されます。

ネットワーク特性の計測にはネットワーク利用とその利用効果の計測が必要であり、どちらもこのAPIによって可能となります。WebTransportはサイトに、任意のサーバーへのネットワーク活動生成および効果の観察能力を提供します。ネットワーク経路の安定した特性や動的な利用効果の両方の観察が可能です。

ネットワーク情報は、サーバー自身のネットワークスタック、クライアントによるデータ消費・送信速度、またはAPIが提供する統計情報(§ 6.13 WebTransportConnectionStats Dictionary参照)としてサーバーに直接・間接的に提供されます。そのため、ユーザーエージェントで情報制限するだけではプライバシーリスク管理には不十分な場合があります。

14.5.1. 静的観測

サイトはユーザーエージェントと選択したサーバー間の利用可能なネットワーク容量やRTT(往復遅延時間)を観測できます。これらの情報は他のトラッキング要素と組み合わせると識別性を持つ場合があります。RTTは複数地点から複数回測定することでユーザーエージェントの物理的な位置情報の一部を明らかにできる場合もあります。

ネットワークは共有されているものの、利用は断続的なことが多いため、サイトは競合や負荷の少ない経路の容量やRTTを観測できる場合があります。これらの特性は多くの人にとって安定しており、ネットワークの位置が変わらず、ボトルネック(容量決定要素)がユーザーエージェントに近い場合は特に安定します。

14.5.2. 共有ネットワーク

競合するリンクでは、サイトにクロスサイト認識 の機会が生まれ、これが非公認のトラッキング([UNSANCTIONED-TRACKING])に利用される恐れがあります。 ネットワーク容量は有限で共有資源のため、ユーザーエージェントが複数サイトに同時アクセスする場合、各サイトに提示されるアイデンティティの関連付けが明らかになる場合があります。

一つのサイトでネットワーク機能を使うと、他サイトで利用できる容量が減少し、ネットワークAPIを使って観測できます。ネットワーク利用やメトリクスは動的に変化し、変化はリアルタイムで観測可能です。これにより、異なるサイト上の活動が同一ユーザーによるものであるという確信度を高めることができます。

ユーザーエージェントは、アクティブでない・フォーカスされていないサイトに対して、フィードバック機構(統計情報、§ 6.13 WebTransportConnectionStats Dictionary)へのアクセスを制限・劣化させることができます。ただし、これだけではサーバーがネットワークの変化を観測することを防ぎきれません。

14.5.3. セッションのプール

共有ネットワークのシナリオと同様、セッションが単一の接続上でプールされる場合、あるセッションの情報は他のセッションの活動によって影響を受けます。別のセッションがどの程度データを送信しているかなどの情報が推論される可能性があります。

共有接続の利用は、サーバー側がセッションを関連付けることを可能にします。network partition keyを使用すると、プール利用が無効化され、共有セッションが不要なクロスサイト認識を可能にする状況を防ぐことができます。

15.

15.1. データグラムバッファの送信

この節は非規範的です。

データグラムのバッファ送信は、datagramscreateWritable メソッドおよびその結果のストリームのwriterを利用して実現できます。下記例では、トランスポートが送信可能な場合のみデータグラムを送信します。

async function sendDatagrams(url, datagrams) {
  const wt = new WebTransport(url);
  const writable = wt.datagrams.createWritable();
  const writer = writable.getWriter();
  for (const bytes of datagrams) {
    await writer.ready;
    writer.write(bytes).catch(() => {});
  }
  await writer.close();
}

15.2. 一定レートでデータグラム送信

この節は非規範的です。

トランスポートが送信可能かどうかに関わらず一定レートでデータグラムを送信したい場合は、datagramscreateWritable メソッドと、その結果のストリームのwriterをready属性を待たずに使えばよいです。

// 100msごとにデータグラム送信
async function sendFixedRate(url, createDatagram, ms = 100) {
  const wt = new WebTransport(url);
  const writable = wt.datagrams.createWritable();
  const writer = writable.getWriter();
  const bytes = createDatagram();
  setInterval(() => writer.write(bytes).catch(() => {}), ms);
}

15.3. データグラム受信

この節は非規範的です。

データグラムはtransport.datagrams.readable 属性から読み出すことで受信できます。null値はパケット処理が遅すぎることを示す場合があります。

async function receiveDatagrams(url) {
  const wt = new WebTransport(url);
  for await (const datagram of wt.datagrams.readable) {
    // datagramを処理
  }
}

15.4. BYOBリーダーによるデータグラム受信

この節は非規範的です。

datagrams可読バイトストリームであるため、バッファ割当てをより正確に制御しコピーを避けるための BYOBリーダー を取得できる。この例では64キビバイトのメモリバッファにデータグラムを読み出している。

const wt = new WebTransport(url);

for await (const datagram of wt.datagrams.readable) {
  const reader = datagram.getReader({ mode: "byob" });

  let array_buffer = new ArrayBuffer(65536);
  const buffer = await readInto(array_buffer);
}

async function readInto(buffer) {
  let offset = 0;

  while (offset < buffer.byteLength) {
    const {value: view, done} = await reader.read(
        new Uint8Array(buffer, offset, buffer.byteLength - offset));
    buffer = view.buffer;
    if (done) {
      break;
    }
    offset += view.byteLength;
  }

  return buffer;
}

15.5. ストリーム送信

この節は非規範的です。

一方向ストリームでデータを送信するには、createUnidirectionalStream 関数およびその結果のストリームのwriterを利用します。

書き込みchunkの境界は受信側で保証されません。バイトがワイヤ上で合流する可能性があるため、アプリケーションは独自フレーミングを推奨します。

async function sendData(url, ...data) {
  const wt = new WebTransport(url);
  const writable = await wt.createUnidirectionalStream();
  const writer = writable.getWriter();
  for (const bytes of data) {
    await writer.ready;
    writer.write(bytes).catch(() => {});
  }
  await writer.close();
}

Streams仕様では write()のawait を推奨しません。

エンコーディングは、ReadableStreamからpipeすることで実現できます。 例えばTextEncoderStream を用います。

async function sendText(url, readableStreamOfTextData) {
  const wt = new WebTransport(url);
  const writable = await wt.createUnidirectionalStream();
  await readableStreamOfTextData
    .pipeThrough(new TextEncoderStream("utf-8"))
    .pipeTo(writable);
}

15.6. 着信ストリームの受信

この節は非規範的です。

着信ストリームの読み出しは、incomingUnidirectionalStreams 属性を反復し、各WebTransportReceiveStream のチャンクを反復処理することで実現できます。

チャンク化はユーザーエージェントによって決定され、送信者ではありません。

async function receiveData(url, processTheData) {
  const wt = new WebTransport(url);
  for await (const readable of wt.incomingUnidirectionalStreams) {
    // 各ストリームを個別に消費し、ストリームごとのエラーを報告
    ((async () => {
      try {
        for await (const bytes of readable) {
          processTheData(bytes);
        }
      } catch (e) {
        console.error(e);
      }
    })());
  }
}

デコードは新しいWritableStreamにpipeすることで実現できます。例えば TextDecoderStream を使います。 この例ではテキスト出力が混在しないよう、1ストリームずつ読み取ります。

async function receiveText(url, createWritableStreamForTextData) {
  const wt = new WebTransport(url);
  for await (const readable of wt.incomingUnidirectionalStreams) {
    // 順次消費して出力を混在させず、ストリームごとのエラーを報告
    try {
      await readable
       .pipeThrough(new TextDecoderStream("utf-8"))
       .pipeTo(createWritableStreamForTextData());
    } catch (e) {
      console.error(e);
    }
  }
}

15.7. BYOBリーダーでストリーム受信

この節は非規範的です。

WebTransportReceiveStream読み取りバイトストリームなので、コピーを避けるために より精密なバッファ割り当て制御ができるBYOBリーダーを取得できます。 この例では、WebTransportReceiveStream から最初の1024バイトを単一のメモリバッファに読み取ります。

const wt = new WebTransport(url);

const reader = wt.incomingUnidirectionalStreams.getReader();
const { value: recv_stream, done } = await reader.read();
const byob_reader = recv_stream.getReader({ mode: "byob" });

let array_buffer = new ArrayBuffer(1024);
const buffer = await readInto(array_buffer);

async function readInto(buffer) {
  let offset = 0;

  while (offset < buffer.byteLength) {
    const {value: view, done} = await reader.read(
        new Uint8Array(buffer, offset, buffer.byteLength - offset));
    buffer = view.buffer;
    if (done) {
      break;
    }
    offset += view.byteLength;
  }

  return buffer;
}

15.8. ストリームでトランザクションチャンク送信

この節は非規範的です。

一方向ストリームで、フロー制御でブロックせずに全体送信できる場合のみトランザクションデータを送信したい場合は、 getWriter 関数およびそのwriterを利用します。

async function sendTransactionalData(wt, bytes) {
  const writable = await wt.createUnidirectionalStream();
  const writer = writable.getWriter();
  await writer.ready;
  try {
    await writer.atomicWrite(bytes);
  } catch (e) {
    if (e.name != "AbortError") throw e;
    // フロー制御でブロックを避けるためreject
    // 非atomicな書き込みがpendingでなければwritableはエラー化されない
  } finally {
    writer.releaseLock();
  }
}

15.9. サーバー証明書ハッシュ利用

この節は非規範的です。

WebTransportセッションは、クライアント側で行われるデフォルトの信頼評価を、サーバーに提供された証明書のハッシュによるチェックで上書きできます。下記例ではhashValue下層接続が有効とみなすべきサーバー証明書のSHA-256ハッシュを含むBufferSourceです。

const wt = new WebTransport(url, {
  serverCertificateHashes: [
    {
      algorithm: "sha-256",
      value: hashValue,
    }
  ]
});
await wt.ready;

15.10. 完全な例

この節は非規範的です。

この例はclosed/ready promiseの利用、クライアント・サーバー双方での一方向・双方向ストリームの開始、データグラムの送受信方法を示します。

writable属性(transportのdatagramsにあったもの)は 以下のようにPolyfillできます:
wt.datagrams.writable ||= wt.datagrams.createWritable();
// ページ上のイベントログにエントリを追加し、指定CSSクラスを適用可能
// CSSクラスを任意指定

let wt, streamNumber, datagramWriter;

connect.onclick = async () => {
  try {
    const url = document.getElementById('url').value;

    wt = new WebTransport(url);
    wt.datagrams.writable ||= wt.datagrams.createWritable();
    addToEventLog('接続を開始しています...');
    await wt.ready;
    addToEventLog(`${(wt.reliability == "reliable-only")? "TCP" : "UDP"} ` +
                  `接続完了.`);
    wt.closed
      .then(() => addToEventLog('接続が正常に閉じられました。'))
      .catch(() => addToEventLog('接続が異常終了しました。', 'error'));

    streamNumber = 1;
    datagramWriter = wt.datagrams.writable.getWriter();

    readDatagrams();
    acceptUnidirectionalStreams();
    document.forms.sending.elements.send.disabled = false;
    document.getElementById('connect').disabled = true;
  } catch (e) {
    addToEventLog(`接続失敗: ${e}`, 'error');
  }
}

sendData.onclick = async () => {
  const form = document.forms.sending.elements;
  const data = sending.data.value;
  const bytes = new TextEncoder('utf-8').encode(data);
  try {
    switch (form.sendtype.value) {
      case 'datagram': {
        await datagramWriter.ready;
        datagramWriter.write(bytes).catch(() => {});
        addToEventLog(`データグラム送信: ${data}`);
        break;
      }
      case 'unidi': {
        const writable = await wt.createUnidirectionalStream();
        const writer = writable.getWriter();
        writer.write(bytes).catch(() => {});
        await writer.close();
        addToEventLog(`一方向ストリームでデータ送信: ${data}`);
        break;
      }
      case 'bidi': {
        const duplexStream = await wt.createBidirectionalStream();
        const n = streamNumber++;
        readFromIncomingStream(duplexStream.readable, n);

        const writer = duplexStream.writable.getWriter();
        writer.write(bytes).catch(() => {});
        await writer.close();
        addToEventLog(`双方向ストリーム #${n} でデータ送信: ${data}`);
        break;
      }
    }
  } catch (e) {
    addToEventLog(`送信中のエラー: ${e}`, 'error');
  }
}

// EOF到達までデータグラムをイベントログに読み出し
async function readDatagrams() {
  try {
    const decoder = new TextDecoderStream('utf-8');

    for await (const data of wt.datagrams.readable.pipeThrough(decoder)) {
      addToEventLog(`データグラム受信: ${data}`);
    }
    addToEventLog('データグラム読み取り終了!');
  } catch (e) {
    addToEventLog(`データグラム読取中のエラー: ${e}`, 'error');
  }
}

async function acceptUnidirectionalStreams() {
  try {
    for await (const readable of wt.incomingUnidirectionalStreams) {
      const number = streamNumber++;
      addToEventLog(`新しい着信一方向ストリーム #${number}`);
      readFromIncomingStream(readable, number);
    }
    addToEventLog('着信一方向ストリーム受付終了!');
  } catch (e) {
    addToEventLog(`ストリーム受付中エラー ${e}`, 'error');
  }
}

async function readFromIncomingStream(readable, number) {
  try {
    const decoder = new TextDecoderStream('utf-8');
    for await (const data of readable.pipeThrough(decoder)) {
      addToEventLog(`ストリーム #${number} でデータ受信: ${data}`);
    }
    addToEventLog(`ストリーム #${number} 閉じました`);
  } catch (e) {
    addToEventLog(`ストリーム #${number} 読取中のエラー: ${e}`, 'error');
    addToEventLog(`    ${e.message}`);
  }
}

function addToEventLog(text, severity = 'info') {
  const log = document.getElementById('event-log');
  const previous = log.lastElementChild;
  const entry = document.createElement('li');
  entry.innerText = text;
  entry.className = `log-${severity}`;
  log.appendChild(entry);

  // ログの直前のエントリが可視なら、新しい要素までスクロール
  if (previous &&
      previous.getBoundingClientRect().top < log.getBoundingClientRect().bottom) {
    entry.scrollIntoView();
  }
}

16. 謝辞

編集者は、ワーキンググループ議長およびチームコンタクトである Jan-Ivar Bruaroey、Will Law、Yves Lafon のご支援に感謝します。

WebTransport インターフェイスは、W3C ORTC CGで最初に記述された QuicTransport インターフェイスに基づいており、本仕様に合わせて適合・拡張されています。

索引

本仕様で定義される用語

参照によって定義される用語

参考文献

規範的参考文献

[CSP3]
Mike West; Antonio Sartori. コンテンツセキュリティポリシー レベル3。2025年11月6日。WD。URL: https://www.w3.org/TR/CSP3/
[DOM]
Anne van Kesteren。DOM 標準。リビングスタンダード。 URL: https://dom.spec.whatwg.org/
[ECMASCRIPT-6.0]
Allen Wirfs-Brock。ECMA-262 第6版、ECMAScript 2015 言語仕様。2015年6月。標準。URL: http://www.ecma-international.org/ecma-262/6.0/index.html
[ENCODING]
Anne van Kesteren。エンコーディング標準。リビングスタンダード。URL: https://encoding.spec.whatwg.org/
[FETCH]
Anne van Kesteren。Fetch 標準。リビングスタンダード。URL: https://fetch.spec.whatwg.org/
[HR-TIME-3]
Yoav Weiss。高精度タイム。2024年11月7日。WD。URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; ほか。HTML 標準。リビングスタンダード。URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola。Infra 標準。リビングスタンダード。URL: https://infra.spec.whatwg.org/
[QUIC]
Jana Iyengar; Martin Thomson。QUIC: UDP ベースの多重化かつセキュアなトランスポート。提案標準。URL: https://www.rfc-editor.org/rfc/rfc9000
[QUIC-DATAGRAM]
Tommy Pauly; Eric Kinnear; David Schinazi。QUIC への信頼性のないデータグラム拡張。提案標準。URL: https://www.rfc-editor.org/rfc/rfc9221
[RFC2119]
S. Bradner。要求レベルを示すために RFC で使用するキーワード。1997年3月。ベスト・カレント・プラクティス。URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC3279]
L. Bassham; W. Polk; R. Housley。インターネット X.509 公開鍵基盤 証明書および失効リスト (CRL) プロファイルのアルゴリズムと識別子。2002年4月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc3279
[RFC5280]
D. Cooper; ほか。インターネット X.509 公開鍵基盤 証明書および失効リスト (CRL) プロファイル。2008年5月。 提案標準。URL: https://www.rfc-editor.org/rfc/rfc5280
[RFC8174]
B. Leiba。RFC 2119 キーワードにおける大文字と小文字のあいまいさ。2017年5月。ベスト・カレント・プラクティス。URL: https://www.rfc-editor.org/rfc/rfc8174
[RFC8422]
Y. Nir; S. Josefsson; M. Pegourie-Gonnard。TLS 1.2 およびそれ以前のバージョン向けの楕円曲線暗号 (ECC) 暗号スイート。2018年8月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc8422
[RFC8441]
P. McManus。HTTP/2 による WebSocket のブートストラップ。2018年9月。提案標準。URL: https://httpwg.org/specs/rfc8441.html
[RFC9002]
J. Iyengar, 編集者; I. Swett, 編集者。QUIC の損失検出と輻輳制御。2021年5月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc9002
[RFC9220]
R. Hamilton。HTTP/3 による WebSocket のブートストラップ。2022年6月。提案標準。URL: https://httpwg.org/specs/rfc9220.html
[RFC9525]
P. Saint-Andre; R. Salz。TLS におけるサービス識別。2023年11月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc9525
[STREAMS]
Adam Rice; ほか。Streams 標準。リビングスタンダード。 URL: https://streams.spec.whatwg.org/
[URL]
Anne van Kesteren。URL 標準。リビングスタンダード。 URL: https://url.spec.whatwg.org/
[WEB-TRANSPORT-HTTP2]
Alan Frindell; ほか。HTTP/2 上の WebTransport。Internet-Draft。URL: https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http2
[WEB-TRANSPORT-HTTP3]
Alan Frindell; Eric Kinnear; Victor Vasiliev。HTTP/3 上の WebTransport。Internet-Draft。URL: https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3
[WEB-TRANSPORT-OVERVIEW]
Victor Vasiliev。WebTransport プロトコル・フレームワーク。Internet-Draft。URL: https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-overview
[WEBIDL]
Edgar Chen; Timothy Gu。Web IDL 標準。リビングスタンダード。 URL: https://webidl.spec.whatwg.org/

参考情報

[RELIABLE-RESET]
Marten Seemann; 奥一穂. QUIC Stream Resets with Partial Delivery. インターネットドラフト. URL: https://datatracker.ietf.org/doc/html/draft-ietf-quic-reliable-stream-reset
[RFC7301]
S. Friedl; 他. Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension. 2014年7月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc7301
[RFC8446]
E. Rescorla. The Transport Layer Security (TLS) Protocol Version 1.3. 2018年8月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc8446
[RFC9308]
M. Kühlewind; B. Trammell. Applicability of the QUIC Transport Protocol. 2022年9月. 情報提供. URL: https://www.rfc-editor.org/rfc/rfc9308
[UNSANCTIONED-TRACKING]
Mark Nottingham. Unsanctioned Web Tracking. 2015年7月17日. TAG Finding. URL: https://www.w3.org/2001/tag/doc/unsanctioned-tracking/
[WEBRTC]
Cullen Jennings; 他. WebRTC: Real-Time Communication in Browsers. 2025年3月13日. REC. URL: https://www.w3.org/TR/webrtc/

IDL索引

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportDatagramsWritable : WritableStream {
  attribute WebTransportSendGroup? sendGroup;
  attribute long long sendOrder;
};

[Exposed=(Window,Worker), SecureContext]
interface WebTransportDatagramDuplexStream {
  WebTransportDatagramsWritable createWritable(
      optional WebTransportSendOptions options = {});
  readonly attribute ReadableStream readable;

  readonly attribute unsigned long maxDatagramSize;
  attribute unrestricted double? incomingMaxAge;
  attribute unrestricted double? outgoingMaxAge;
  attribute unrestricted double incomingHighWaterMark;
  attribute unrestricted double outgoingHighWaterMark;
};

[Exposed=(Window,Worker), SecureContext]
interface WebTransport {
  constructor(USVString url, optional WebTransportOptions options = {});

  Promise<WebTransportConnectionStats> getStats();
  [NewObject] Promise<ArrayBuffer> exportKeyingMaterial(BufferSource label, optional BufferSource context);
  readonly attribute Promise<undefined> ready;
  readonly attribute WebTransportReliabilityMode reliability;
  readonly attribute WebTransportCongestionControl congestionControl;
  [EnforceRange] attribute unsigned short? anticipatedConcurrentIncomingUnidirectionalStreams;
  [EnforceRange] attribute unsigned short? anticipatedConcurrentIncomingBidirectionalStreams;
  readonly attribute DOMString protocol;

  readonly attribute Promise<WebTransportCloseInfo> closed;
  readonly attribute Promise<undefined> draining;
  undefined close(optional WebTransportCloseInfo closeInfo = {});

  readonly attribute WebTransportDatagramDuplexStream datagrams;

  Promise<WebTransportBidirectionalStream> createBidirectionalStream(
      optional WebTransportSendStreamOptions options = {});
  /* a ReadableStream of WebTransportBidirectionalStream objects */
  readonly attribute ReadableStream incomingBidirectionalStreams;

  Promise<WebTransportSendStream> createUnidirectionalStream(
      optional WebTransportSendStreamOptions options = {});
  /* a ReadableStream of WebTransportReceiveStream objects */
  readonly attribute ReadableStream incomingUnidirectionalStreams;
  WebTransportSendGroup createSendGroup();

  static readonly attribute boolean supportsReliableOnly;
};

enum WebTransportReliabilityMode {
  "pending",
  "reliable-only",
  "supports-unreliable",
};

dictionary WebTransportHash {
  required DOMString algorithm;
  required BufferSource value;
};

dictionary WebTransportOptions {
  boolean allowPooling = false;
  boolean requireUnreliable = false;
  sequence<WebTransportHash> serverCertificateHashes = [];
  WebTransportCongestionControl congestionControl = "default";
  [EnforceRange] unsigned short? anticipatedConcurrentIncomingUnidirectionalStreams = null;
  [EnforceRange] unsigned short? anticipatedConcurrentIncomingBidirectionalStreams = null;
  sequence<DOMString> protocols = [];
  ReadableStreamType datagramsReadableType;
};

enum WebTransportCongestionControl {
  "default",
  "throughput",
  "low-latency",
};

dictionary WebTransportCloseInfo {
  unsigned long closeCode = 0;
  USVString reason = "";
};

dictionary WebTransportSendOptions {
  WebTransportSendGroup? sendGroup = null;
  long long sendOrder = 0;
};

dictionary WebTransportSendStreamOptions : WebTransportSendOptions {
  boolean waitUntilAvailable = false;
};

dictionary WebTransportConnectionStats {
  unsigned long long bytesSent;
  unsigned long long bytesSentOverhead;
  unsigned long long bytesAcknowledged;
  unsigned long long packetsSent;
  unsigned long long bytesLost;
  unsigned long long packetsLost;
  unsigned long long bytesReceived;
  unsigned long long packetsReceived;
  DOMHighResTimeStamp smoothedRtt;
  DOMHighResTimeStamp rttVariation;
  DOMHighResTimeStamp minRtt;
  required WebTransportDatagramStats datagrams;
  unsigned long long? estimatedSendRate = null;
  boolean atSendCapacity = false;
};

dictionary WebTransportDatagramStats {
  unsigned long long droppedIncoming;
  unsigned long long expiredIncoming;
  unsigned long long expiredOutgoing;
  unsigned long long lostOutgoing;
};

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportSendStream : WritableStream {
  attribute WebTransportSendGroup? sendGroup;
  attribute long long sendOrder;
  Promise<WebTransportSendStreamStats> getStats();
  WebTransportWriter getWriter();
};

dictionary WebTransportSendStreamStats {
  unsigned long long bytesWritten;
  unsigned long long bytesSent;
  unsigned long long bytesAcknowledged;
};

[Exposed=(Window,Worker), SecureContext]
interface WebTransportSendGroup {
  Promise<WebTransportSendStreamStats> getStats();
};

[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportReceiveStream : ReadableStream {
  Promise<WebTransportReceiveStreamStats> getStats();
};

dictionary WebTransportReceiveStreamStats {
  unsigned long long bytesReceived;
  unsigned long long bytesRead;
};

[Exposed=(Window,Worker), SecureContext]
interface WebTransportBidirectionalStream {
  readonly attribute WebTransportReceiveStream readable;
  readonly attribute WebTransportSendStream writable;
};

[Exposed=*, SecureContext]
interface WebTransportWriter : WritableStreamDefaultWriter {
  Promise<undefined> atomicWrite(optional any chunk);
  undefined commit();
};

[Exposed=(Window,Worker), Serializable, SecureContext]
interface WebTransportError : DOMException {
  constructor(optional DOMString message = "", optional WebTransportErrorOptions options = {});

  readonly attribute WebTransportErrorSource source;
  readonly attribute unsigned long? streamErrorCode;
};

dictionary WebTransportErrorOptions {
  WebTransportErrorSource source = "stream";
  [Clamp] unsigned long? streamErrorCode = null;
};

enum WebTransportErrorSource {
  "stream",
  "session",
};

課題索引

これはWorkerでも対応する必要があります。詳細は #127 および whatwg/html#6731 を参照してください。

この設定オプションは、現時点で低遅延最適化の輻輳制御アルゴリズムをブラウザが実装していないため、リスクのある機能と見なされています。

bytesAcknowledgedWebTransportConnectionStats において、実装可能性に関する懸念からワーキンググループによりリスクあり機能(feature at risk)と識別されている。