From 92002fa35ea8dae30da8a3d2e4c1c06e96320cfa Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Sun, 21 Jun 2026 13:47:51 +0800 Subject: [PATCH] fix(listener): route WS/WSS HTTP server errors through GOST logger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set http.Server.ErrorLog to a logWriter that routes HTTP server errors (TLS handshake failures, malformed requests) to the GOST logger at Debug level instead of escaping to stderr via log.Printf. Without this, network scanners and protocol filters probing the WSS port produce uncontrolled output: http: TLS handshake error from ... Also downgrade WebSocket upgrade failures from Error to Warn — plain HTTP requests hitting the WebSocket endpoint are operational noise. Fixes go-gost/gost#419 --- listener/ws/listener.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/listener/ws/listener.go b/listener/ws/listener.go index 6b70e8fc..12e51469 100644 --- a/listener/ws/listener.go +++ b/listener/ws/listener.go @@ -2,9 +2,11 @@ package ws import ( "context" + stdlog "log" "net" "net/http" "net/http/httputil" + "strings" "time" "github.com/go-gost/core/limiter" @@ -85,6 +87,12 @@ func (l *wsListener) Init(md md.Metadata) (err error) { Addr: l.options.Addr, Handler: mux, ReadHeaderTimeout: l.md.readHeaderTimeout, + // Route HTTP server errors (TLS handshake failures, malformed + // requests) to the GOST logger instead of the default stderr + // output via log.Printf. Without this, network scanners and + // protocol filters probing the WSS port produce uncontrolled + // noise: "http: TLS handshake error from ...". + ErrorLog: stdlog.New(&logWriter{log: l.log}, "", 0), } l.cqueue = make(chan net.Conn, l.md.backlog) @@ -186,7 +194,9 @@ func (l *wsListener) upgrade(w http.ResponseWriter, r *http.Request) { conn, err := l.upgrader.Upgrade(w, r, l.md.header) if err != nil { - log.Error(err) + // Upgrade failures (plain HTTP requests, websocket + // handshake errors) are operational noise — log at Warn. + log.Warn(err) return } @@ -208,3 +218,17 @@ func (l *wsListener) upgrade(w http.ResponseWriter, r *http.Request) { log.Warnf("connection queue is full, client %s discarded", conn.RemoteAddr()) } } + +// logWriter adapts a GOST logger to the io.Writer interface required by +// http.Server.ErrorLog. It writes each log entry as a Debug-level message +// so that HTTP server errors (TLS handshake failures, malformed requests) +// are captured in GOST's logging pipeline instead of escaping to stderr +// via log.Printf. +type logWriter struct { + log logger.Logger +} + +func (w *logWriter) Write(p []byte) (n int, err error) { + w.log.Debug(strings.TrimSpace(string(p))) + return len(p), nil +}