HTTPにはCONNECTメソッドというものがあります、このメソッドを使ってProxyと接続しHTTPメッセージを中継してもらいます。
拡張CONNECTメソッドは、HTTPメッセージ以外のデータを中継してもらうのに使用します。特にHTTP/2やHTTP/3では特定のストリームを、データのトンネル用にするために、拡張CONNECTメソッドを使います。
例えば、WebTransport over HTTP/3なども拡張CONNECTメソッドを利用します。そのため、拡張CONNECTメソッドをサポートしてない単純なHTTP/3 ProxyとはWebTransport通信は行ったりは出来ません(Datagramらへんも絡む)。
今回は、その拡張CONNECTメソッド (Extended CONNECT Method) について見ていきます。
利用例
拡張CONNECTメソッドはもともと、WebSocket over HTTP/2の仕様で導入されました。
(HTTP/2でHTTPメッセージはストリームで管理するので、コネクションを切り替えるUpgradeは使えません。そこで拡張CONNECTを使うことになってます。標準化当時の議論 URL)
その後、その他のプロトコルでも利用されるようになりました。例えば次のようなプロトコルです。
- WebSocket over HTTP/2 (RFC8441)
- WebSocket over HTTP/3
- WebTransport over HTTP/3
- UDP Proxying Support for HTTP (UDPパケットをHTTPコネクションを介してProxyする)
- IP Proxying Support for HTTP (IPパケットをHTTPコネクションを介してProxyする)
上記のように、HTTPリクエストを使ってサーバと通信したあとに、そのコネクション上でHTTPメッセージ以外のアプリケーションデータをやりとりできるようになります。もちろん、どのようなアプリケーションデータをやりとりするかはプロトコル次第ですが、HTTPレイヤではそのアプリケーションデータには関与しません (一般に、DATAフレームに格納され送信されます)。
UDP Proxying Support for HTTPは、Apple Private Relayでも利用されている技術であり、詳しくは以前の記事を参照ください
asnokaze.hatenablog.com
拡張CONNECTメソッド
拡張CONNECTメソッドはどのようなメッセージなのか具体例を以下に示します。これは、WebTransport over HTTP/3の接続リクエストの例です。
:method = CONNECT :protocol = webtransport :scheme = https :path = / :authority = server.example.com origin: server.example.com
上記のように :protocol という疑似ヘッダを持つCONNECTメソッドが拡張CONNECTメソッドです。このリクエストに対して200番を返すことで該当のストリームは、:protocol疑似ヘッダで指定されたプロトコル用にデータをトンネルするようになります。ですので、レスポンスを返してもストリームはクローズしません。
先に上げたプロトコルでは、疑似ヘッダの値はこれらになります。
- websocket
- webtransport
- connect-udp
- connect-ip
疑似ヘッダ(pseudo-header)
疑似ヘッダについてはここで簡単に補足します。
HTTP/2やHTTP/3では、メソッド名やリクエストしたURLのスキームやパスは疑似ヘッダとして表現されます(これによりヘッダ圧縮が可能になります)。
疑似ヘッダはHTTP/2やHTTP/3の仕様で定義されていないものを送ってはなりません、受信した側はエラーとして扱う必要があります。ただし拡張CONNECTメソッドは拡張仕様であり、相手がこの拡張仕様に対応していれば :protocol疑似ヘッダを送信することが出来ます。
相手が :protocol 疑似ヘッダに対応しているかは、一般にSETTINGSパラメータで確認します。
SETTINGSパラメータ
HTTP/2やHTTP/3ではコネクションが確立したあとに、クライアントとサーバでSETTINGSパラメータを送り合い、通信に関するパラメータを交換します。その流れで、拡張CONNECTメソッドに対応しているかを確認します。
- SETTINGS_ENABLE_CONNECT_PROTOCOL パラメータをセットして送ることで、相手に対応していることを通知します
- もしくはWebTranportプロトコルの場合は、SETTINGS_ENABLE_WEBTRANSPORTパラメータを送ることで拡張CONNECTメソッドに対応していることを相手に通知します
その後
拡張CONNECTメソッドを用いてストリームをトンネル化したあと、どのようなデータをやりとりするかは、:protocol 疑似ヘッダで示されるプロトコルの仕様によります。