From 2fdfa727b432f1547bc5b25affdfc8342ff50a77 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Apr 2026 07:26:34 +0000 Subject: [PATCH] refactor: improve browser dialer instance handling and diagnostics Agent-Logs-Url: https://github.com/XTLS/Xray-core/sessions/56665ec5-84ea-4bc3-a812-2e699e0e880d Co-authored-by: RPRX <63339210+RPRX@users.noreply.github.com> --- transport/internet/browser_dialer/dialer.go | 32 +++++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/transport/internet/browser_dialer/dialer.go b/transport/internet/browser_dialer/dialer.go index d7cfb810..f7088d52 100644 --- a/transport/internet/browser_dialer/dialer.go +++ b/transport/internet/browser_dialer/dialer.go @@ -6,6 +6,7 @@ import ( _ "embed" "encoding/base64" "encoding/json" + stderrors "errors" "net/http" "sync" "time" @@ -44,17 +45,20 @@ var upgrader = &websocket.Upgrader{ func Reload() { addr := getEnvAddress() mu.Lock() - defer mu.Unlock() closeDialerInstance(&dialerInstance{conns: conns, server: server}) conns = nil server = nil + var dialer *dialerInstance if addr != "" { - dialer := newDialerInstance(addr) + dialer = newDialerInstance(addr) conns = dialer.conns server = dialer.server } + mu.Unlock() + + startDialerInstance(dialer) } func HasBrowserDialer() bool { @@ -102,10 +106,20 @@ func newDialerInstance(addr string) *dialerInstance { } }), } - go dialer.server.ListenAndServe() return dialer } +func startDialerInstance(dialer *dialerInstance) { + if dialer == nil || dialer.server == nil { + return + } + go func() { + if err := dialer.server.ListenAndServe(); err != nil && !stderrors.Is(err, http.ErrServerClosed) { + errors.LogError(context.Background(), "Browser dialer http server unexpected error on ", dialer.server.Addr, ": ", err) + } + }() +} + func closeDialerInstance(d *dialerInstance) { if d == nil { return @@ -113,11 +127,12 @@ func closeDialerInstance(d *dialerInstance) { if d.server != nil { d.server.Close() } - for len(d.conns) > 0 { + for { select { case c := <-d.conns: c.Close() default: + return } } } @@ -127,15 +142,17 @@ func getDialerByAddress(addr string) *dialerInstance { return nil } mu.Lock() - defer mu.Unlock() if sockoptDialers == nil { sockoptDialers = make(map[string]*dialerInstance) } if dialer, found := sockoptDialers[addr]; found { + mu.Unlock() return dialer } dialer := newDialerInstance(addr) sockoptDialers[addr] = dialer + mu.Unlock() + startDialerInstance(dialer) return dialer } @@ -255,7 +272,10 @@ func dialTaskWithAddress(addr string, task task) (*websocket.Conn, error) { conns := connsByAddress(addr) if conns == nil { - return nil, errors.New("browser dialer is not configured") + if addr != "" { + return nil, errors.New("browser dialer is not configured for sockopt.browserDialer: ", addr) + } + return nil, errors.New("browser dialer is not configured; set sockopt.browserDialer or env ", platform.BrowserDialerAddress) } var conn *websocket.Conn