[50] WebSocket接続の確立時にクライアントとサーバーで
Sec-WebSocket-Extensions:
ヘッダーにより折衝することで、
拡張を使うことができます。
[68] 拡張は圧縮 permessage-deflate
のために用いられています。
理論上はそれ以外の用途や手法にも利用できますが、実際には使われていません。
[78] 拡張は、 WebSocket プロトコル本体仕様に含まれない機能を追加で定めるものです。
[80] WebSocket の実装はどの拡張にも対応する義務はありません。 クライアントとサーバーはどの拡張を利用するかを WebSocket接続の確立時に決定します。
[55] RFC 7692 は WebSocket に圧縮機能を追加するフレームワークとして WebSocket Per-Message Compression Extensions (PMCEs) を定義しています。 >>54
[56] RFC 7692 は PMCE に則った具体的な WebSocket拡張として
permessage-deflate
を定義しています。これ以外は定義されていませんし、
その動きもありません。
[77] 各 PMCE は、次のものを定めなければなりません >>76。
[65] JavaScript の WebSocket クライアントが利用する拡張を指定する手段は提供されていません。 どの拡張を使うかは、 Webブラウザーの実装次第となっています。
WebSocket
インターフェイス extensions
属性[34] WebSocket
インターフェイスの
extensions
IDL属性は、
利用されている拡張について返すものです。
[66] このIDL属性により、クライアントとサーバーとの折衝の結果利用されることとなった (そして現に利用されている) 拡張が何であるかを著者は知ることができます。
[35] この属性は、内部的に保持している値を返さなければなりません >>33。 値は、WebIDL接続の確立の過程で設定されます。
[4] ハンドシェイクの手順についてはWebSocket接続の確立を参照。
Sec-WebSockete-Extensions:
ヘッダー[3] クライアントは Sec-WebSocket-Extensions:
ヘッダーで拡張を指定することで、
拡張を使うことを要求できます。
[64] サーバーは Sec-WebSocket-Extensions:
ヘッダーで拡張を指定することで、
拡張を使うことに合意することを示せます。
[5] 本ヘッダーの値は、
1つ以上の拡張の指定のリスト (HTTP)
(#
) です >>2。
[12] 拡張の指定の順序は、意味を持ちます。 拡張同士の関係は、 特に規定がある場合は、それによります。そうでない場合、 クライアントが先に指定したものが優先度の高いものです。 サーバーが指定した順序が実際の適用順となり、 データに対して先に指定したものから順に拡張依存の操作を適用していったことを表します。 >>2
[57] next extension in use after extension X
とは、
サーバーが Sec-WebSocket-Extensions:
ヘッダーで
X の直後に指定した拡張です。
すなわち、送信するデータに関しては X の直後に適用し、
受信するデータに関しては X の直前に適用するものです。 >>75
[58] extension in use preceding extension X
とは、
サーバーが Sec-WebSocket-Extensions:
ヘッダーで
X の直前に指定した拡張です。
すなわち、送信するデータに関しては X の直前に適用し、
受信するデータに関しては X の直後に適用するものです。 >>75
[6] 拡張の指定は、
拡張の字句の後に0個以上の引数を続けたものです。
引数の前には ;
が必要です。 >>2
暗示的な空白 >>2 により、 ;
の前後には OWS が認められると推測されます。
[9] 字句は、IANA登録簿 >>15, >>17 に登録されたものでなければなりません >>2。
[7] 引数は、字句の後に =
があり、
その後に字句か引用文字列が来るものです。ただし =
以後は省略できます。また引用文字列の場合は、 unescape
して字句となる値でなければなりません。 >>2
暗示的な空白 >>2 により、 ;
の前後には BWS が認められると推測されます。
[10] 引数は、当該拡張で定義されたものでなければなりません >>2。
[8] 本ヘッダーは、要求では複数指定できます >>2, >>14。 応答で複数使ってはならない >>14 と規定がありますが、 他の部分と矛盾しているとし、使っても良いと訂正 >>16 されています。
[59] extension negotiation offer
は、クライアントの Sec-WebSocket-Extensions:
ヘッダーの各要素です。 >>75
[83]
クライアントは、
PMCE を使うことを望む場合、
Sec-WebSocket-Extensions:
ヘッダーに
PMCE 拡張名を含めなければなりません。
必要があれば引数も使います。
>>82
[84] 複数の PMCE を指定したり、異なる引数の同じ PMCE を複数指定したりもできます。 >>82
[85] 順序は、クライアントの希望の高い順とします。 サーバーは、対応している希望度の高いものを採用するべきです。 >>82
[86] PMCE extension negotiation offer は、 クライアントからサーバーに対する要求やヒントを記述するものです。 要求は、サーバーが満たさなければならない制約を指定するものです。 ヒントは、サーバーが無視しても採用しても良いクライアントの動作に関する情報を記述するものです。 >>82
[98] クライアントは offer の引数で次のような情報を記述します。 サーバーはこれを元に動作を決定します。 >>82
[60] extension negotiation response
は、サーバーの Sec-WebSocket-Extensions:
ヘッダーの各要素です。 >>75
[61] corresponding extension negotiation response for an extension negotiation offer は、 extension negotiation offer と同じ拡張名であってその表す要件を満たす extension negotiation response です。 >>75
[62] Accepting an extension negotiation offer とは、 corresponding extension negotiation response for an extension negotiation offer を含めることです。 >>75
[63] Declining an extension negotiation offer とは、 corresponding extension negotiation response for an extension negotiation offer を含めないことです。 >>75
[87] サーバーは、 PMCE の offer を accept する場合、
拡張名を Sec-WebSocket-Extensions:
ヘッダーに含めなければなりません。
引数は PMCE の詳細を記述するもので、 agreed parameter
といいます。
この extension negotiation response は、
サーバーが完全に対応している PMCE でなければなりません。
>>82
[99] サーバーは引数で次の事項を記述します。 クライアントはこれにより動作を決定します。 >>82
[89] agreed parameter は、 クライアントの要求とヒントをサーバーがどう扱うかを表すものであると共に、 サーバーがクライアントの挙動について要求とヒントを示すものでもなければなりません。 >>82
[88] extension negotiation response は extension negotiation offer と完全に一致している必要はありません。 offer の引数で指定された追加機能をサーバーが使わない場合は、 これを agreed parameter に含めないようにします。 なお extension negotiation offer の引数名と extension negotiation response の引数名が同じである必要もありません。 >>82
[90] 引数名は送受信どちらに関するものであるかを区別するため
server_
や client_
をつけることもできます。 >>82
[91] サーバーは、 PMCE extension negotiation offer と
RSV1
の用法が衝突する他の拡張を同時に受理してはなりません。
クライアントは、そのような応答を受信した場合、
WebSocket接続失敗としなければなりません。
>>82
[92] サーバーは、PMCE が出力に適用される場合に、 次のような状況となるような他の拡張を同時に受理してはなりません。 クライアントは、そのような応答を受信した場合、 WebSocket接続失敗としなければなりません。 >>82
RSV1
, RSV2
, RSV3
を用いるもの。[95] サーバーは、 PMCE をすべて declining する場合には、 PMCE 拡張名を含めてはなりません。 >>82
[96] クライアントが offer していない PMCE が accepting されているなど不当な応答を受信した場合には、 クライアントはWebSocket接続失敗としなければなりません。 >>82
[100] クライアントは PMCE extension negotiation response
が受け入れられないものである時は、
閉じ符号 1010
の closing handshake を開始します。 >>82
[97] サーバーが妥当な PMCE の指定を Sec-WebSocket-Extensions:
ヘッダーに含め、
WebSocket接続確立に至った場合、
クライアントとサーバーは
agreed parameter に従った PMCE
により、 message payload の変形 (圧縮・展開) を行わなければなりません。
>>82
[52] 拡張は、次のプロトコル要素を使うことができます >>49。
[103] WebSocketフレームには、 拡張データ欄があります。 これは拡張により規定された長さと用途のデータです。 拡張がなければ長さ 0 です。 >>102
[13] 現時点で利用例はありません。
[101] WebSocketフレームには、
RSV1 (frame-rsv1
),
RSV2 (frame-rsv2
),
RSV3 (frame-rsv3
)
の3つの1ビット欄があります。 >>102
[108] この3つの欄は、拡張により規定される場合を除き、 0 でなければなりません。 受信したフレームのこの3つの欄のいずれかであっても非 0 値であり、拡張の規定に拠っていない場合には、 WebSocket接続失敗としなければなりません。 >>102
[109] この3つの欄についてはIANA登録簿があります >>163, >>166。
permessage-deflate
における RSV1 が登録されています。
[104] PMCE は RSV1 を メッセージ毎圧縮 ビットと呼んでいます。 メッセージが圧縮されているか否かを表します。 >>111
[120] データメッセージの先頭のデータフレームでメッセージ毎圧縮ビットが設定されている場合、 そのデータメッセージのpayloadデータは圧縮データです。
[119] 制御フレームや、データメッセージの先頭以外のデータフレームでは、 メッセージ毎圧縮ビットを設定してはなりません。 そのようなフレームを受信した場合、 WebSocket接続失敗としなければなりません。 >>111
[110] PMCE はデータメッセージにのみ適用されます。 >>111
[105] 最初のフレームのメッセージ毎圧縮ビットの設定されたメッセージを、 圧縮メッセージといいます。 >>111
[122] 圧縮メッセージのフレームのpayloadデータは、 圧縮されたデータです。 opcode 依存の payloadデータの制約は、展開された状態のデータにのみ適用されます。 >>111
[123] 例えばテキストフレームからはじまる message payload は UTF-8 データでなければなりません。圧縮メッセージでは実際に送信される各フレームのpayloadデータは UTF-8 になっているとは限りません (なっていない可能性の方が高いです)。 しかしそれを展開した結果は UTF-8 となっていなければなりません。
[106] 最初のフレームのメッセージ毎圧縮ビットの設定されていないメッセージを、 非圧縮メッセージといいます。 >>111
[121] 非圧縮メッセージのフレームのpayloadデータは、 圧縮されていないデータです。 >>111
permessage-deflate
[130] DEFLATE を使う場合の拡張名は
permessage-deflate
です。
次の引数があります。
いずれもクライアントの extension negotiation offer
とサーバーのextension negotiation response で使用します。
>>129
[132] client_
はクライアントが圧縮しサーバーが展開する際のもの、
server_
はサーバーが圧縮しクライアントが展開する際のものを表します。
>>129
[133] サーバーは、 次のいずれかを満たす場合、 extension negotiation offer を decline しなければなりません。 >>129
[134] クライアントは、 extension negotiation offer に対する extension negotiation response が次のいずれかを満たす場合、 WebSocket接続失敗としなければなりません。 >>129
[74] Chrome と Firefox は permessage-deflate
を実装しています。
[18] 現時点で IANA に登録されている拡張はありません。
[48] 2015年9月に permessage-deflate
が登録されています。
[23] DEFLATE 圧縮のための x-webkit-deflate-frame
が実装されていました >>20。
[24] その改訂版である permessage-deflate
>>46
が実装されています >>25, >>22。
[29] Chrome は次のようなヘッダーを送るようです。
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
[31] 他に多重化のための拡張が提案されていました >>30。
[43] 拡張のせいで不必要にプロトコルが複雑になっている気がしますが...
[41] WebSocket permessage-deflate in Chrome with no context takeover - Stack Overflow ( 版) <http://stackoverflow.com/questions/22169036/websocket-permessage-deflate-in-chrome-with-no-context-takeover>
[42] Intent to Implement: PerMessageDeflate extension on WebSocket - Google グループ ( 版) <https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/ZboxIILY2fo>
[44] Issue 163882 - chromium - WebSocket permessage-deflate: Improve compress/no-compress decision - An open-source project to help move the web forward. - Google Project Hosting ( 版) <https://code.google.com/p/chromium/issues/detail?id=163882>
[45] Re: [hybi] Closing the hybi working group ( 版) <http://www.ietf.org/mail-archive/web/hybi/current/msg10527.html>
[47] [hybi] Discontinuation of mux standardizaton in favor of WS/HTTP/2.0 ( 版) <http://www.ietf.org/mail-archive/web/hybi/current/msg10266.html>
[51] Define permessage-deflate extension and cache-mode for WebSocket · whatwg/fetch@267a8ef ( 版) <https://github.com/whatwg/fetch/commit/267a8effeacfe5d641010d1d4f4609f9602cdab6>
[53] Fix #852: WebSocket has implemented extensions · whatwg/html@78e6d56 ( 版) <https://github.com/whatwg/html/commit/78e6d56a64eb7d8ed7ee29b93ea37789f249b3ef>
[69] Bug 485469 – permessage-deflate extension causes protocol error in Firefox/Chrome () <https://bugs.eclipse.org/bugs/show_bug.cgi?id=485469>
[70] 580290 - permessage-deflate implementation does not support RFC7692 Section 7.2.3.6 (empty frame) correctly - chromium - Monorail () <https://bugs.chromium.org/p/chromium/issues/detail?id=580290>
[71] 115504 – [WebSocket] Remove x-webkit-deflate-frame extension support () <https://bugs.webkit.org/show_bug.cgi?id=115504>
[72] 98840 – [WebSocket] Add permessage-compress extension () <https://bugs.webkit.org/show_bug.cgi?id=98840>
[73] 115863 – [WebSocket] Update pywebsocket to r760 () <https://bugs.webkit.org/show_bug.cgi?id=115863>