You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* permessage-deflate: implement context takeover
* Use negative windowBits values for the deflater
The compression format of the output produced by zlibs deflater is decided
by the windowBits values it is configured with. We used positive windowBits
values which, according to the zlib manual, emits the zlib stream starting
with a zlib header. WebSockets use raw deflate streams, and not zlib streams.
Consequently, we had to strip the zlib header.
The deflater can be configured to emit a raw deflate format by using negative
values for the windowBits. With this in place, there's no zlib header in the
output stream.
* Handle the special case of LZ77 window size of 256
The server_max_window_bits value sent by the client in the negotiation
offer is used to configure the deflater on the server. This acceptance
is also notified to the client by returning the server_max_window_bits
header in the negotiation response.
A special case arises when we receive server_max_window_bits = 8.
There's an open zlib issue with the window size of 256 (windoBits=8).
For zlib streams, the library silently changes the windowBits to 9 and
informs the inflater via the zlib header. However, this apparent hack
is not feasible for raw deflate streams, which are used in WebSockets.
To take care of this fact, zlib has been patched to reject a window
size of 256, via a deflateInit2() failure.
Details here: madler/zlib#171
As a result, we need to handle a window size of 256 (windowBits=8) as a
special case. We silently change it to 9 and inform the client via a
suitable header in the negotiation response.
* Close deflater and inflater streams on connection close
Without context takeover, the deflater and inflater are initialized and closed
on every message. However, with context takeover, the deflater and inflater
persist for the entire lifetime of the connection. They need to be closed on a
connection close.
The deflater is on a ChannelOutboundHandler and must be closed when the
WebSocketConnections issues a channel.close(). The inflater is on a
ChannelInboundHandler, it must be closed when we receive a `closeConnection`
frame from the remote peer.
0 commit comments