From 5c6a6d94274ddff27c0ee57d9ee99e02bbb020e0 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 26 Jun 2025 15:52:25 +0200 Subject: [PATCH] cluster/websocket: Fix and test for invalid X-Application-Name --- src/cluster/websocket/WebSocket.cc | 1 - .../client..stdout | 4 ++ .../cluster/telemetry/ws-invalid-app.zeek | 64 +++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/cluster.telemetry.ws-invalid-app/client..stdout create mode 100644 testing/btest/cluster/telemetry/ws-invalid-app.zeek diff --git a/src/cluster/websocket/WebSocket.cc b/src/cluster/websocket/WebSocket.cc index 1063ab8b6f..95288f89f1 100644 --- a/src/cluster/websocket/WebSocket.cc +++ b/src/cluster/websocket/WebSocket.cc @@ -303,7 +303,6 @@ void WebSocketEventDispatcher::Process(const WebSocketOpen& open) { }); if ( ! good_application_name ) { - QueueReply(WebSocketCloseReply{wsc, 1001, "Internal error"}); open.wsc->SendError("invalid_application_name", "Invalid X-Application-Name"); open.wsc->Close(1008, "Invalid X-Application-Name"); diff --git a/testing/btest/Baseline/cluster.telemetry.ws-invalid-app/client..stdout b/testing/btest/Baseline/cluster.telemetry.ws-invalid-app/client..stdout new file mode 100644 index 0000000000..df263af0e8 --- /dev/null +++ b/testing/btest/Baseline/cluster.telemetry.ws-invalid-app/client..stdout @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +connected +recv code invalid_application_name context Invalid X-Application-Name +exception code 1008 reason Invalid X-Application-Name diff --git a/testing/btest/cluster/telemetry/ws-invalid-app.zeek b/testing/btest/cluster/telemetry/ws-invalid-app.zeek new file mode 100644 index 0000000000..d46c9b8fd1 --- /dev/null +++ b/testing/btest/cluster/telemetry/ws-invalid-app.zeek @@ -0,0 +1,64 @@ +# @TEST-DOC: Test a WebSocket client with an invalid X-Application-Name that is rejected. +# +# @TEST-REQUIRES: have-zeromq +# @TEST-REQUIRES: python3 -c 'import websockets.sync' +# +# @TEST-GROUP: cluster-zeromq +# +# @TEST-PORT: XPUB_PORT +# @TEST-PORT: XSUB_PORT +# @TEST-PORT: LOG_PULL_PORT +# @TEST-PORT: WEBSOCKET_PORT +# +# @TEST-EXEC: cp $FILES/zeromq/cluster-layout-simple.zeek cluster-layout.zeek +# @TEST-EXEC: cp $FILES/zeromq/test-bootstrap.zeek zeromq-test-bootstrap.zeek +# @TEST-EXEC: cp $FILES/ws/wstest.py . +# +# @TEST-EXEC: zeek -b --parse-only manager.zeek +# @TEST-EXEC: python3 -m py_compile client.py +# +# @TEST-EXEC: btest-bg-run manager "ZEEKPATH=$ZEEKPATH:.. && CLUSTER_NODE=manager zeek -b ../manager.zeek" +# @TEST-EXEC: python3 client.py > client.out 2>&1 +# +# @TEST-EXEC: btest-diff client.out + +# @TEST-START-FILE manager.zeek +@load ./zeromq-test-bootstrap + +global ping: event(msg: string, c: count) &is_used; + +event zeek_init() + { + Cluster::subscribe("/test/pings"); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + } + +# terminate() on the first proper client connection. +event Cluster::websocket_client_added(info: Cluster::EndpointInfo, subscriptions: string_vec) + { + terminate(); + } +# @TEST-END-FILE + + +# @TEST-START-FILE client.py +import websockets.exceptions +import wstest + +def run(ws_url): + try: + with wstest.connect("ws1", ws_url, additional_headers={"X-Application-Name": "!!invalid~~"}) as tc: + print("connected") + while True: + err = tc.recv_json() + print("recv", "code", err["code"], "context", err["context"]) + except websockets.exceptions.ConnectionClosedError as e: + print("exception", "code", e.code, "reason", e.reason) + + # For terminating the Zeek server. + with wstest.connect("ws2", ws_url) as tc: + tc.hello_v1([]) + +if __name__ == "__main__": + wstest.main(run, wstest.WS4_URL_V1) +# @TEST-END-FILE