From a817ed0bdd278a446faf8df06a200f4097eca68c Mon Sep 17 00:00:00 2001 From: "Mikkel K. Andersen" Date: Thu, 16 Jul 2026 15:39:10 +0200 Subject: [PATCH] Allow disabling client_max_window_bits/server_max_window_bits in the deflate offer permessage-deflate always appended "; server_max_window_bits=15; client_max_window_bits=15" to the handshake header. 15 is the RFC 7692 default window size, so those parameters convey nothing, and some servers and gateways reject a client offer that carries them. Add a sendClientServerMaxWindowBits flag on WebSocketPerMessageDeflateOptions (default true, so existing behavior is unchanged) that gates emitting the two parameters. Set it to false to send a bare "permessage-deflate" offer. Also initialize the flag in the header-parsing constructor, which previously left it unset. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../IXWebSocketPerMessageDeflateOptions.cpp | 17 ++++++++++++++--- .../IXWebSocketPerMessageDeflateOptions.h | 5 ++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/ixwebsocket/IXWebSocketPerMessageDeflateOptions.cpp b/ixwebsocket/IXWebSocketPerMessageDeflateOptions.cpp index b583bac3..285588d6 100644 --- a/ixwebsocket/IXWebSocketPerMessageDeflateOptions.cpp +++ b/ixwebsocket/IXWebSocketPerMessageDeflateOptions.cpp @@ -27,13 +27,15 @@ namespace ix bool clientNoContextTakeover, bool serverNoContextTakeover, uint8_t clientMaxWindowBits, - uint8_t serverMaxWindowBits) + uint8_t serverMaxWindowBits, + bool sendClientServerMaxWindowBits) { _enabled = enabled; _clientNoContextTakeover = clientNoContextTakeover; _serverNoContextTakeover = serverNoContextTakeover; _clientMaxWindowBits = clientMaxWindowBits; _serverMaxWindowBits = serverMaxWindowBits; + _sendClientServerMaxWindowBits = sendClientServerMaxWindowBits; sanitizeClientMaxWindowBits(); } @@ -59,6 +61,7 @@ namespace ix _enabled = false; _clientNoContextTakeover = false; _serverNoContextTakeover = false; + _sendClientServerMaxWindowBits = true; _clientMaxWindowBits = kDefaultClientMaxWindowBits; _serverMaxWindowBits = kDefaultServerMaxWindowBits; @@ -128,8 +131,11 @@ namespace ix if (_clientNoContextTakeover) ss << "; client_no_context_takeover"; if (_serverNoContextTakeover) ss << "; server_no_context_takeover"; - ss << "; server_max_window_bits=" << static_cast(_serverMaxWindowBits); - ss << "; client_max_window_bits=" << static_cast(_clientMaxWindowBits); + if (_sendClientServerMaxWindowBits) + { + ss << "; server_max_window_bits=" << static_cast(_serverMaxWindowBits); + ss << "; client_max_window_bits=" << static_cast(_clientMaxWindowBits); + } ss << "\r\n"; @@ -168,6 +174,11 @@ namespace ix return _serverMaxWindowBits; } + bool WebSocketPerMessageDeflateOptions::getSendClientServerMaxWindowBits() const + { + return _sendClientServerMaxWindowBits; + } + bool WebSocketPerMessageDeflateOptions::startsWith(const std::string& str, const std::string& start) { diff --git a/ixwebsocket/IXWebSocketPerMessageDeflateOptions.h b/ixwebsocket/IXWebSocketPerMessageDeflateOptions.h index 95751b61..0650bbc7 100644 --- a/ixwebsocket/IXWebSocketPerMessageDeflateOptions.h +++ b/ixwebsocket/IXWebSocketPerMessageDeflateOptions.h @@ -19,7 +19,8 @@ namespace ix bool clientNoContextTakeover = false, bool serverNoContextTakeover = false, uint8_t clientMaxWindowBits = kDefaultClientMaxWindowBits, - uint8_t serverMaxWindowBits = kDefaultServerMaxWindowBits); + uint8_t serverMaxWindowBits = kDefaultServerMaxWindowBits, + bool sendClientServerMaxWindowBits = true); WebSocketPerMessageDeflateOptions(std::string extension); @@ -29,6 +30,7 @@ namespace ix bool getServerNoContextTakeover() const; uint8_t getServerMaxWindowBits() const; uint8_t getClientMaxWindowBits() const; + bool getSendClientServerMaxWindowBits() const; static bool startsWith(const std::string& str, const std::string& start); static std::string removeSpaces(const std::string& str); @@ -40,6 +42,7 @@ namespace ix bool _enabled; bool _clientNoContextTakeover; bool _serverNoContextTakeover; + bool _sendClientServerMaxWindowBits; uint8_t _clientMaxWindowBits; uint8_t _serverMaxWindowBits;