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
{{ message }}
Repository navigation
PerMessageDeflateExtension *_no_context_takeover negotiation is faulty, leading to mismatch #1496
Describe the bug
The PerMessageDeflateExtension#getProvidedExtensionAsClient() method unconditionally includes client_no_context_takeover and server_no_context_takeover in the extensions to send to the server, ignoring the clientNoContextTakeover and serverNoContextTakeover configuration variables.
The acceptProvidedExtensionAsServer() on the server will thus ALWAYS set its clientNoContextTakeover variable to true, but the acceptProvidedExtensionAsClient() does NOT update its clientNoContextTakeover configuration variable upon receiving this, leading to a mismatch.
As a result, the second compressed response the client receives from the server yields an exception:
org.java_websocket.exceptions.InvalidDataException: invalid distance too far back
at org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension.decodeFrame(PerMessageDeflateExtension.java:193)
at org.java_websocket.drafts.Draft_6455.translateSingleFrame(Draft_6455.java:589)
To Reproduce
Steps to reproduce the behavior:
Set up WebSocketClient and WebSocketServer with the PerMessageDelateExtension
Connect them
Send messages back and forth
The client side will bail out at the second message it receives from the server
getProvidedExtensionsAsClient() must add the extensions following the clientNoContextTakeover and serverNoContextTakeover configuration variables (i.e. leave them out if false).
acceptProvidedExtensionsAsServer() must enable the clientNoContextTakeover and/or serverNoContextTakeover if their corresponding extensions are received, effectively ORing them with the locally configured settings.
getProviderExtensionsAsServer() must add the extensions following the (potentially updated) clientNoContextTakeover and serverNoContextTakeover configuration variables (i.e. leave them out if false).
acceptProvidedExtensionsAsClient() must enable the clientNoContextTakeover and/or serverNoContextTakeover if their corresponding extensions are received, effectively ORing them with the locally configured settings.
This ensures these configuration settings are always properly synchronized on both ends, and allows operation with context takeover on both ends (both configuration variables set to false on both ends), which maximizes the compression efficiency.
The logic to reset the deflater and inflater is also bugged: You cannot directly infer which to reset by the two configuration variables. Instead, it is swapped on client and server. So if one no_context_takeover is set, it must cause one side to reset the inflater, and the other to reset the deflater.
Right now both sides will reset the same of these two for one of these variables, that's why it blows up in case both are not the same. I.e. the code works for true/true and false/false, but not for true/false or false/true combinations of clientNoContextTakeover and serverNoContextTakeover.
I have submitted PR #1497 to fix this. Note that the last verifier run failed, presumably because the server ran out of sockets. Unfortunately, I cannot find a button to rerun the verifier.
It appears this extension has even more issues, such as not keeping track of whether the current message is to be compressed/decompressed (it might choose not to compress the first fragment, and then start compressing further fragments, which is not allowed). It also does not produce/handle all examples from RFC 7692 chapter 7.2.3 correctly. And the "rogue" inflater reset in line 181 (with the bogus "most likely" explanation) also breaks the context takeover, as it erases the context.
The above PR fixes the worst bug, but there are many more. I'd advise not to use this extension in this state.
I have submitted a new PR #1498, which adds a complete reimplementation of the RFC 7962 extension, written for full compliance with the RFC as well as full API compatibility with the existing extension. The new PR supersedes the old PR #1497.
Activity
robert-s-ubi commentedon Dec 19, 2025
The logic to reset the deflater and inflater is also bugged: You cannot directly infer which to reset by the two configuration variables. Instead, it is swapped on client and server. So if one no_context_takeover is set, it must cause one side to reset the inflater, and the other to reset the deflater.
Right now both sides will reset the same of these two for one of these variables, that's why it blows up in case both are not the same. I.e. the code works for true/true and false/false, but not for true/false or false/true combinations of clientNoContextTakeover and serverNoContextTakeover.
Fix Per-Message Compression Extension support
robert-s-ubi commentedon Dec 19, 2025
I have submitted PR #1497 to fix this. Note that the last verifier run failed, presumably because the server ran out of sockets. Unfortunately, I cannot find a button to rerun the verifier.
robert-s-ubi commentedon Dec 23, 2025
It appears this extension has even more issues, such as not keeping track of whether the current message is to be compressed/decompressed (it might choose not to compress the first fragment, and then start compressing further fragments, which is not allowed). It also does not produce/handle all examples from RFC 7692 chapter 7.2.3 correctly. And the "rogue" inflater reset in line 181 (with the bogus "most likely" explanation) also breaks the context takeover, as it erases the context.
The above PR fixes the worst bug, but there are many more. I'd advise not to use this extension in this state.
robert-s-ubi commentedon Dec 25, 2025
I have submitted a new PR #1498, which adds a complete reimplementation of the RFC 7962 extension, written for full compliance with the RFC as well as full API compatibility with the existing extension. The new PR supersedes the old PR #1497.
marci4 commentedon Jan 13, 2026
Fixed #1498