| インターネット技術タスクフォース (IETF) | P. McManus |
| Request for Comments: 8441 | Mozilla |
| Updates: 6455 | 2018年9月 |
| カテゴリー: Standards Track | |
| ISSN: 2070-1721 |
HTTP/2 による WebSocket のブートストラップ
概要
本書は、WebSocket プロトコル (RFC 6455) を HTTP/2 接続の単一ストリーム上で実行するためのメカニズムを定義します。
本メモの状態
これはインターネット標準トラックの文書です。
この文書は Internet Engineering Task Force (IETF) の成果物です。IETF コミュニティの合意を表しています。公開審査を受け、Internet Engineering Steering Group (IESG) によって公開が承認されています。インターネット標準に関するさらなる情報は RFC 7841 のセクション 2 をご覧ください。
この文書の現状、訂正情報、およびフィードバックの送付方法に関する情報は https://www.rfc-editor.org/info/rfc8441 で入手できます。
Copyright Notice
Copyright (c) 2018 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
1. 導入
The Hypertext Transfer Protocol (HTTP) [RFC7230] は異なるバージョン間でリソースレベルの互換的セマンティクスを提供しますが、接続管理レベルでの互換性は提供しません。WebSockets のように HTTP の接続管理の詳細に依存する他のプロトコルは、HTTP の新しいバージョンに合わせて更新する必要があります。
The WebSocket Protocol [RFC6455] は、HTTP/1.1 の Upgrade メカニズム(Section 6.7 of [RFC7230])を用いて、TCP 接続を HTTP から WebSocket 接続へ遷移させます。HTTP/2 [RFC7540] では異なるアプローチが必要です。マルチプレクシングの性質上、HTTP/2 では Upgrade や Connection のような接続全体に関わるヘッダーフィールドや 101 (Switching Protocols) のようなステータスコードを使用できません。これらは [RFC6455] のオープニングハンドシェイクで必須とされている要素です。
HTTP/2 から WebSockets をブートストラップできるようにすることで、単一の TCP 接続を両方のプロトコルで共有でき、HTTP/2 によるネットワークの効率的利用を WebSockets にも拡張できます。
本書は HTTP/2 における CONNECT メソッド(Section 8.3 of [RFC7540])を拡張します。この拡張により、通常 CONNECT が指定する外部ホストの代わりに接続先として新しいプロトコル名を置換できるようになります。その結果、単一の HTTP/2 ストリーム上のトンネルが生成され、WebSockets(または他の任意のプロトコル)のデータを運ぶことができます。接続上の他のストリームは拡張 CONNECT トンネル、従来の HTTP/2 データ、またはその混在を運ぶことができます。
このトンネル化されたストリームは接続上の他の通常ストリームとマルチプレクスされ、HTTP/2 の通常の優先度、キャンセル、フロー制御の機能を享受します。
本仕様で定義するオープニングハンドシェイクの修正を用いてトンネル化ストリーム上で WebSocket 接続を確立したストリームは、その後は従来の WebSocket プロトコルを使用し、当該ストリームを RFC6455 が参照する TCP 接続として扱います。
2. 用語
3. SETTINGS_ENABLE_CONNECT_PROTOCOL SETTINGS パラメータ
本書は [RFC7540] の定義する SETTINGS パラメータに新しいパラメータを追加します(Section 6.5.2)。
新しいパラメータ名は SETTINGS_ENABLE_CONNECT_PROTOCOL です。パラメータの値は 0 または 1 でなければなりません。
SETTINGS_ENABLE_CONNECT_PROTOCOL の値が 1 で受信された場合、クライアントは新しいストリームを作成する際に本書で定義する拡張 CONNECT を使用してもよい(MAY)ものとします。サーバーがこのパラメータを受信しても、サーバー側に影響はありません。
送信者は、一度 1 を送信した後に 0 の SETTINGS_ENABLE_CONNECT_PROTOCOL を送信してはなりません(MUST NOT)。
互換性のないプロトコル変更へのオプトインに SETTINGS パラメータを用いることは、[RFC7540] の “Extending HTTP/2” の利用法です(Section 5.5)。具体的には、新しい疑似ヘッダフィールド “:protocol” の追加と、Section 4 における :authority 疑似ヘッダの意味の変更はオプトインの交渉を必要とします。クライアントが SETTINGS_ENABLE_CONNECT_PROTOCOL を先に受け取らずに本拡張を用いると、非対応のピアは不正な要求を検出してストリームエラーを生成します(Section 8.1.2.6)。
4. 拡張 CONNECT メソッド
HTTP/2 における CONNECT メソッドの利用は Section 8.3 of [RFC7540] で定義されています。本拡張は次の点でメソッドを修正します:
- 要求 HEADERS に新しい疑似ヘッダフィールド :protocol を含めることができ、これは CONNECT により作成されるトンネル上で使用したいプロトコルを示します。疑似ヘッダは単一値であり、値は IANA の “Hypertext Transfer Protocol (HTTP) Upgrade Token Registry” にあるトークンから選ばれます(<https://www.iana.org/assignments/http-upgrade-tokens/>)。
- :protocol 疑似ヘッダを含む要求では、ターゲット URI の疑似ヘッダ :scheme と :path(Section 5 を参照)も必ず含めなければなりません(MUST)。
- :protocol 疑似ヘッダを付けた要求では、:authority 疑似ヘッダは本拡張においては Section 8.1.2.3 の解釈に従い扱われます。これは、通常の拡張されていない CONNECT リクエストで行われるように、:authority で示されたホストへトンネルを作成するという動作をサーバーが行ってはならない(MUST NOT)ことを意味します。
:protocol 疑似ヘッダを持つ CONNECT リクエストを受け取ると、サーバーは疑似ヘッダで示されたプロトコル種別の別のサービスへトンネルを確立します。このサービスはサーバーと同一ホストである場合もあれば、そうでない場合もあります。
5. 拡張 CONNECT を用いた WebSocket プロトコルのブートストラップ
:protocol 疑似ヘッダは CONNECT リクエストに必ず含められなければならず(MUST)、HTTP/2 ストリーム上で WebSocket 接続を開始するためにはその値が websocket でなければなりません。クッキー操作などの他の HTTP リクエスト/レスポンスヘッダーフィールドは、従来どおり CONNECT の HEADERS に含めることができます。この要求は [RFC6455] の GET ベースの要求に代わるものであり、WebSockets のオープニングハンドシェイクを処理するために使用されます。
ターゲット URI のスキーム(Section 5.1 of [RFC7230])は、"wss" スキームの WebSockets については “https”、"ws" スキームの WebSockets については “http” でなければなりません。ターゲット URI の残りの部分は WebSocket URI と同じです。WebSocket URI は依然としてプロキシ自動構成に使用されます。本仕様で使用される HTTP/2 接続のセキュリティ要件は、https リクエストについては [RFC7540] に、http リクエストについては [RFC8164] によって確立されます。
[RFC6455] は、HTTP/2 の一部ではない Connection および Upgrade ヘッダーフィールドの使用を要求しています。これらはここで定義する CONNECT リクエストには含めてはなりません(MUST NOT)。
[RFC6455] は Host ヘッダーフィールドの使用も要求していますが、HTTP/2 では Host 情報は各トランザクションで必須の疑似ヘッダフィールド :authority として伝えられます。
本拡張を使って WebSockets をブートストラップする実装では、Sec-WebSocket-Key および Sec-WebSocket-Accept ヘッダーフィールドの処理は行いません。これらの機能は :protocol 疑似ヘッダフィールドによって置き換えられるためです。
Origin ([RFC6454]), Sec-WebSocket-Version, Sec-WebSocket-Protocol, および Sec-WebSocket-Extensions ヘッダーフィールドは、[RFC6455] に定義されたとおりに CONNECT のリクエストおよびレスポンスヘッダーフィールドで使用されます。なお、HTTP/1 のヘッダーフィールド名は大文字小文字を区別しませんでしたが、HTTP/2 では小文字でエンコードすることが要求される点に注意してください。
オープニングハンドシェイクを正常に処理した後、ピアは CONNECT トランザクションの HTTP/2 ストリームを RFC6455 が参照する TCP 接続の代わりとして扱い、WebSocket プロトコルを進めます。この時点で WebSocket 接続の状態は RFC6455 の定義どおり OPEN になります([RFC6455], Section 4.1)。
HTTP/2 ストリームのクローズは RFC6455 の TCP 接続クローズに相当します。順序だてられた TCP レベルのクローズは END_STREAM フラグで表現され([RFC7540], Section 6.1)、RST の例外は RST_STREAM フレーム([RFC7540], Section 6.4)と CANCEL エラーコードで表現されます([RFC7540], Section 7)。
5.1. 例
[[ From Client ]] [[ From Server ]]
SETTINGS
SETTINGS_ENABLE_CONNECT_[..] = 1
HEADERS + END_HEADERS
:method = CONNECT
:protocol = websocket
:scheme = https
:path = /chat
:authority = server.example.com
sec-websocket-protocol = chat, superchat
sec-websocket-extensions = permessage-deflate
sec-websocket-version = 13
origin = http://www.example.com
HEADERS + END_HEADERS
:status = 200
sec-websocket-protocol = chat
DATA
WebSocket Data
DATA + END_STREAM
WebSocket Data
DATA + END_STREAM
WebSocket Data
6. 設計上の考慮事項
HTTP/2 とよりネイティブに統合するには、HTTP/2 にさらなる追加を行うことで可能ですが、本設計は複雑さを最小限に抑えつつ、HTTP/2 と WebSockets を同時に動作させる主要な課題に対処するために選択されました。
7. 仲介者に関して
本書は WebSockets と HTTP フォワードプロキシの相互作用を変更しません。WebSockets を使用したいクライアントが HTTP/2 経由で HTTP プロキシに接続する場合、そのクライアントは従来の CONNECT(すなわち :protocol 疑似ヘッダを使わない通常の CONNECT)を用いて、そのプロキシ経由で WebSocket サーバーへトンネルするべきです。
その結果得られるトンネル上で使用される HTTP のバージョンが、WebSockets を直接開始するか、本書で説明された修正された CONNECT 要求を介して開始するかを決定します。
8. セキュリティに関する考慮事項
[RFC6455] は、特に XMLHttpRequest ベースのクライアントのような非 WebSockets クライアントが WebSocket 接続を確立できないようにする仕組みを提供します。その主なメカニズムは、XMLHttpRequest ベースのクライアントが作成できない Sec- プレフィックスの付いたリクエストヘッダーフィールドの使用です。本仕様はこの懸念に二つの方法で対処します:
- XMLHttpRequest は Sec- プレフィックスのヘッダーフィールドに加え、CONNECT メソッドの使用も禁止しています。
- 疑似ヘッダフィールドの使用は接続固有のものであり、HTTP/2 ではプロトコルスタック外で疑似ヘッダを作成することは決して許されません。
[RFC6455] のセキュリティ考慮事項(Section 10)は、本仕様を用いる場合の WebSocket プロトコルの使用にも引き続き適用されます。ただし、Section 10.8 は、本書で変更されたブートストラップハンドシェイク固有の内容であるため該当しません。
9. IANA に関する考慮事項
9.1. 新しい HTTP/2 設定
本書は Section 11.3 of [RFC7540] で確立された “HTTP/2 Settings” レジストリにエントリを登録します。
- Code:
- 0x8
- Name:
- SETTINGS_ENABLE_CONNECT_PROTOCOL
- Initial Value:
- 0
- Specification:
- 本書
9.2. 新しい HTTP Upgrade トークン
本書は [RFC7230] によって確立された “HTTP Upgrade Tokens” レジストリにエントリを登録します。
- Value:
- websocket
- Description:
- The Web Socket Protocol
- Expected Version Tokens:
- References:
- [RFC6455] [RFC8441]
10. 規範的参考文献
- [RFC2119]
- Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.
- [RFC6454]
- Barth, A., “The Web Origin Concept”, RFC 6454, DOI 10.17487/RFC6454, December 2011, <https://www.rfc-editor.org/info/rfc6454>.
- [RFC6455]
- Fette, I. and A. Melnikov, “The WebSocket Protocol”, RFC 6455, DOI 10.17487/RFC6455, December 2011, <https://www.rfc-editor.org/info/rfc6455>.
- [RFC7230]
- Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing”, RFC 7230, DOI 10.17487/RFC7230, June 2014, <https://www.rfc-editor.org/info/rfc7230>.
- [RFC7540]
- Belshe, M., Peon, R., and M. Thomson, Ed., “Hypertext Transfer Protocol Version 2 (HTTP/2)”, RFC 7540, DOI 10.17487/RFC7540, May 2015, <https://www.rfc-editor.org/info/rfc7540>.
- [RFC8164]
- Nottingham, M. and M. Thomson, “Opportunistic Security for HTTP/2”, RFC 8164, DOI 10.17487/RFC8164, May 2017, <https://www.rfc-editor.org/info/rfc8164>.
- [RFC8174]
- Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.
謝辞
2017 年の HTTP ワークショップでは、この問題の主要点と許容される解決の複雑さのレベルを決定する上で非常に生産的な議論が行われました。