WebTransport over HTTP/2 の仕様について

目次

背景と仕様

以前取り上げたように、WebSocketに変わるWebTransportという新しい双方向メッセージングプロトコルの標準化および実装が進められている。
asnokaze.hatenablog.com

JavaScript APIに関してはW3C側で(仕様リンク)で策定されているが、プロトコルIETFで策定が進められている。

使用するトランスポートプロトコルによって仕様が分かれており、以下の3つが存在する。

このうち、QUICやHTTP/3が使用できない場合のフォールバック先として用意される「WebTransport over HTTP/2」の仕様が先日投稿された。

提出された「WebTransport using HTTP/2」の著者はFacebookAlan Frindell氏の他、GoogleのVictor Vasiliev氏、AppleのTommy Pauly氏らが名を連ねている。

彼らは元々 HTTP/2上で任意の双方向メッセージを行うための提案仕様を書いていたので、WebTransport over HTTP/2へと向かうのも頷ける。

WebTransport over HTTP/2 (Http2Transport)

特徴

現在の仕様では、WebTransport over HTTP/2は以下の機能を持つと述べています

  • HTTP/2上でWebTransportセッションが確立したあと、クライアントとサーバのどちらからでもWebTransport用ストリームをオープンできる。
  • WebTransport用ストリームでヘッダー圧縮、優先順位付け、フロー制御 の機能が利用できる
  • 中継者がいてもWebTransport用ストリームのデータを正しい相手に配送できる
  • WebTransport用ストリームをグループ化できる

WebSocket over HTTP/2とは異なり、セッションが確立したあとにサーバ側からWebTransport用ストリームをオープンできる。そのデータをただしくクライアントに配送するための工夫が入っている。

ただ、WebTransportでは優先度処理がどうなるかはまだ変わるところがあると思われる(WICG/Web-Transport)

概要

WebTransport over HTTP/2の仕様では、以下について言及している

  • WebTransport over HTTP/2のネゴシエーション方法 (SETTINGSパラメータ)
  • WebTransport Connect StreamsとWebTransport Streams
  • WTHEADERS拡張フレーム

それぞれ説明していく。最後に通信例を示す。

WebTransport over HTTP/2のネゴシエーション

WebTransport over HTTP/2を使うために、以下の2つのSETTINGSパラメータを投げます。

  • SETTINGS_ENABLE_CONNECT_PROTOCOL
  • SETTINGS_ENABLE_WEBTRANSPORT

それぞれ 1 の場合に、有効であることを示します。クライアントからSETTINGSフレームを送信し、サーバからも同様に有効であることを示すSETTINGSパラメータを受け取った場合のみWebTransport over HTTP/2の機能が使用できます。

WebTransport Connect StreamsとWebTransport Streams

WebTransport over HTTP/2では2種類のストリームを使用します。それぞれストリームですので、ストリームIDを持ちます。

  • WebTransport Connect Streams: クライアントからCONNECTメソッドのHEADERSフレームで開かれるストリーム。グループ化のために使用される
  • WebTransport Streams: WTHEADERSフレームを使用することでクライアント/サーバのどちらからでも開くことができるストリーム。実際にデータをやりとりするのに使用される。WebTransport Connect Streamsに関連付けられる。

実際にデータをやり取りするWebTransport Streamsは、必ずWebTransport Connect Streamsに関連付けられます。WebTransport Connect Streamsがクローズすると、関連するWebTransport Streamsもクローズされます。一つのWebTransport Connect Streamsに複数のWebTransport Streamsを関連付けることもできます。

中継者(Proxy)がいると、サーバ側からオープンしたWebTransport Streamsのデータを、どのクライアントに配送すべきか判断するためこのような仕組みになっています。WebTransport Streamsを、クライアントからオープンしたWebTransport Connect Streamsに必ず関連付けることで、その配送が分かります。

ちょっと仕組みが分かりづらいですが、後述の通信例を見るとわかりやすいかと思います。

WTHEADERSフレーム

WTHEADERSフレームは、先述のWebTransport Streamsをオープンするのに使用する拡張フレームです。クライアントおよびサーバのどちらからでも送信することができます。

HTTP/2のHEADERSフレームと似ていますが、WebTransport Connect Streamsと関連付けるために Connect Stream ID というフィールドを持ちます。その他は、HEADERSフレームと同様です。
f:id:ASnoKaze:20200311012400p:plain

ただし、優先度の依存は同じWebTransport Connect Streamsに関連付けられたストリーム間でしか考慮されません。

CONTINUATIONフレームが続く可能性があるのも同様です。

通信例

ネゴシエーション

f:id:ASnoKaze:20200311013359p:plain

まず、クライアントとサーバはSETTINGSフレームでお互いにWebTransport over HTTP/2が有効なことを確認します。

その後、クライアントからCONNECTメソッドのHEADERSフレームを送信します。このストリームがWebTransport Connect Streamsです。このとき、:protocol疑似ヘッダにwebtransportを指定します。

:status 200が返ってきたらってきたらWebTransport Connect Streamsの準備はOKです。

WebTransport Streams

WebTransport Connect Streamsの準備ができたら、WTHEADERSフレームを用いてデータ通信用のWebTransport Streamsを開きます。下記は、サーバ側からWebTransport Streamsを開く例です。CONNECT_STREAMとして、先に開いたWebTransport Connect StreamsのストリームIDを指定しています。

相手から同様にWTHEADERSフレームで:status 200が返ってきたら、DATAフレームによる双方向通信ができるようになります。

f:id:ASnoKaze:20200311014213p:plain

中間装置(Proxy)の例

中間装置(Proxy)がいる構成における、配送について簡単に補足します。
WebTransport Connect Streamsが赤、WebTransport Streams青です。

f:id:ASnoKaze:20200311014913p:plain

中間装置とサーバは一つのコネクションに集約することができますす。

先述の通り、WebTransport Streamsはサーバからオープンできます。中間装置(Proxy)は、サーバからオープンしたストリームのデータをどのクライアントに配送すべきかマッピングできる必要があります。

WebTransport Streamsは必ずWebTransport Connect Streamsと関連付けられているため、そのWebTransport Connect Streamsをオープンしたクライアントにデータを配送することができます。

その他

CORSのように、Originヘッダを使って正規のオリジンからの通信のみを許可するようですが、仕様中の例には含まれてない?