From 01d16b3ce8dda09005274d66dea28e0ed65e4603 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Sun, 31 Oct 2021 04:34:39 +0100 Subject: [PATCH] Fix broken compression --- src/HttpResponse.h | 8 +++---- src/PerMessageDeflate.h | 53 ++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/HttpResponse.h b/src/HttpResponse.h index bfbccce..606eaf0 100644 --- a/src/HttpResponse.h +++ b/src/HttpResponse.h @@ -239,11 +239,11 @@ public: /* Make sure to map SHARED_DECOMPRESSOR to windowBits = 0, not 1 */ int wantedInflationWindow = 0; if ((webSocketContextData->compression & CompressOptions::_DECOMPRESSOR_MASK) != CompressOptions::SHARED_DECOMPRESSOR) { - wantedInflationWindow = (webSocketContextData->compression & CompressOptions::_DECOMPRESSOR_MASK) >> 12; + wantedInflationWindow = (webSocketContextData->compression & CompressOptions::_DECOMPRESSOR_MASK) >> 8; } /* Map from selected compressor (this automatically maps SHARED_COMPRESSOR to windowBits 0, not 1) */ - int wantedCompressionWindow = (webSocketContextData->compression & CompressOptions::_COMPRESSOR_MASK) >> 8; + int wantedCompressionWindow = (webSocketContextData->compression & CompressOptions::_COMPRESSOR_MASK) >> 4; auto [negCompression, negCompressionWindow, negInflationWindow, negResponse] = negotiateCompression(true, wantedCompressionWindow, wantedInflationWindow, @@ -256,7 +256,7 @@ public: if (negCompressionWindow == 0) { compressOptions = CompressOptions::SHARED_COMPRESSOR; } else { - compressOptions = (CompressOptions) ((uint32_t) (negCompressionWindow << 8) + compressOptions = (CompressOptions) ((uint32_t) (negCompressionWindow << 4) | (uint32_t) (negCompressionWindow - 7)); /* If we are dedicated and have the 3kb then correct any 4kb to 3kb, @@ -270,7 +270,7 @@ public: if (negInflationWindow == 0) { compressOptions = CompressOptions(compressOptions | CompressOptions::SHARED_DECOMPRESSOR); } else { - compressOptions = CompressOptions(compressOptions | (negInflationWindow << 12)); + compressOptions = CompressOptions(compressOptions | (negInflationWindow << 8)); } writeHeader("Sec-WebSocket-Extensions", negResponse); diff --git a/src/PerMessageDeflate.h b/src/PerMessageDeflate.h index 8ca82d9..70fea17 100644 --- a/src/PerMessageDeflate.h +++ b/src/PerMessageDeflate.h @@ -25,40 +25,40 @@ /* We always define these options no matter if ZLIB is enabled or not */ namespace uWS { - /* Compressor mode is 12 lowest bits where HIGH4(windowBits), LOW8(memLevel). - * Decompressor mode is 4 highest bits (windowBits). + /* Compressor mode is 8 lowest bits where HIGH4(windowBits), LOW4(memLevel). + * Decompressor mode is 8 highest bits LOW4(windowBits). * If compressor or decompressor bits are 1, then they are shared. * If everything is just simply 0, then everything is disabled. */ enum CompressOptions : uint16_t { /* These are not actual compression options */ - _COMPRESSOR_MASK = 0x0FFF, - _DECOMPRESSOR_MASK = 0xF000, + _COMPRESSOR_MASK = 0x00FF, + _DECOMPRESSOR_MASK = 0x0F00, /* Disabled, shared, shared are "special" values */ DISABLED = 0, SHARED_COMPRESSOR = 1, - SHARED_DECOMPRESSOR = 1 << 12, + SHARED_DECOMPRESSOR = 1 << 8, /* Highest 4 bits describe decompressor */ - DEDICATED_DECOMPRESSOR_32KB = 15 << 12, - DEDICATED_DECOMPRESSOR_16KB = 14 << 12, - DEDICATED_DECOMPRESSOR_8KB = 13 << 12, - DEDICATED_DECOMPRESSOR_4KB = 12 << 12, - DEDICATED_DECOMPRESSOR_2KB = 11 << 12, - DEDICATED_DECOMPRESSOR_1KB = 10 << 12, - DEDICATED_DECOMPRESSOR_512B = 9 << 12, + DEDICATED_DECOMPRESSOR_32KB = 15 << 8, + DEDICATED_DECOMPRESSOR_16KB = 14 << 8, + DEDICATED_DECOMPRESSOR_8KB = 13 << 8, + DEDICATED_DECOMPRESSOR_4KB = 12 << 8, + DEDICATED_DECOMPRESSOR_2KB = 11 << 8, + DEDICATED_DECOMPRESSOR_1KB = 10 << 8, + DEDICATED_DECOMPRESSOR_512B = 9 << 8, /* Same as 32kb */ - DEDICATED_DECOMPRESSOR = 15 << 12, + DEDICATED_DECOMPRESSOR = 15 << 8, - /* Lowest 12 bit describe compressor */ - DEDICATED_COMPRESSOR_3KB = 9 << 8 | 1, - DEDICATED_COMPRESSOR_4KB = 9 << 8 | 2, - DEDICATED_COMPRESSOR_8KB = 10 << 8 | 3, - DEDICATED_COMPRESSOR_16KB = 11 << 8 | 4, - DEDICATED_COMPRESSOR_32KB = 12 << 8 | 5, - DEDICATED_COMPRESSOR_64KB = 13 << 8 | 6, - DEDICATED_COMPRESSOR_128KB = 14 << 8 | 7, - DEDICATED_COMPRESSOR_256KB = 15 << 8 | 8, + /* Lowest 8 bit describe compressor */ + DEDICATED_COMPRESSOR_3KB = 9 << 4 | 1, + DEDICATED_COMPRESSOR_4KB = 9 << 4 | 2, + DEDICATED_COMPRESSOR_8KB = 10 << 4 | 3, + DEDICATED_COMPRESSOR_16KB = 11 << 4 | 4, + DEDICATED_COMPRESSOR_32KB = 12 << 4 | 5, + DEDICATED_COMPRESSOR_64KB = 13 << 4 | 6, + DEDICATED_COMPRESSOR_128KB = 14 << 4 | 7, + DEDICATED_COMPRESSOR_256KB = 15 << 4 | 8, /* Same as 256kb */ - DEDICATED_COMPRESSOR = 15 << 8 | 8 + DEDICATED_COMPRESSOR = 15 << 4 | 8 }; } @@ -140,7 +140,7 @@ struct DeflationStream { /* Sliding inflator should be about 44kb by default, less than compressor */ /* Memory usage is given by 2 ^ (windowBits + 2) + 2 ^ (memLevel + 9) */ - int windowBits = -(int) ((compressOptions & 0xFF00) >> 8), memLevel = compressOptions & 0x00FF; + int windowBits = -(int) ((compressOptions & _COMPRESSOR_MASK) >> 4), memLevel = compressOptions & 0xF; //printf("windowBits: %d, memLevel: %d\n", windowBits, memLevel); @@ -216,9 +216,8 @@ struct InflationStream { z_stream inflationStream = {}; InflationStream(CompressOptions compressOptions) { - /* Inflation windowBits are the top 4 bits of the 16 bit compressOptions */ - //printf("%d\n", -(compressOptions >> 12)); - inflateInit2(&inflationStream, -(compressOptions >> 12)); + /* Inflation windowBits are the top 8 bits of the 16 bit compressOptions */ + inflateInit2(&inflationStream, -(compressOptions >> 8)); } ~InflationStream() {