fix: prevert body not close where conn is already closed before setup for sing-mux and trusttunnel

This commit is contained in:
wwqgtxx
2026-04-17 16:08:13 +08:00
parent 37942ce9d8
commit e4099f0fa1
5 changed files with 21 additions and 13 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ require (
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/restls-client-go v0.1.7
github.com/metacubex/sing v0.5.7
github.com/metacubex/sing-mux v0.3.7
github.com/metacubex/sing-mux v0.3.8
github.com/metacubex/sing-quic v0.0.0-20260414034501-3ea3410d197a
github.com/metacubex/sing-shadowsocks v0.2.12
github.com/metacubex/sing-shadowsocks2 v0.2.7
+2 -2
View File
@@ -125,8 +125,8 @@ github.com/metacubex/restls-client-go v0.1.7 h1:eCwiXCTQb5WJu9IlgYvDBA1OgrINv58d
github.com/metacubex/restls-client-go v0.1.7/go.mod h1:BN/U52vPw7j8VTSh2vleD/MnmVKCov84mS5VcjVHH4g=
github.com/metacubex/sing v0.5.7 h1:8OC+fhKFSv/l9ehEhJRaZZAOuthfZo68SteBVLe8QqM=
github.com/metacubex/sing v0.5.7/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
github.com/metacubex/sing-mux v0.3.7 h1:CnsRQfxFOLNh8gZqbPVFVPNVWgq5paiLksI0tVJI5CY=
github.com/metacubex/sing-mux v0.3.7/go.mod h1:8bT7ZKT3clRrJjYc/x5CRYibC1TX/bK73a3r3+2E+Fc=
github.com/metacubex/sing-mux v0.3.8 h1:b9WWmdVG/StDErCZpR3hPxO5z65zcRzDGq1a/eh4anI=
github.com/metacubex/sing-mux v0.3.8/go.mod h1:8bT7ZKT3clRrJjYc/x5CRYibC1TX/bK73a3r3+2E+Fc=
github.com/metacubex/sing-quic v0.0.0-20260414034501-3ea3410d197a h1:977o0ZYYbiQAGuOxql7Q6UN3rEy59OyAE0tELq4gZfI=
github.com/metacubex/sing-quic v0.0.0-20260414034501-3ea3410d197a/go.mod h1:6ayFGfzzBE85csgQkM3gf4neFq6s0losHlPRSxY+nuk=
github.com/metacubex/sing-shadowsocks v0.2.12 h1:Wqzo8bYXrK5aWqxu/TjlTnYZzAKtKsaFQBdr6IHFaBE=
+3 -3
View File
@@ -155,16 +155,16 @@ func (c *Client) roundTrip(request *http.Request, conn *httpConn) {
if err != nil {
_ = pipeWriter.CloseWithError(err)
_ = pipeReader.CloseWithError(err)
conn.setUp(nil, err)
conn.setup(nil, err)
} else if response.StatusCode != http.StatusOK {
_ = response.Body.Close()
err = fmt.Errorf("unexpected status code: %d", response.StatusCode)
_ = pipeWriter.CloseWithError(err)
_ = pipeReader.CloseWithError(err)
conn.setUp(nil, err)
conn.setup(nil, err)
} else {
c.resetHealthCheckTimer()
conn.setUp(response.Body, nil)
conn.setup(response.Body, nil)
}
}()
}
+12 -4
View File
@@ -10,6 +10,7 @@ import (
"net/netip"
"runtime"
"strings"
"sync"
"time"
"github.com/metacubex/mihomo/common/httputils"
@@ -95,6 +96,7 @@ type httpConn struct {
writer io.Writer
flusher http.Flusher
body io.ReadCloser
setupOnce sync.Once
created chan struct{}
createErr error
cancelFn func()
@@ -105,10 +107,15 @@ type httpConn struct {
deadline *time.Timer
}
func (h *httpConn) setUp(body io.ReadCloser, err error) {
h.body = body
h.createErr = err
close(h.created)
func (h *httpConn) setup(body io.ReadCloser, err error) {
h.setupOnce.Do(func() {
h.body = body
h.createErr = err
close(h.created)
})
if h.createErr != nil && body != nil { // conn already closed before setup
_ = body.Close()
}
}
func (h *httpConn) waitCreated() error {
@@ -118,6 +125,7 @@ func (h *httpConn) waitCreated() error {
func (h *httpConn) Close() error {
var errorArr []error
h.setup(nil, net.ErrClosed)
if closer, ok := h.writer.(io.Closer); ok {
errorArr = append(errorArr, closer.Close())
}
+3 -3
View File
@@ -167,7 +167,7 @@ func (s *Service) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
},
}
httputils.SetAddrFromRequest(&conn.NetAddr, request)
conn.setUp(request.Body, nil)
conn.setup(request.Body, nil)
firstPacket := buf.NewPacket()
destination, err := conn.ReadPacket(firstPacket)
if err != nil {
@@ -204,7 +204,7 @@ func (s *Service) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
},
}
httputils.SetAddrFromRequest(&conn.NetAddr, request)
conn.setUp(request.Body, nil)
conn.setup(request.Body, nil)
s.icmpHandler.NewICMPConnection(ctx, conn)
}
case HealthCheckMagicAddress:
@@ -227,7 +227,7 @@ func (s *Service) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
},
}
httputils.SetAddrFromRequest(&conn.NetAddr, request)
conn.setUp(request.Body, nil)
conn.setup(request.Body, nil)
_ = s.handler.NewConnection(ctx, N.NewDeadlineConn(conn), M.Metadata{
Protocol: "trusttunnel",
Source: M.ParseSocksaddr(request.RemoteAddr),