From a2f5eb9cf095a8d942d9518a2ef5848cd47ce8f1 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 28 Jan 2025 16:09:48 +0100 Subject: [PATCH] [WS] Fix wslay multi-frame message parsing (again) We incorrectly assumed that the `payload_length` in the recv start callback of wslay was the final message size, but according to the WebSocket protocol, the payload length always refers to the current frame's payload size. The protocol, in fact, do not include a "message payload" length on purpose to allow sending messages of unknown size without forcing the sender to buffer the whole message (RFC6455 Section 5.4). This means a receiving peer has no way to know beforehand how long a message will be, and needs instead to keep track of the length of each frame until the FIN one is received to properly reconstruct the message at the end. --- modules/websocket/wsl_peer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index f50b4c48065..1a1f52a8a06 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -598,7 +598,6 @@ void WSLPeer::_wsl_recv_start_callback(wslay_event_context_ptr ctx, const struct // Get ready to process a data package. PendingMessage &pm = peer->pending_message; pm.opcode = op; - pm.payload_size = arg->payload_length; } } @@ -608,6 +607,7 @@ void WSLPeer::_wsl_frame_recv_chunk_callback(wslay_event_context_ptr ctx, const if (pm.opcode != 0) { // Only write the payload. peer->in_buffer.write_packet(arg->data, arg->data_length, nullptr); + pm.payload_size += arg->data_length; } }