From 09050e24dd91a6799a8f4a80cf7b091730409f49 Mon Sep 17 00:00:00 2001 From: Aleksander Korzynski <59058391+akorzynski@users.noreply.github.com> Date: Mon, 5 Oct 2026 20:01:20 +0200 Subject: [PATCH] Preserve per-connection WebSocket compressor selection The 3 KB compatibility check used a bitwise overlap test. Every dedicated compressor setting shares bits with `DEDICATED_COMPRESSOR_3KB`, so the check silently replaced larger per-connection compressors with the 3 KB setting, which uses a 512-byte window and `memLevel` 1. Mask the configured options with `CompressOptions::_COMPRESSOR_MASK` before comparing them with `DEDICATED_COMPRESSOR_3KB`. This keeps the 3 KB compatibility handling while allowing larger dedicated compressors to use their negotiated settings. Replaying 1,500 recorded stage frames (7.8 MB) produced these compression ratios: DEDICATED_COMPRESSOR_256KB 1.64x before, 7.90x after DEDICATED_COMPRESSOR_8KB 1.64x before, 3.00x after DEDICATED_COMPRESSOR_3KB 1.64x before, 1.64x after SHARED_COMPRESSOR 4.65x before, 4.65x after Every frame decompressed byte-for-byte after the change. Contributed by Spiderware (https://spiderware.gg). --- src/HttpResponse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HttpResponse.h b/src/HttpResponse.h index 9c4b37082..8b46a24fc 100644 --- a/src/HttpResponse.h +++ b/src/HttpResponse.h @@ -314,7 +314,7 @@ struct HttpResponse : public AsyncSocket { /* If we are dedicated and have the 3kb then correct any 4kb to 3kb, * (they both share the windowBits = 9) */ - if (webSocketContextData->compression & DEDICATED_COMPRESSOR_3KB) { + if ((webSocketContextData->compression & CompressOptions::_COMPRESSOR_MASK) == DEDICATED_COMPRESSOR_3KB) { compressOptions = DEDICATED_COMPRESSOR_3KB; } }