From 5127094f0ef3a5d1ae62b2cbcadf5ae68c4def90 Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Fri, 31 Jul 2020 22:07:20 -0700 Subject: [PATCH] zlib is optional --- .github/workflows/unittest_uwp.yml | 6 ++--- .github/workflows/unittest_windows.yml | 4 +--- CMakeLists.txt | 16 +++++++++---- ixwebsocket/IXHttpClient.cpp | 6 +++++ ixwebsocket/IXHttpClient.h | 2 ++ ixwebsocket/IXHttpServer.cpp | 4 ++++ .../IXWebSocketPerMessageDeflateCodec.cpp | 24 +++++++++++++++++++ .../IXWebSocketPerMessageDeflateCodec.h | 8 +++++++ .../IXWebSocketPerMessageDeflateOptions.cpp | 10 ++++++++ makefile | 2 +- 10 files changed, 71 insertions(+), 11 deletions(-) diff --git a/.github/workflows/unittest_uwp.yml b/.github/workflows/unittest_uwp.yml index 4766d1ba..a890f19f 100644 --- a/.github/workflows/unittest_uwp.yml +++ b/.github/workflows/unittest_uwp.yml @@ -10,13 +10,13 @@ jobs: steps: - uses: actions/checkout@v1 - uses: seanmiddleditch/gha-setup-vsdevenv@master - - run: | - vcpkg install zlib:x64-uwp - run: | mkdir build cd build - cmake -DCMAKE_TOOLCHAIN_FILE=c:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0" -DCMAKE_CXX_COMPILER=cl.exe -DUSE_TEST=1 .. + cmake -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0" -DCMAKE_CXX_COMPILER=cl.exe -DUSE_TEST=1 -DUSE_ZLIB=0 .. - run: cmake --build build + #- run: ../build/test/ixwebsocket_unittest.exe + #working-directory: test # # Windows with OpenSSL is working but disabled as it takes 13 minutes (10 for openssl) to build with vcpkg diff --git a/.github/workflows/unittest_windows.yml b/.github/workflows/unittest_windows.yml index ccd2e639..f1ed0f8b 100644 --- a/.github/workflows/unittest_windows.yml +++ b/.github/workflows/unittest_windows.yml @@ -10,10 +10,8 @@ jobs: steps: - uses: actions/checkout@v1 - uses: seanmiddleditch/gha-setup-vsdevenv@master - - run: | - vcpkg install zlib:x64-windows - run: | mkdir build cd build - cmake -DCMAKE_TOOLCHAIN_FILE=c:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_CXX_COMPILER=cl.exe -DUSE_WS=1 -DUSE_TEST=1 .. + cmake -DCMAKE_CXX_COMPILER=cl.exe -DUSE_WS=1 -DUSE_TEST=1 -DUSE_ZLIB=0 .. - run: cmake --build build diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bb567b6..782b1d47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,10 +190,18 @@ if (USE_TLS) endif() endif() -# Use ZLIB_ROOT CMake variable if you need to use your own zlib -find_package(ZLIB REQUIRED) -include_directories(${ZLIB_INCLUDE_DIRS}) -target_link_libraries(ixwebsocket ${ZLIB_LIBRARIES}) +option(USE_ZLIB "Enable zlib support" TRUE) + +if (USE_ZLIB) + # Use ZLIB_ROOT CMake variable if you need to use your own zlib + find_package(ZLIB) + if (ZLIB_FOUND) + include_directories(${ZLIB_INCLUDE_DIRS}) + target_link_libraries(ixwebsocket ${ZLIB_LIBRARIES}) + + target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_ZLIB) + endif() +endif() if (WIN32) target_link_libraries(ixwebsocket wsock32 ws2_32 shlwapi) diff --git a/ixwebsocket/IXHttpClient.cpp b/ixwebsocket/IXHttpClient.cpp index 49da10da..5ff137e7 100644 --- a/ixwebsocket/IXHttpClient.cpp +++ b/ixwebsocket/IXHttpClient.cpp @@ -174,11 +174,13 @@ namespace ix ss << verb << " " << path << " HTTP/1.1\r\n"; ss << "Host: " << host << "\r\n"; +#ifdef IXWEBSOCKET_USE_ZLIB if (args->compress) { ss << "Accept-Encoding: gzip" << "\r\n"; } +#endif // Append extra headers for (auto&& it : args->extraHeaders) @@ -495,6 +497,7 @@ namespace ix downloadSize = payload.size(); +#ifdef IXWEBSOCKET_USE_ZLIB // If the content was compressed with gzip, decode it if (headers["Content-Encoding"] == "gzip") { @@ -513,6 +516,7 @@ namespace ix } payload = decompressedPayload; } +#endif return std::make_shared(code, description, @@ -672,6 +676,7 @@ namespace ix return ss.str(); } +#ifdef IXWEBSOCKET_USE_ZLIB bool HttpClient::gzipInflate(const std::string& in, std::string& out) { z_stream inflateState; @@ -716,6 +721,7 @@ namespace ix inflateEnd(&inflateState); return true; } +#endif void HttpClient::log(const std::string& msg, HttpRequestArgsPtr args) { diff --git a/ixwebsocket/IXHttpClient.h b/ixwebsocket/IXHttpClient.h index 97727e6e..9e585e7d 100644 --- a/ixwebsocket/IXHttpClient.h +++ b/ixwebsocket/IXHttpClient.h @@ -90,7 +90,9 @@ namespace ix private: void log(const std::string& msg, HttpRequestArgsPtr args); +#ifdef IXWEBSOCKET_USE_ZLIB bool gzipInflate(const std::string& in, std::string& out); +#endif // Async API background thread runner void run(); diff --git a/ixwebsocket/IXHttpServer.cpp b/ixwebsocket/IXHttpServer.cpp index 4d544f71..09ceb668 100644 --- a/ixwebsocket/IXHttpServer.cpp +++ b/ixwebsocket/IXHttpServer.cpp @@ -41,6 +41,7 @@ namespace return std::make_pair(res.first, std::string(vec.begin(), vec.end())); } +#ifdef IXWEBSOCKET_USE_ZLIB std::string gzipCompress(const std::string& str) { z_stream zs; // z_stream is zlib's control structure @@ -83,6 +84,7 @@ namespace return outstring; } +#endif } // namespace namespace ix @@ -168,12 +170,14 @@ namespace ix std::string content = res.second; +#ifdef IXWEBSOCKET_USE_ZLIB std::string acceptEncoding = request->headers["Accept-encoding"]; if (acceptEncoding == "*" || acceptEncoding.find("gzip") != std::string::npos) { content = gzipCompress(content); headers["Content-Encoding"] = "gzip"; } +#endif // Log request std::stringstream ss; diff --git a/ixwebsocket/IXWebSocketPerMessageDeflateCodec.cpp b/ixwebsocket/IXWebSocketPerMessageDeflateCodec.cpp index fb02e755..913b9a04 100644 --- a/ixwebsocket/IXWebSocketPerMessageDeflateCodec.cpp +++ b/ixwebsocket/IXWebSocketPerMessageDeflateCodec.cpp @@ -28,21 +28,26 @@ namespace ix WebSocketPerMessageDeflateCompressor::WebSocketPerMessageDeflateCompressor() : _compressBufferSize(kBufferSize) { +#ifdef IXWEBSOCKET_USE_ZLIB memset(&_deflateState, 0, sizeof(_deflateState)); _deflateState.zalloc = Z_NULL; _deflateState.zfree = Z_NULL; _deflateState.opaque = Z_NULL; +#endif } WebSocketPerMessageDeflateCompressor::~WebSocketPerMessageDeflateCompressor() { +#ifdef IXWEBSOCKET_USE_ZLIB deflateEnd(&_deflateState); +#endif } bool WebSocketPerMessageDeflateCompressor::init(uint8_t deflateBits, bool clientNoContextTakeOver) { +#ifdef IXWEBSOCKET_USE_ZLIB int ret = deflateInit2(&_deflateState, Z_DEFAULT_COMPRESSION, Z_DEFLATED, @@ -57,6 +62,9 @@ namespace ix _flush = (clientNoContextTakeOver) ? Z_FULL_FLUSH : Z_SYNC_FLUSH; return true; +#else + return false; +#endif } template @@ -96,6 +104,7 @@ namespace ix template bool WebSocketPerMessageDeflateCompressor::compressData(const T& in, S& out) { +#ifdef IXWEBSOCKET_USE_ZLIB // // 7.2.1. Compression // @@ -152,6 +161,9 @@ namespace ix } return true; +#else + return false; +#endif } // @@ -160,6 +172,7 @@ namespace ix WebSocketPerMessageDeflateDecompressor::WebSocketPerMessageDeflateDecompressor() : _compressBufferSize(kBufferSize) { +#ifdef IXWEBSOCKET_USE_ZLIB memset(&_inflateState, 0, sizeof(_inflateState)); _inflateState.zalloc = Z_NULL; @@ -167,16 +180,20 @@ namespace ix _inflateState.opaque = Z_NULL; _inflateState.avail_in = 0; _inflateState.next_in = Z_NULL; +#endif } WebSocketPerMessageDeflateDecompressor::~WebSocketPerMessageDeflateDecompressor() { +#ifdef IXWEBSOCKET_USE_ZLIB inflateEnd(&_inflateState); +#endif } bool WebSocketPerMessageDeflateDecompressor::init(uint8_t inflateBits, bool clientNoContextTakeOver) { +#ifdef IXWEBSOCKET_USE_ZLIB int ret = inflateInit2(&_inflateState, -1 * inflateBits); if (ret != Z_OK) return false; @@ -186,10 +203,14 @@ namespace ix _flush = (clientNoContextTakeOver) ? Z_FULL_FLUSH : Z_SYNC_FLUSH; return true; +#else + return false; +#endif } bool WebSocketPerMessageDeflateDecompressor::decompress(const std::string& in, std::string& out) { +#ifdef IXWEBSOCKET_USE_ZLIB // // 7.2.2. Decompression // @@ -226,5 +247,8 @@ namespace ix } while (_inflateState.avail_out == 0); return true; +#else + return false; +#endif } } // namespace ix diff --git a/ixwebsocket/IXWebSocketPerMessageDeflateCodec.h b/ixwebsocket/IXWebSocketPerMessageDeflateCodec.h index 476d3c79..89673f48 100644 --- a/ixwebsocket/IXWebSocketPerMessageDeflateCodec.h +++ b/ixwebsocket/IXWebSocketPerMessageDeflateCodec.h @@ -6,7 +6,9 @@ #pragma once +#ifdef IXWEBSOCKET_USE_ZLIB #include "zlib.h" +#endif #include #include #include @@ -34,7 +36,10 @@ namespace ix int _flush; size_t _compressBufferSize; std::unique_ptr _compressBuffer; + +#ifdef IXWEBSOCKET_USE_ZLIB z_stream _deflateState; +#endif }; class WebSocketPerMessageDeflateDecompressor @@ -50,7 +55,10 @@ namespace ix int _flush; size_t _compressBufferSize; std::unique_ptr _compressBuffer; + +#ifdef IXWEBSOCKET_USE_ZLIB z_stream _inflateState; +#endif }; } // namespace ix diff --git a/ixwebsocket/IXWebSocketPerMessageDeflateOptions.cpp b/ixwebsocket/IXWebSocketPerMessageDeflateOptions.cpp index da81693a..259ddcba 100644 --- a/ixwebsocket/IXWebSocketPerMessageDeflateOptions.cpp +++ b/ixwebsocket/IXWebSocketPerMessageDeflateOptions.cpp @@ -61,6 +61,7 @@ namespace ix _clientMaxWindowBits = kDefaultClientMaxWindowBits; _serverMaxWindowBits = kDefaultServerMaxWindowBits; +#ifdef IXWEBSOCKET_USE_ZLIB // Split by ; std::string token; std::stringstream tokenStream(extension); @@ -112,6 +113,7 @@ namespace ix sanitizeClientMaxWindowBits(); } } +#endif } void WebSocketPerMessageDeflateOptions::sanitizeClientMaxWindowBits() @@ -126,6 +128,7 @@ namespace ix std::string WebSocketPerMessageDeflateOptions::generateHeader() { +#ifdef IXWEBSOCKET_USE_ZLIB std::stringstream ss; ss << "Sec-WebSocket-Extensions: permessage-deflate"; @@ -138,11 +141,18 @@ namespace ix ss << "\r\n"; return ss.str(); +#else + return std::string(); +#endif } bool WebSocketPerMessageDeflateOptions::enabled() const { +#ifdef IXWEBSOCKET_USE_ZLIB return _enabled; +#else + return false; +#endif } bool WebSocketPerMessageDeflateOptions::getClientNoContextTakeover() const diff --git a/makefile b/makefile index 44e2e695..c3d9e282 100644 --- a/makefile +++ b/makefile @@ -34,7 +34,7 @@ ws: mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 .. && ninja install) ws_install: - mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 .. && make -j 4 install) + mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_ZLIB=0 -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 .. && ninja install) ws_openssl: mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 -DUSE_OPEN_SSL=1 .. ; make -j 4)