fix(webui): quiet non-WebSocket handshake noise on public port
The WebSocket channel also serves the WebUI over plain HTTP, so on a
public endpoint (e.g. a Render *.onrender.com service) the underlying
websockets library logs a full-traceback ERROR for every request that
isn't a valid GET handshake: HEAD probes ("unsupported HTTP method;
expected GET"), port scanners, uptime monitors, and TLS-to-plain-port
attempts. These are internet background noise, not server faults.
WebSocketHandshakeNoiseFilter already suppressed "opening handshake
failed" records caused by mid-handshake disconnects; widen it to also
suppress records whose exception chain contains websockets'
InvalidMessage, which covers both non-GET methods and malformed/empty
requests. Genuine server-side handshake errors still log.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Xubin Ren
co-authored by
Claude Opus 4.8
parent
c77379099b
commit
c062e1af14
@@ -4,6 +4,8 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from websockets.exceptions import InvalidMessage
|
||||
|
||||
from nanobot.webui.websocket_logging import (
|
||||
OPENING_HANDSHAKE_FAILED_MESSAGE,
|
||||
WebSocketHandshakeNoiseFilter,
|
||||
@@ -34,6 +36,23 @@ def test_websocket_handshake_noise_filter_suppresses_disconnects() -> None:
|
||||
assert not filter_.filter(_log_record(OPENING_HANDSHAKE_FAILED_MESSAGE, empty_handshake))
|
||||
|
||||
|
||||
def test_websocket_handshake_noise_filter_suppresses_non_get_probes() -> None:
|
||||
"""HEAD probes reach the WS port as InvalidMessage wrapping a ValueError."""
|
||||
filter_ = WebSocketHandshakeNoiseFilter()
|
||||
head_probe = InvalidMessage("did not receive a valid HTTP request")
|
||||
head_probe.__cause__ = ValueError("unsupported HTTP method; expected GET; got HEAD")
|
||||
|
||||
assert not filter_.filter(_log_record(OPENING_HANDSHAKE_FAILED_MESSAGE, head_probe))
|
||||
|
||||
|
||||
def test_websocket_handshake_noise_filter_suppresses_malformed_requests() -> None:
|
||||
"""Port scanners / TLS-to-plain-port probes raise a bare InvalidMessage."""
|
||||
filter_ = WebSocketHandshakeNoiseFilter()
|
||||
malformed = InvalidMessage("did not receive a valid HTTP request")
|
||||
|
||||
assert not filter_.filter(_log_record(OPENING_HANDSHAKE_FAILED_MESSAGE, malformed))
|
||||
|
||||
|
||||
def test_websocket_handshake_noise_filter_keeps_real_errors() -> None:
|
||||
filter_ = WebSocketHandshakeNoiseFilter()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user