diff --git a/.github/workflows/unittest_uwp.yml b/.github/workflows/unittest_uwp.yml index 4766d1ba..d37763c0 100644 --- a/.github/workflows/unittest_uwp.yml +++ b/.github/workflows/unittest_uwp.yml @@ -10,12 +10,10 @@ 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_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 -DUSE_ZLIB=0 .. - run: cmake --build build # diff --git a/.github/workflows/unittest_windows.yml b/.github/workflows/unittest_windows.yml index ccd2e639..4fe63e6c 100644 --- a/.github/workflows/unittest_windows.yml +++ b/.github/workflows/unittest_windows.yml @@ -10,10 +10,11 @@ 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 + +#- run: ../build/test/ixwebsocket_unittest.exe +# working-directory: test diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bb567b6..4760ca77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,10 +190,16 @@ 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 REQUIRED) + include_directories(${ZLIB_INCLUDE_DIRS}) + target_link_libraries(ixwebsocket ${ZLIB_LIBRARIES}) + + target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_ZLIB) +endif() if (WIN32) target_link_libraries(ixwebsocket wsock32 ws2_32 shlwapi) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 7597cba1..a9873fca 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All changes to this project will be documented in this file. +## [10.1.2] - 2020-07-31 + +(build) make using zlib optional, with the caveat that some http and websocket features are not available when zlib is absent + ## [10.1.1] - 2020-07-29 (websocket client) onProgressCallback not called for short messages on a websocket (fix #233) diff --git a/docs/build.md b/docs/build.md index 00e5895d..0c32b899 100644 --- a/docs/build.md +++ b/docs/build.md @@ -17,6 +17,7 @@ There is a unittest which can be executed by typing `make test`. Options for building: +* `-DUSE_ZLIB=1` will enable zlib support, required for http client + server + websocket per message deflate extension * `-DUSE_TLS=1` will enable TLS support * `-DUSE_OPEN_SSL=1` will use [openssl](https://www.openssl.org/) for the TLS support (default on Linux and Windows) * `-DUSE_MBED_TLS=1` will use [mbedlts](https://tls.mbed.org/) for the TLS support diff --git a/ixwebsocket/IXHttpClient.cpp b/ixwebsocket/IXHttpClient.cpp index 49da10da..d34eeed3 100644 --- a/ixwebsocket/IXHttpClient.cpp +++ b/ixwebsocket/IXHttpClient.cpp @@ -16,7 +16,10 @@ #include #include #include + +#ifdef IXWEBSOCKET_USE_ZLIB #include +#endif namespace ix { @@ -174,11 +177,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 +500,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 +519,7 @@ namespace ix } payload = decompressedPayload; } +#endif return std::make_shared(code, description, @@ -672,6 +679,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 +724,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..08fc3a4c 100644 --- a/ixwebsocket/IXHttpServer.cpp +++ b/ixwebsocket/IXHttpServer.cpp @@ -13,7 +13,10 @@ #include #include #include + +#ifdef IXWEBSOCKET_USE_ZLIB #include +#endif namespace { @@ -41,6 +44,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 +87,7 @@ namespace return outstring; } +#endif } // namespace namespace ix @@ -168,12 +173,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/IXUserAgent.cpp b/ixwebsocket/IXUserAgent.cpp index 85fb9992..89dcb0f3 100644 --- a/ixwebsocket/IXUserAgent.cpp +++ b/ixwebsocket/IXUserAgent.cpp @@ -8,7 +8,9 @@ #include "IXWebSocketVersion.h" #include +#ifdef IXWEBSOCKET_USE_ZLIB #include +#endif // Platform name #if defined(_WIN32) @@ -77,8 +79,10 @@ namespace ix ss << " nossl"; #endif +#ifdef IXWEBSOCKET_USE_ZLIB // Zlib version ss << " zlib " << ZLIB_VERSION; +#endif return ss.str(); } 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/ixwebsocket/IXWebSocketVersion.h b/ixwebsocket/IXWebSocketVersion.h index d704a633..a2b86a11 100644 --- a/ixwebsocket/IXWebSocketVersion.h +++ b/ixwebsocket/IXWebSocketVersion.h @@ -6,4 +6,4 @@ #pragma once -#define IX_WEBSOCKET_VERSION "10.1.1" +#define IX_WEBSOCKET_VERSION "10.1.2"