]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_websocket: Handle incoming CONTINUATION frames.
authorGeorge Joseph <gjoseph@sangoma.com>
Wed, 20 May 2026 15:16:48 +0000 (09:16 -0600)
committergithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Thu, 21 May 2026 17:27:52 +0000 (17:27 +0000)
chan_websocket now tells res_http_websocket to accumulate incoming CONTINUATION
frames into 1024 byte TEXT or BINARY frames.

Resolves: #1941

channels/chan_websocket.c

index bc05538a708351adabd3251e1b11259f4adfda62..6b8acc42bd9a0b4450e77d5cac55d39264b734ac 100644 (file)
@@ -1096,7 +1096,14 @@ static int read_from_ws_and_queue(struct websocket_pvt *instance)
                return process_text_message(instance, payload, payload_len);
        }
 
-       if (opcode == AST_WEBSOCKET_OPCODE_PING || opcode == AST_WEBSOCKET_OPCODE_PONG) {
+       /*
+        * PINGs and PONGs will have been handled by res_http_websocket.
+        * We also need to ignore CONTINUATION frames as they will be accumulated
+        * by res_http_websocket until the threshold set in websocket_handoff_to_channel()
+        * is reached, then it will send us a TEXT or BINARY frame.
+        */
+       if (opcode == AST_WEBSOCKET_OPCODE_PING || opcode == AST_WEBSOCKET_OPCODE_PONG
+               || opcode == AST_WEBSOCKET_OPCODE_CONTINUATION) {
                return 0;
        }
 
@@ -1139,6 +1146,13 @@ static int websocket_handoff_to_channel(struct websocket_pvt *instance)
                ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on websocket connection: %s\n", strerror(errno));
        }
 
+       /*
+        * Tell res_http_websocket to accumulate incoming WebSocket CONTINUATION frames
+        * into chunks of 1024 bytes and send us a TEXT or BINARY frame when the threshold
+        * is reached.
+        */
+       ast_websocket_reconstruct_enable(instance->websocket, 1024);
+
        ast_channel_set_fd(instance->channel, WS_WEBSOCKET_FDNO, ast_websocket_fd(instance->websocket));
 
        res = send_event(instance, MEDIA_START);