What is the Sec-WebSocket-Extensions header?
The Sec-WebSocket-Extensions header negotiates protocol-level extensions for a WebSocket connection, as defined in RFC 6455 Section 9.1. Unlike a subprotocol, which gives meaning to messages, an extension changes the framing or the payload itself, for example by compressing it.
The client offers extensions in order of preference, each a registered token with optional ;-separated parameters:
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bitsThe server accepts by echoing the extensions it will use, which MUST be drawn from the client’s offer, with parameters as each extension defines. The list in the server’s response is what is actually in use, and its order is the order the extensions are applied to the data. A client offering an extension MUST NOT use it unless the server accepts it, and MUST fail the connection if the server names one it did not offer.
In a request the header may appear more than once, which is the same as one combined list. In a response it MUST NOT appear more than once.
API Usage & Best Practices
permessage-deflateis the one that matters. Defined in RFC 7692, it compresses each message with DEFLATE. Its four parameters,server_no_context_takeover,client_no_context_takeover,server_max_window_bitsandclient_max_window_bits, trade compression ratio for memory per connection. Browsers offer it by default; the WHATWG WebSockets standard has them send apermessage-deflateoffer on every connection.- Bound the memory before you enable it. Each connection with context takeover keeps a compression window in memory for its lifetime. On a server holding many idle connections, accept with
server_no_context_takeoveror a smallerserver_max_window_bitsand measure before you accept the default. - Think about secrets in compressed messages. Compression applied to a message that mixes attacker-influenced data with a secret can leak the secret through message sizes, the same class of attack as CRIME, which RFC 7692’s security considerations cite. Do not compress messages that carry tokens next to user-controlled content.
- Never accept an extension you were not offered. The client will fail the connection, and it is a protocol violation besides.
- Unknown offers are not an error. A server that does not support an offered extension simply leaves it out of the response. Do not reject the handshake because of it.
- It works the same over HTTP/2. RFC 8441 carries
Sec-WebSocket-Extensionsin the extendedCONNECTrequest and response, and its own example offerspermessage-deflate.
Examples
A client offering permessage-deflate twice, with a fallback, from RFC 7692 Section 7.1.3:
GET /chat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Sec-WebSocket-Version: 13Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits; server_max_window_bits=10, permessage-deflate; client_max_window_bitsThe server accepting the first offer:
HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=10