[50] [[WebSocket接続の確立]]時に[[クライアント]]と[[サーバー]]で
[CODE(HTTP)@en[Sec-WebSocket-Extensions:]] [[ヘッダー][HTTPヘッダー]]により折衝することで、
[DFN[[RUBYB[拡張]@en[extension]]]]を使うことができます。

[68] [[拡張][WebSocket拡張]]は[[圧縮]] [CODE[permessage-deflate]] のために用いられています。
理論上はそれ以外の用途や手法にも利用できますが、実際には使われていません。

* 仕様書

[REFS[
- [1] [CITE@en[RFC 6455 - The WebSocket Protocol]]
([TIME[2015-03-11 20:42:50 +09:00]] 版)
<https://tools.ietf.org/html/rfc6455#section-4.3>
- [102] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <https://tools.ietf.org/html/rfc6455#section-5>
- [2] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <https://tools.ietf.org/html/rfc6455#section-9>
- [14] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <https://tools.ietf.org/html/rfc6455#section-11.3.2>
- [15] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <https://tools.ietf.org/html/rfc6455#section-11.4>
- [163] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <https://tools.ietf.org/html/rfc6455#section-11.9>
- [16] [CITE[RFC Errata Report]] ([TIME[2015-05-16 22:22:53 +09:00]] 版) <http://www.rfc-editor.org/errata_search.php?rfc=6455>
- [166] [CITE[WebSocket Protocol Registries]] ([TIME[2015-03-06 13:09:47 +09:00]] 版) <https://www.iana.org/assignments/websocket/websocket.xml#framing-header-bits>
- [17] [CITE[WebSocket Protocol Registries]] ([TIME[2015-03-06 13:09:47 +09:00]] 版) <https://www.iana.org/assignments/websocket/websocket.xml#extension-name>
- [33] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-05-06 10:42:35 +09:00]] 版) <https://html.spec.whatwg.org/#dom-websocket-extensions>
- [54] [CITE@en[RFC 7692 - Compression Extensions for WebSocket]] ([TIME[2017-09-19 00:18:15 +09:00]]) <https://tools.ietf.org/html/rfc7692>
-- [75] [CITE@en[RFC 7692 - Compression Extensions for WebSocket]] ([TIME[2017-09-19 00:18:15 +09:00]]) <https://tools.ietf.org/html/rfc7692#section-3>
-- [76] [CITE@en[RFC 7692 - Compression Extensions for WebSocket]] ([TIME[2017-09-19 00:18:15 +09:00]]) <https://tools.ietf.org/html/rfc7692#section-4>
-- [82] [CITE@en[RFC 7692 - Compression Extensions for WebSocket]] ([TIME[2017-09-19 00:18:15 +09:00]]) <https://tools.ietf.org/html/rfc7692#section-5>
-- [111] [CITE@en[RFC 7692 - Compression Extensions for WebSocket]] ([TIME[2017-09-19 00:18:15 +09:00]]) <https://tools.ietf.org/html/rfc7692#section-6>
-- [129] [CITE@en[RFC 7692 - Compression Extensions for WebSocket]] ([TIME[2017-09-19 00:18:15 +09:00]]) <https://tools.ietf.org/html/rfc7692#section-7>
]REFS]

* 拡張

[78] [[拡張][WebSocket拡張]]は、 [[WebSocket]] 
プロトコル本体仕様に含まれない機能を追加で定めるものです。

[80] [[WebSocket]] の実装はどの[[拡張][WebSocket拡張]]にも対応する義務はありません。
[[クライアント]]と[[サーバー]]はどの[[拡張][WebSocket拡張]]を利用するかを
[[WebSocket接続の確立]]時に決定します。

[81] 実際に存在しているのは [[PMCE]] のみです。

** PMCE

[55] [DFN[RFC 7692]] は [[WebSocket]] に[[圧縮]]機能を追加する[[フレームワーク]]として
[DFN[WebSocket Per-Message Compression Extensions]] ([DFN[PMCEs]])
を定義しています。
[SRC[>>54]]

[56] [[RFC 7692]] は [[PMCE]] に則った具体的な [[WebSocket拡張]]として 
[CODE[permessage-deflate]] を定義しています。これ以外は定義されていませんし、
その動きもありません。

[77] 各 [[PMCE]] は、次のものを定めなければ[MUST[なりません]] [SRC[>>76]]。

- 拡張名
- [[引数]]とその解釈
- [[message payload]] の[RUBYB[変形]@en[transform]]方法

* クライアント API

[65] [[JavaScript]] の [[WebSocket]] クライアントが利用する[[拡張][WebSocket拡張]]を指定する手段は提供されていません。
どの[[拡張][WebSocket拡張]]を使うかは、 [[Webブラウザー]]の実装次第となっています。

** [CODE(DOMi)@en[WebSocket]] インターフェイス [CODE(DOMa)@en[extensions]] 属性

[34] [CODE(DOMi)@en[[[WebSocket]]]] [[インターフェイス]]の
[DFN[[CODE(DOMa)@en[[[extensions]]]]]] [[IDL属性]]は、
利用されている[[拡張]]について返すものです。

[66] この[[IDL属性]]により、[[クライアント]]と[[サーバー]]との折衝の結果利用されることとなった
(そして現に利用されている) [[拡張][WebSocket拡張]]が何であるかを[[著者]]は知ることができます。

;; [67] もっとも、この情報が有用かどうかは謎です。

[35] この[[属性]]は、内部的に保持している値を返さなければ[MUST[なりません]] [SRC[>>33]]。
値は、[[WebIDL接続の確立]]の過程で設定されます。

* ハンドシェイク

[4] ハンドシェイクの手順については[[WebSocket接続の確立]]を参照。

** [CODE[Sec-WebSockete-Extensions:]] ヘッダー

[3] [[クライアント]]は [CODE(HTTP)@en[Sec-WebSocket-Extensions:]]
[[ヘッダー][HTTPヘッダー]]で[[拡張][WebSocket拡張]]を指定することで、
[[拡張][WebSocket拡張]]を使うことを要求できます。

[64] [[サーバー]]は [CODE(HTTP)@en[[[Sec-WebSocket-Extensions:]]]]
[[ヘッダー][HTTPヘッダー]]で[[拡張][WebSocket拡張]]を指定することで、
[[拡張][WebSocket拡張]]を使うことに合意することを示せます。

;; [36] この[[ヘッダー]]は、 [[fingerprinting vector]] です。

-*-*-

[5] 本[[ヘッダー][HTTPヘッダー]]の値は、
1つ[[以上]]の[[拡張][WebSocket拡張]]の指定の[[リスト (HTTP)]] 
([CODE(HTTP)[#]]) です [SRC[>>2]]。

[FIG(railroad)[
= [[拡張][WebSocket拡張]]の指定
= *
== [[OWS]]
== [CODE(HTTP)[[[,]]]]
== [[OWS]]
== [[拡張][WebSocket拡張]]の指定
]FIG]

[12] [[拡張][WebSocket拡張]]の指定の順序は、意味を持ちます。
[[拡張][WebSocket拡張]]同士の関係は、
特に規定がある場合は、それによります。そうでない場合、
[[クライアント]]が先に指定したものが優先度の高いものです。
[[サーバー]]が指定した順序が実際の適用順となり、
データに対して先に指定したものから順に[[拡張][WebSocket拡張]]依存の操作を適用していったことを表します。 [SRC[>>2]]

[57] [DFN[next extension in use after extension [VAR[X]]]]
とは、
[[サーバー]]が [CODE[Sec-WebSocket-Extensions:]] [[ヘッダー][HTTPヘッダー]]で
[VAR[X]] の直後に指定した[[拡張][WebSocket拡張]]です。
すなわち、送信するデータに関しては [VAR[X]] の直後に適用し、
受信するデータに関しては [VAR[X]] の直前に適用するものです。 [SRC[>>75]]

[58] [DFN[extension in use preceding extension [VAR[X]]]]
とは、
[[サーバー]]が [CODE[Sec-WebSocket-Extensions:]] [[ヘッダー][HTTPヘッダー]]で
[VAR[X]] の直前に指定した[[拡張][WebSocket拡張]]です。
すなわち、送信するデータに関しては [VAR[X]] の直前に適用し、
受信するデータに関しては [VAR[X]] の直後に適用するものです。 [SRC[>>75]]

-*-*-

[6] [[拡張][WebSocket拡張]]の指定は、
[[拡張][WebSocket拡張]]の[[字句]]の後に0個以上の[[引数]]を続けたものです。
[[引数]]の前には [CODE(HTTP)[[[;]]]] が必要です。 [SRC[>>2]]
暗示的な[[空白]] [SRC[>>2]] により、 [CODE(HTTP)[[[;]]]]
の前後には [[OWS]] が認められると推測されます。

[9] [[字句]]は、[[IANA登録簿]] [SRC[>>15, >>17]]
に登録されたものでなければ[['''なりません''']] [SRC[>>2]]。

[FIG(railroad)[
= [[字句]]
= *
== [[OWS]]
== [CODE(HTTP)[[[;]]]]
== [[OWS]]
== [[引数]]
]FIG]

[7] [[引数]]は、[[字句]]の後に [CODE(HTTP)[[[=]]]] があり、
その後に[[字句]]か[[引用文字列]]が来るものです。ただし [CODE(HTTP)[[[=]]]]
以後は省略できます。また[[引用文字列]]の場合は、 [[unescape]]
して[[字句]]となる値でなければ[['''なりません''']]。 [SRC[>>2]]
暗示的な[[空白]] [SRC[>>2]] により、 [CODE(HTTP)[[[;]]]]
の前後には [[BWS]] が認められると推測されます。

[10] [[引数]]は、当該[[拡張][WebSocket拡張]]で定義されたものでなければ[MUST[なりません]] 
[SRC[>>2]]。

[FIG(railroad)[
= [[字句]]
= ?
== [CODE(HTTP)[[[=]]]]
== |
=== [[字句]]
=== [[引用文字列]]
]FIG]

[8] 本[[ヘッダー][HTTPヘッダー]]は、[[要求]]では複数指定できます [SRC[>>2, >>14]]。
[[応答]]で複数使っては[MUST[ならない]] [SRC[>>14]] と規定がありますが、
他の部分と矛盾しているとし、使っても良いと訂正 [SRC[>>16]] されています。

-*-*-

[11] [[クライアント]]は、[[サーバー]]が[[応答]]で同意しない限り[[拡張][WebSocket拡張]]を使っては[['''なりません''']]
[SRC[>>2]]。

** 処理

[59] [DFN[extension negotiation offer]]
は、[[クライアント]]の [CODE[Sec-WebSocket-Extensions:]] 
[[ヘッダー][HTTPヘッダー]]の各要素です。 [SRC[>>75]]

[83] 
[[クライアント]]は、
[[PMCE]] を使うことを望む場合、
[CODE[Sec-WebSocket-Extensions:]] [[ヘッダー][HTTPヘッダー]]に
[[PMCE]] 拡張名を含めなければ[MUST[なりません]]。
必要があれば[[引数]]も使います。
[SRC[>>82]]

[84] 複数の [[PMCE]] を指定したり、異なる[[引数]]の同じ [[PMCE]] を複数指定したりもできます。
[SRC[>>82]]

[85] 順序は、[[クライアント]]の希望の高い順とします。
[[サーバー]]は、対応している希望度の高いものを採用する[RUBYB[べき]@en[recommended]]です。
[SRC[>>82]]

[86] [[PMCE]] [[extension negotiation offer]] は、
[[クライアント]]から[[サーバー]]に対する[RUBYB[要求]@en[request]]や[RUBYB[ヒント]@en[hint]]を記述するものです。
要求は、[[サーバー]]が満たさなければならない制約を指定するものです。
ヒントは、[[サーバー]]が無視しても採用しても良い[[クライアント]]の動作に関する情報を記述するものです。 [SRC[>>82]]

[98] [[クライアント]]は offer の[[引数]]で次のような情報を記述します。
[[サーバー]]はこれを元に動作を決定します。 [SRC[>>82]]

- クライアントがデータを圧縮する方法のヒント
- サーバーが圧縮する方法の要求
- クライアントの圧縮機能についての制限



[60] [DFN[extension negotiation response]] 
は、[[サーバー]]の [CODE[Sec-WebSocket-Extensions:]] 
[[ヘッダー][HTTPヘッダー]]の各要素です。 [SRC[>>75]]

[61] [DFN[corresponding extension negotiation response for an extension negotiation offer]]
は、 [[extension negotiation offer]] と同じ拡張名であってその表す要件を満たす
[[extension negotiation response]] です。 [SRC[>>75]]

[62] [DFN[Accepting an extension negotiation offer]]
とは、 [[corresponding extension negotiation response for an extension negotiation offer]]
を含めることです。 [SRC[>>75]]

[63] [DFN[Declining an extension negotiation offer]]
とは、 [[corresponding extension negotiation response for an extension negotiation offer]]
を含め''ない''ことです。 [SRC[>>75]]

[87] [[サーバー]]は、 [[PMCE]] の offer を accept する場合、
拡張名を [CODE[Sec-WebSocket-Extensions:]] [[ヘッダー][HTTPヘッダー]]に含めなければ[MUST[なりません]]。
[[引数]]は [[PMCE]] の詳細を記述するもので、 [DFN[agreed parameter]]
といいます。
この [[extension negotiation response]] は、
[[サーバー]]が完全に対応している [[PMCE]] でなければ[MUST[なりません]]。
[SRC[>>82]]

[99] [[サーバー]]は[[引数]]で次の事項を記述します。
[[クライアント]]はこれにより動作を決定します。 [SRC[>>82]]

- クライアントがデータを圧縮する方法についての要求
- サーバーがデータを圧縮する方法


[89] [[agreed parameter]] は、
[[クライアント]]の要求とヒントを[[サーバー]]がどう扱うかを表すものであると共に、
[[サーバー]]が[[クライアント]]の挙動について要求とヒントを示すものでもなければなりません。
[SRC[>>82]]

[88] [[extension negotiation response]] は
[[extension negotiation offer]] と完全に一致している必要はありません。
offer の[[引数]]で指定された追加機能を[[サーバー]]が使わない場合は、
これを [[agreed parameter]] に含めないようにします。
なお [[extension negotiation offer]] の引数名と
[[extension negotiation response]] の引数名が同じである必要もありません。 [SRC[>>82]]

[90] [[引数]]名は送受信どちらに関するものであるかを区別するため
[CODE[server_]] や [CODE[client_]] をつけることもできます。 [SRC[>>82]]


[91] [[サーバー]]は、 [[PMCE]] [[extension negotiation offer]] と
[CODE[RSV1]] の用法が衝突する他の[[拡張][WebSocket extension]]を同時に受理しては[MUST[なりません]]。
[[クライアント]]は、そのような[[応答]]を受信した場合、
[[WebSocket接続失敗]]としなければ[MUST[なりません]]。
[SRC[>>82]]

[92] [[サーバー]]は、[[PMCE]] が出力に適用される場合に、
次のような状況となるような他の[[拡張][WebSocket extension]]を同時に受理しては[MUST[なりません]]。
[[クライアント]]は、そのような[[応答]]を受信した場合、
[[WebSocket接続失敗]]としなければ[MUST[なりません]]。
[SRC[>>82]]

- [93] 送信者における拡張の出力と、受信者における拡張への入力との間で、
[[フレーム][WebSocketフレーム]]境界が保持される必要があるもの。
- [94] [[フレーム][WebSocketフレーム]]ごとの属性として[F[拡張データ]]や
[CODE[RSV1]], [CODE[RSV2]], [CODE[RSV3]] を用いるもの。


[95] [[サーバー]]は、
[[PMCE]] をすべて declining する場合には、
[[PMCE]] 拡張名を含めては[MUST[なりません]]。 [SRC[>>82]]

[96] [[クライアント]]が offer していない [[PMCE]] が accepting
されているなど不当な[[応答]]を受信した場合には、
[[クライアント]]は[[WebSocket接続失敗]]としなければ[MUST[なりません]]。 [SRC[>>82]]

[100] [[クライアント]]は [[PMCE]] [[extension negotiation response]]
が受け入れられないものである時は、
[[閉じ符号]] [CODE[1010]] の [[closing handshake]] を開始します。 [SRC[>>82]]


[97] [[サーバー]]が妥当な [[PMCE]] の指定を [CODE[Sec-WebSocket-Extensions:]]
[[ヘッダー][HTTPヘッダー]]に含め、
[[WebSocket接続確立]]に至った場合、
[[クライアント]]と[[サーバー]]は
[[agreed parameter]] に従った [[PMCE]]
により、 [[message payload]] の変形 (圧縮・展開) を行わなければ[MUST[なりません]]。
[SRC[>>82]]


* フレーム

[52] [[拡張][WebSocket拡張]]は、次の[[プロトコル要素]]を使うことができます [SRC[>>49]]。

[FIG(list short)[ [79] [[拡張][WebSokcet拡張]]の利用可能な[[プロトコル要素]]
- [F[opcode]] [CODE[[[0x3]]]]-[CODE[[[0x7]]]], [CODE[[[0xB]]]]-[CODE[[[0xF]]]]
- [F[RSV1]]
- [F[RSV2]]
- [F[RSV3]]
- [F[拡張データ]]
]FIG]

** 拡張データ

[103] [[WebSocketフレーム]]には、
[DFN[[RUBYB[拡張データ]@en[extension data]]]]欄があります。
これは[[拡張][WebSocket拡張]]により規定された長さと用途のデータです。
[[拡張][WebSocket拡張]]がなければ長さ [N[0]] です。 [SRC[>>102]]

[13] 現時点で利用例はありません。

** RSV1、RSV2、RSV3

[101] [[WebSocketフレーム]]には、
[DFN[[F[RSV1]]]] ([DFN[[CODE[[[frame-rsv1]]]]]]),
[DFN[[F[RSV2]]]] ([DFN[[CODE[[[frame-rsv2]]]]]]),
[DFN[[F[RSV3]]]] ([DFN[[CODE[[[frame-rsv3]]]]]])
の3つの1ビット欄があります。 [SRC[>>102]]

[108] この3つの欄は、[[拡張][WebSocket拡張]]により規定される場合を除き、 
[N[0]] でなければ[MUST[なりません]]。
受信した[[フレーム][WebSocketフレーム]]のこの3つの欄のいずれかであっても非 [N[0]]
値であり、[[拡張][WebSocket拡張]]の規定に拠っていない場合には、
[[WebSocket接続失敗]]としなければ[MUST[なりません]]。
[SRC[>>102]]

[109] この3つの欄については[[IANA登録簿]]があります [SRC[>>163, >>166]]。
[CODE[permessage-deflate]] における [F[RSV1]] が登録されています。

[104] [[PMCE]] は [F[RSV1]] を 
[DFN[[F[[RUBYB[[[メッセージ毎圧縮]]]@en[Per-Message Compressed]]]]]] ビットと呼んでいます。
[[メッセージ][WebSocketメッセージ]]が[[圧縮]]されているか否かを表します。
[SRC[>>111]]

[120] [[データメッセージ]]の先頭の[[データフレーム]]で[F[メッセージ毎圧縮]]ビットが設定されている場合、
その[[データメッセージ]]の[[payloadデータ]]は圧縮データです。

[119] [[制御フレーム]]や、[[データメッセージ]]の先頭以外の[[データフレーム]]では、
[F[メッセージ毎圧縮]]ビットを設定しては[MUST[なりません]]。
そのような[[フレーム][WebSocketフレーム]]を受信した場合、
[[WebSocket接続失敗]]としなければ[MUST[なりません]]。 [SRC[>>111]]

** PMCE

[110] [[PMCE]] は[[データメッセージ]]にのみ適用されます。 [SRC[>>111]]

[105] 最初の[[フレーム][WebSocketフレーム]]の[F[メッセージ毎圧縮]]ビットの設定された[[メッセージ][WebSocketメッセージ]]を、
[DFN[[RUBYB[圧縮メッセージ]@en[compressed message]]]]といいます。  [SRC[>>111]]

[122] [[圧縮メッセージ]]の[[フレーム][WebSocketフレーム]]の[F[payloadデータ]]は、
圧縮されたデータです。
[F[opcode]] 依存の [F[payloadデータ]]の制約は、展開された状態のデータにのみ適用されます。
[SRC[>>111]]

[EG[
[123] 例えば[[テキストフレーム]]からはじまる [[message payload]] は [[UTF-8]]
データでなければなりません。[[圧縮メッセージ]]では実際に送信される各[[フレーム][WebSocketフレーム]]の[F[payloadデータ]]は
[[UTF-8]] になっているとは限りません (なっていない可能性の方が高いです)。
しかしそれを[[展開]]した結果は [[UTF-8]] となっていなければなりません。
]EG]

[106] 最初の[[フレーム][WebSocketフレーム]]の[F[メッセージ毎圧縮]]ビットの設定されて''いない''[[メッセージ][WebSocketメッセージ]]を、
[DFN[[RUBYB[非圧縮メッセージ]@en[uncompressed message]]]]といいます。  [SRC[>>111]]

[121] [[非圧縮メッセージ]]の[[フレーム][WebSocketフレーム]]の[F[payloadデータ]]は、
圧縮されていないデータです。
[SRC[>>111]]


[107] [[メッセージ][WebSocketメッセージ]]の送信時には、
次のようにしなければ[MUST[なりません]] [SRC[>>111]]。

[FIG(steps)[
= [115] [[圧縮メッセージ]]の場合、
== [112] [VAR[データ]]を、 [[message payload]] に [[PMCE]] の[[圧縮]]を適用した結果に設定します。
== [113] [VAR[データ]]を使って[[フレーム][WebSocketフレーム]](群)を生成します。
== [114] 最初の[[フレーム][WebSocketフレーム]]の[F[メッセージ毎圧縮]]を、 [N[1]]
に設定します。
= [116] [[非圧縮メッセージ]]の場合、
== [117] [VAR[データ]]を、 [[message payload]] に設定します。
== [118] [VAR[データ]]を使って[[フレーム][WebSocketフレーム]](群)を生成します。
]FIG]


[124] [[圧縮メッセージ]]を受信した場合、
次のようにしなければ[MUST[なりません]]。 [SRC[>>111]]

[FIG(steps)[
= [128] [F[メッセージ毎圧縮]]が [N[1]] の場合、
== [125] [VAR[データ]]を、[[圧縮メッセージ]]の[[フレーム][WebSocketフレーム]]の[F[payloadデータ]]を連結したものに設定します。
== [126] [VAR[データ]]を、[VAR[データ]]に [[PMCE]] の[[展開]]を適用した結果に設定します。
== [127] [F[メッセージ毎圧縮]]を、[N[0]] に設定します。
]FIG]


** [CODE[permessage-deflate]]

[130] [[DEFLATE]] を使う場合の拡張名は
[DFN[[CODE[permessage-deflate]]]] です。
次の[[引数]]があります。 
いずれも[[クライアント]]の [[extension negotiation offer]] 
と[[サーバー]]の[[extension negotiation response]] で使用します。
[SRC[>>129]]

[FIG(middle list)[ [131] [CODE[permessage-deflate]] の[[引数]]
- [CODE[server_no_context_takeover]]
- [CODE[client_no_context_takeover]]
- [CODE[server_max_window_bits]]
- [CODE[client_max_window_bits]]
]FIG]

[132] [CODE[client_]] は[[クライアント]]が圧縮し[[サーバー]]が展開する際のもの、
[CODE[server_]] は[[サーバー]]が圧縮し[[クライアント]]が展開する際のものを表します。
[SRC[>>129]]


[133] [[サーバー]]は、
次の''いずれか''を満たす場合、
[[extension negotiation offer]] を decline しなければ[MUST[なりません]]。
[SRC[>>129]]

- [[extension negotiation offer]] に、 offer での利用が定義されていない[[引数]]が含まれる
- [[extension negotiation offer]] に、非妥当な値の[[引数]]が含まれる
- [[extension negotiation offer]] に同名の[[引数]]が複数含まれる
- [[extension negotiation offer]] で指定されたものに対応していない

[134] [[クライアント]]は、
[[extension negotiation offer]] に対する [[extension negotiation response]] 
が次の''いずれか''を満たす場合、
[[WebSocket接続失敗]]としなければ[MUST[なりません]]。 [SRC[>>129]]

- [[extension negotiation response]] に、response での利用が定義されていない[[引数]]が含まれる
- [[extension negotiation response]] に、非妥当な値の[[引数]]が含まれる
- [[extension negotiation response]] に同名の[[引数]]が複数含まれる
- [[extension negotiation response]] で指定されたものに対応していない

* 実装

[74] [[Chrome]] と [[Firefox]] は [CODE[permessage-deflate]] を実装しています。

* 歴史

** 拡張の一覧

[18] 現時点で [[IANA]] に登録されている[[拡張]]はありません。 [TIME[2015-05-16T13:32:07.700Z]]

[48] 2015年9月に [CODE[[[permessage-deflate]]]] が登録されています。

[REFS[
- [49] [CITE@en[RFC 7692 - Compression Extensions for WebSocket]] ([TIME[2015-12-08 10:51:52 +09:00]] 版) <https://tools.ietf.org/html/rfc7692>
]REFS]

[23] [[DEFLATE]] [[圧縮]]のための [DFN[[CODE[[[x-webkit-deflate-frame]]]]]]
が実装されていました [SRC[>>20]]。

[24] その改訂版である [CODE[[[permessage-deflate]]]] [SRC[>>46]]
が実装されています [SRC[>>25, >>22]]。

[EG[
[29] [[Chrome]] は次のような[[ヘッダー]]を送るようです。
[PRE(HTTP code)[
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
]PRE]
]EG]

;; [39] [[Chrome]] は現在は次のような[[ヘッダー]]を送るようです。 [TIME[2015-08-04T13:50:07.700Z]]
[PRE(HTTP code)[
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
]PRE]

;; [40] [[Firefox]] は [CODE(HTTP)@en[Sec-WebSocket-Extensions: permessage-deflate]]
を送るようです。 [TIME[2015-08-08T13:30:24.300Z]]

[REFS[
- [46] [CITE@en[draft-ietf-hybi-permessage-compression-27 - Compression Extensions for WebSocket]] ([TIME[2015-08-07 04:09:59 +09:00]] 版) <https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-27>
- [19] [CITE@en[draft-tyoshino-hybi-permessage-compression-00 - WebSocket Per-message Compression]] ([TIME[2015-04-24 04:35:38 +09:00]] 版) <https://tools.ietf.org/html/draft-tyoshino-hybi-permessage-compression-00>
- [28] [CITE@en[draft-ietf-hybi-permessage-compression-21 - Compression Extensions for WebSocket]] ([TIME[2015-05-16 12:31:55 +09:00]] 版) <https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-21>
- [20] [CITE@en[Bug 77522 – Adding WebSocket per-frame DEFLATE extension]] ([TIME[2015-05-16 23:06:15 +09:00]] 版) <https://bugs.webkit.org/show_bug.cgi?id=77522>
- [21] [CITE@en[Bug 115504 – '''['''WebSocket''']''' Remove x-webkit-deflate-frame extension support]] ([TIME[2015-05-16 23:06:43 +09:00]] 版) <https://bugs.webkit.org/show_bug.cgi?id=115504>
- [25] [CITE[Issue 280910 - chromium - Implement permessage-deflate extension for the new WebSocket implementation - An open-source project to help move the web forward. - Google Project Hosting]] ([TIME[2015-05-16 23:13:31 +09:00]] 版) <https://code.google.com/p/chromium/issues/detail?id=280910>
- [26] [CITE[Intent to Implement: PerMessageDeflate extension on WebSocket - Google Groups]] ([TIME[2015-05-16 23:14:11 +09:00]] 版) <https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/ZboxIILY2fo>
- [27] [CITE[Intent to ship: WebSocket permessage-deflate extension - Google Groups]] ([TIME[2015-05-16 23:14:47 +09:00]] 版) <https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/-B4uhxryIG4>
- [22] [CITE@en[792831 – Implement WebSocket compression extension]] ([TIME[2015-05-16 23:07:17 +09:00]] 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=792831>
- [32] [CITE@en[Web Applications 1.0 r6330  WebSocket: Disallow this controversial extension rather than require it.]]
([TIME[2011-07-28 05:37:00 +09:00]] 版)
<https://html5.org/r/6330>
]REFS]

[31] 他に[[多重化]]のための拡張が提案されていました [SRC[>>30]]。

[REFS[
- [30] [CITE@en[draft-ietf-hybi-websocket-multiplexing-11 - A Multiplexing Extension for WebSockets]] ([TIME[2015-04-24 04:12:04 +09:00]] 版) <https://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-11>
]REFS]

;; [38] >>37 に [[JSON]] 形式の一覧データファイルがあります。
[REFS[
- [37] [CITE@en[data-web-defs/http-frames.txt at master · manakai/data-web-defs]] ([TIME[2015-05-28 00:33:14 +09:00]] 版) <https://github.com/manakai/data-web-defs/blob/master/doc/http-frames.txt>
]REFS]

* メモ

[43] [[拡張]]のせいで不必要にプロトコルが複雑になっている気がしますが...

[41] [CITE[WebSocket permessage-deflate in Chrome with no context takeover - Stack Overflow]]
([TIME[2015-08-22 20:41:42 +09:00]] 版)
<http://stackoverflow.com/questions/22169036/websocket-permessage-deflate-in-chrome-with-no-context-takeover>

[42] [CITE[Intent to Implement: PerMessageDeflate extension on WebSocket - Google グループ]]
([TIME[2015-08-22 20:43:55 +09:00]] 版)
<https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/ZboxIILY2fo>

[44] [CITE[Issue 163882 - chromium - WebSocket permessage-deflate: Improve compress/no-compress decision - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-08-22 20:50:45 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=163882>

[45] [CITE[Re: ''''''[''''''hybi'''''']'''''' Closing the hybi working group]]
([TIME[2014-10-07 09:20:18 +09:00]] 版)
<http://www.ietf.org/mail-archive/web/hybi/current/msg10527.html>

[47] [CITE[''''''[''''''hybi'''''']'''''' Discontinuation of mux standardizaton in favor of WS/HTTP/2.0]]
([TIME[2014-01-21 16:50:12 +09:00]] 版)
<http://www.ietf.org/mail-archive/web/hybi/current/msg10266.html>

[51] [CITE@en[Define permessage-deflate extension and cache-mode for WebSocket · whatwg/fetch@267a8ef]]
([TIME[2016-03-17 00:54:31 +09:00]] 版)
<https://github.com/whatwg/fetch/commit/267a8effeacfe5d641010d1d4f4609f9602cdab6>

[53] [CITE@en[Fix #852: WebSocket has implemented extensions · whatwg/html@78e6d56]]
([TIME[2016-03-29 00:32:27 +09:00]] 版)
<https://github.com/whatwg/html/commit/78e6d56a64eb7d8ed7ee29b93ea37789f249b3ef>

[69] [CITE@en[Bug 485469 – permessage-deflate extension causes protocol error in Firefox/Chrome]]
([TIME[2017-10-03 16:43:17 +09:00]])
<https://bugs.eclipse.org/bugs/show_bug.cgi?id=485469>

[70] [CITE@en[580290 - permessage-deflate implementation does not support RFC7692 Section 7.2.3.6 (empty frame) correctly - chromium - Monorail]]
([TIME[2017-10-03 16:44:00 +09:00]])
<https://bugs.chromium.org/p/chromium/issues/detail?id=580290>

[71] [CITE@en[115504 – '''['''WebSocket''']''' Remove x-webkit-deflate-frame extension support]]
([TIME[2017-10-03 16:44:23 +09:00]])
<https://bugs.webkit.org/show_bug.cgi?id=115504>

[72] [CITE@en[98840 – '''['''WebSocket''']''' Add permessage-compress extension]]
([TIME[2017-10-03 16:45:02 +09:00]])
<https://bugs.webkit.org/show_bug.cgi?id=98840>

[73] [CITE@en[115863 – '''['''WebSocket''']''' Update pywebsocket to r760]]
([TIME[2017-10-03 16:45:49 +09:00]])
<https://bugs.webkit.org/show_bug.cgi?id=115863>