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:
Andrew Beresford
2026-05-08 11:31:53 +01:00
parent 07ca57055a
commit 290e9c37d5
3 changed files with 40 additions and 12 deletions
+6
View File
@@ -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 {