Shut down WebSocket socket to prevent Werkzeug HTTP response leak

After a WebSocket handler exits, flask-sock returns a Response to
Werkzeug which writes "HTTP/1.1 200 OK..." on the still-open socket.
Browsers see these HTTP bytes as a malformed WebSocket frame, causing
"Invalid frame header".

Now the handler explicitly closes the raw TCP socket after the
WebSocket close handshake, so Werkzeug's write harmlessly fails.
Applied to both waterfall and audio WebSocket handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Smittix
2026-02-08 13:40:17 +00:00
parent 37842dc1ef
commit 455bc05c69
2 changed files with 35 additions and 2 deletions

View File

@@ -1,10 +1,11 @@
"""WebSocket-based audio streaming for SDR."""
import json
import shutil
import socket
import subprocess
import threading
import time
import shutil
import json
from flask import Flask
# Try to import flask-sock
@@ -251,4 +252,19 @@ def init_audio_websocket(app: Flask):
finally:
with process_lock:
kill_audio_processes()
# Complete WebSocket close handshake, then shut down the
# raw socket so Werkzeug cannot write its HTTP 200 response
# on top of the WebSocket stream.
try:
ws.close()
except Exception:
pass
try:
ws.sock.shutdown(socket.SHUT_RDWR)
except Exception:
pass
try:
ws.sock.close()
except Exception:
pass
logger.info("WebSocket audio client disconnected")

View File

@@ -2,6 +2,7 @@
import json
import queue
import socket
import subprocess
import threading
import time
@@ -348,4 +349,20 @@ def init_waterfall_websocket(app: Flask):
unregister_process(iq_process)
if claimed_device is not None:
app_module.release_sdr_device(claimed_device)
# Complete WebSocket close handshake, then shut down the
# raw socket so Werkzeug cannot write its HTTP 200 response
# on top of the WebSocket stream (which browsers see as
# "Invalid frame header").
try:
ws.close()
except Exception:
pass
try:
ws.sock.shutdown(socket.SHUT_RDWR)
except Exception:
pass
try:
ws.sock.close()
except Exception:
pass
logger.info("WebSocket waterfall client disconnected")