From e5339a80725c0a13ed55b1c19772f50e261fa345 Mon Sep 17 00:00:00 2001 From: qimaoww Date: Sun, 8 Mar 2026 19:42:21 +0800 Subject: [PATCH] chore: improve websocket wss->ws fallback diagnostics --- go-gost/x/socket/websocket_reporter.go | 56 ++++++++++++++++++--- go-gost/x/socket/websocket_reporter_test.go | 29 +++++++++++ 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/go-gost/x/socket/websocket_reporter.go b/go-gost/x/socket/websocket_reporter.go index ab03c64..f53ccee 100644 --- a/go-gost/x/socket/websocket_reporter.go +++ b/go-gost/x/socket/websocket_reporter.go @@ -266,7 +266,7 @@ func (w *WebSocketReporter) connect() error { return nil }) - fmt.Printf("✅ WebSocket连接建立成功 (%s, http=%d, tls=%d, socks=%d)\n", usedURL, cfg.Http, cfg.Tls, cfg.Socks) + fmt.Printf("✅ WebSocket连接建立成功 (%s, http=%d, tls=%d, socks=%d)\n", sanitizeWebSocketURL(usedURL), cfg.Http, cfg.Tls, cfg.Socks) return nil } @@ -345,20 +345,64 @@ func dialWebSocketWithFallback(dialer *websocket.Dialer, candidates []string) (* var errs []string for i, targetURL := range candidates { - conn, _, err := wsDial(dialer, targetURL) + conn, resp, err := wsDial(dialer, targetURL) if err == nil { if i > 0 { - fmt.Printf("↪️ WebSocket已自动回退到: %s\n", targetURL) + fmt.Printf("↪️ WebSocket已自动回退成功: %s\n", sanitizeWebSocketURL(targetURL)) } return conn, targetURL, nil } - errs = append(errs, fmt.Sprintf("%s => %v", targetURL, err)) + errMsg := formatWebSocketDialError(err, resp) + errs = append(errs, fmt.Sprintf("%s => %s", sanitizeWebSocketURL(targetURL), errMsg)) if i < len(candidates)-1 { - fmt.Printf("⚠️ WebSocket连接尝试失败,准备回退: %s => %v\n", targetURL, err) + fmt.Printf( + "⚠️ WebSocket连接失败,准备从 %s 回退到 %s: %s\n", + strings.ToUpper(detectWebSocketScheme(targetURL)), + strings.ToUpper(detectWebSocketScheme(candidates[i+1])), + errMsg, + ) } } - return nil, "", fmt.Errorf("连接WebSocket失败: %s", strings.Join(errs, " | ")) + return nil, "", fmt.Errorf("连接WebSocket失败(已尝试%d种协议): %s", len(candidates), strings.Join(errs, " | ")) +} + +func sanitizeWebSocketURL(rawURL string) string { + u, err := url.Parse(rawURL) + if err != nil { + return rawURL + } + + q := u.Query() + if q.Get("secret") != "" { + q.Set("secret", "***") + u.RawQuery = q.Encode() + } + return u.String() +} + +func formatWebSocketDialError(err error, resp *http.Response) string { + if err == nil { + return "" + } + if resp == nil { + return err.Error() + } + + msg := fmt.Sprintf("%s (HTTP %s)", err, resp.Status) + if resp.Body == nil { + return msg + } + + body, readErr := io.ReadAll(io.LimitReader(resp.Body, 256)) + if readErr != nil { + return msg + } + bodyText := strings.TrimSpace(string(body)) + if bodyText == "" { + return msg + } + return fmt.Sprintf("%s, body=%q", msg, bodyText) } // handleConnection 处理WebSocket连接 diff --git a/go-gost/x/socket/websocket_reporter_test.go b/go-gost/x/socket/websocket_reporter_test.go index 570b393..aa2639e 100644 --- a/go-gost/x/socket/websocket_reporter_test.go +++ b/go-gost/x/socket/websocket_reporter_test.go @@ -2,6 +2,7 @@ package socket import ( "errors" + "io" "net/http" "strings" "testing" @@ -96,3 +97,31 @@ func TestDetectWebSocketScheme(t *testing.T) { t.Fatalf("expected empty detection for non-websocket scheme") } } + +func TestSanitizeWebSocketURL(t *testing.T) { + raw := "wss://panel.example.com/system-info?type=1&secret=abc&version=2.0.2" + sanitized := sanitizeWebSocketURL(raw) + + if strings.Contains(sanitized, "secret=abc") { + t.Fatalf("expected secret to be masked, got %s", sanitized) + } + if !strings.Contains(sanitized, "secret=%2A%2A%2A") { + t.Fatalf("expected masked secret in url, got %s", sanitized) + } +} + +func TestFormatWebSocketDialErrorIncludesHTTPStatus(t *testing.T) { + err := errors.New("websocket: bad handshake") + resp := &http.Response{ + Status: "403 Forbidden", + Body: io.NopCloser(strings.NewReader("forbidden")), + } + + msg := formatWebSocketDialError(err, resp) + if !strings.Contains(msg, "HTTP 403 Forbidden") { + t.Fatalf("expected status in message, got %s", msg) + } + if !strings.Contains(msg, "forbidden") { + t.Fatalf("expected response body in message, got %s", msg) + } +}