diff --git a/DOCKER_VERSION b/DOCKER_VERSION index cbad66a0..d4bda08b 100644 --- a/DOCKER_VERSION +++ b/DOCKER_VERSION @@ -1 +1 @@ -5.1.7 +5.1.8 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 870b595c..0f91fc9e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to this project will be documented in this file. +## [5.1.8] - 2019-09-03 + +- Per message deflate/compression: handle fragmented messages (fix autobahn test: 12.1.X and probably others) + ## [5.1.7] - 2019-09-03 - Receiving invalid UTF-8 TEXT message should fail and close the connection (fix remaining autobahn test: 6.X UTF-8 Handling) diff --git a/ixwebsocket/IXWebSocketTransport.cpp b/ixwebsocket/IXWebSocketTransport.cpp index f2576861..0a0bc152 100644 --- a/ixwebsocket/IXWebSocketTransport.cpp +++ b/ixwebsocket/IXWebSocketTransport.cpp @@ -77,6 +77,7 @@ namespace ix WebSocketTransport::WebSocketTransport() : _useMask(true), + _compressedMessage(false), _readyState(ReadyState::CLOSED), _closeCode(WebSocketCloseConstants::kInternalErrorCode), _closeReason(WebSocketCloseConstants::kInternalErrorMessage), @@ -576,6 +577,8 @@ namespace ix ? MessageKind::MSG_TEXT : MessageKind::MSG_BINARY; + _compressedMessage = _enablePerMessageDeflate && ws.rsv1; + // Continuation message needs to follow a non-fin TEXT or BINARY message if (!_chunks.empty()) { @@ -597,8 +600,10 @@ namespace ix { emitMessage(_fragmentedMessageKind, frameData, - ws, + _compressedMessage, onMessageCallback); + + _compressedMessage = false; } else { @@ -614,12 +619,14 @@ namespace ix if (ws.fin) { emitMessage(_fragmentedMessageKind, getMergedChunks(), - ws, onMessageCallback); + _compressedMessage, onMessageCallback); + _chunks.clear(); + _compressedMessage = false; } else { - emitMessage(MessageKind::FRAGMENT, std::string(), ws, onMessageCallback); + emitMessage(MessageKind::FRAGMENT, std::string(), false, onMessageCallback); } } } @@ -641,14 +648,14 @@ namespace ix sendData(wsheader_type::PONG, frameData, compress); } - emitMessage(MessageKind::PING, frameData, ws, onMessageCallback); + emitMessage(MessageKind::PING, frameData, false, onMessageCallback); } else if (ws.opcode == wsheader_type::PONG) { std::lock_guard lck(_lastReceivePongTimePointMutex); _lastReceivePongTimePoint = std::chrono::steady_clock::now(); - emitMessage(MessageKind::PONG, frameData, ws, onMessageCallback); + emitMessage(MessageKind::PONG, frameData, false, onMessageCallback); } else if (ws.opcode == wsheader_type::CLOSE) { @@ -779,13 +786,13 @@ namespace ix void WebSocketTransport::emitMessage(MessageKind messageKind, const std::string& message, - const wsheader_type& ws, + bool compressedMessage, const OnMessageCallback& onMessageCallback) { size_t wireSize = message.size(); // When the RSV1 bit is 1 it means the message is compressed - if (_enablePerMessageDeflate && ws.rsv1 && messageKind != MessageKind::FRAGMENT) + if (compressedMessage && messageKind != MessageKind::FRAGMENT) { std::string decompressedMessage; bool success = _perMessageDeflate.decompress(message, decompressedMessage); diff --git a/ixwebsocket/IXWebSocketTransport.h b/ixwebsocket/IXWebSocketTransport.h index 54546a7d..3d4cc7a2 100644 --- a/ixwebsocket/IXWebSocketTransport.h +++ b/ixwebsocket/IXWebSocketTransport.h @@ -156,6 +156,9 @@ namespace ix // CONTINUATION opcode and doesn't tell the full message kind MessageKind _fragmentedMessageKind; + // Ditto for whether a message is compressed + bool _compressedMessage; + // Fragments are 32K long static constexpr size_t kChunkSize = 1 << 15; @@ -244,7 +247,7 @@ namespace ix void emitMessage(MessageKind messageKind, const std::string& message, - const wsheader_type& ws, + bool compressedMessage, const OnMessageCallback& onMessageCallback); bool isSendBufferEmpty() const; diff --git a/ixwebsocket/IXWebSocketVersion.h b/ixwebsocket/IXWebSocketVersion.h index 184c6fe6..0f6b5f78 100644 --- a/ixwebsocket/IXWebSocketVersion.h +++ b/ixwebsocket/IXWebSocketVersion.h @@ -6,4 +6,4 @@ #pragma once -#define IX_WEBSOCKET_VERSION "5.1.7" +#define IX_WEBSOCKET_VERSION "5.1.8"