Make pipe read timeout configurable via idleTimeout metadata
The 30s hardcoded readTimeout in Pipe() caused all CONNECT tunnel connections to be hard-closed after 30s of inactivity, breaking WebSocket and long-polling connections through the proxy. Pipe() now accepts a WithReadTimeout(d) option. When d is 0 (the default) no read deadline is set, relying on TCP keepalives or context cancellation to detect dead connections instead. The HTTP handler exposes this as the idleTimeout metadata key. Fixes: https://github.com/go-gost/x/issues/91
This commit is contained in:
@@ -428,7 +428,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
|
||||
start := time.Now()
|
||||
log.Infof("%s <-> %s", conn.RemoteAddr(), addr)
|
||||
// xnet.Transport(conn, cc)
|
||||
xnet.Pipe(ctx, conn, cc)
|
||||
xnet.Pipe(ctx, conn, cc, xnet.WithReadTimeout(h.md.idleTimeout))
|
||||
log.WithFields(map[string]any{
|
||||
"duration": time.Since(start),
|
||||
}).Infof("%s >-< %s", conn.RemoteAddr(), addr)
|
||||
@@ -694,7 +694,7 @@ func (h *httpHandler) handleUpgradeResponse(ctx context.Context, rw io.ReadWrite
|
||||
}
|
||||
|
||||
// return xnet.Transport(rw, backConn)
|
||||
return xnet.Pipe(ctx, rw, backConn)
|
||||
return xnet.Pipe(ctx, rw, backConn, xnet.WithReadTimeout(h.md.idleTimeout))
|
||||
}
|
||||
|
||||
func (h *httpHandler) sniffingWebsocketFrame(ctx context.Context, rw, cc io.ReadWriter, ro *xrecorder.HandlerRecorderObject, log logger.Logger) error {
|
||||
@@ -893,7 +893,7 @@ func (h *httpHandler) authenticate(ctx context.Context, conn net.Conn, req *http
|
||||
|
||||
req.Write(cc)
|
||||
// xnet.Transport(conn, cc)
|
||||
xnet.Pipe(ctx, conn, cc)
|
||||
xnet.Pipe(ctx, conn, cc, xnet.WithReadTimeout(h.md.idleTimeout))
|
||||
return
|
||||
case "file":
|
||||
f, _ := os.Open(pr.Value)
|
||||
|
||||
@@ -21,6 +21,7 @@ const (
|
||||
|
||||
type metadata struct {
|
||||
readTimeout time.Duration
|
||||
idleTimeout time.Duration
|
||||
keepalive bool
|
||||
compression bool
|
||||
probeResistance *probeResistance
|
||||
@@ -57,6 +58,11 @@ func (h *httpHandler) parseMetadata(md mdata.Metadata) error {
|
||||
h.md.readTimeout = 0
|
||||
}
|
||||
|
||||
h.md.idleTimeout = mdutil.GetDuration(md, "idleTimeout")
|
||||
if h.md.idleTimeout < 0 {
|
||||
h.md.idleTimeout = 0
|
||||
}
|
||||
|
||||
if m := mdutil.GetStringMapString(md, "http.header", "header"); len(m) > 0 {
|
||||
hd := http.Header{}
|
||||
for k, v := range m {
|
||||
|
||||
Reference in New Issue
Block a user