From a8a0dc9ea2e8cd37f667614e1b9a6dd5fc0af040 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Tue, 10 Mar 2026 09:38:22 -0700 Subject: net/http/internal/http2: make server write errors sticky After encountering a write error on a server's connection, remember the error and reuse it for future writes. Fixes a rare flakiness in TestServerWriteByteTimeout, where we can sometimes attempt to flush the write buffer after encountering a write timeout. Change-Id: I01649ae41185d6109180e222d4e8f8426a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/753720 Auto-Submit: Damien Neil Reviewed-by: Nicholas Husin LUCI-TryBot-Result: Go LUCI Reviewed-by: Nicholas Husin --- src/net/http/internal/http2/http2.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/net/http/internal/http2/http2.go b/src/net/http/internal/http2/http2.go index ba93bb9479..edf34e1f77 100644 --- a/src/net/http/internal/http2/http2.go +++ b/src/net/http/internal/http2/http2.go @@ -258,6 +258,7 @@ type bufferedWriter struct { conn net.Conn // immutable bw *bufio.Writer // non-nil when data is buffered byteTimeout time.Duration // immutable, WriteByteTimeout + werr error } func newBufferedWriter(conn net.Conn, timeout time.Duration) *bufferedWriter { @@ -289,12 +290,16 @@ func (w *bufferedWriter) Available() int { } func (w *bufferedWriter) Write(p []byte) (n int, err error) { + if w.werr != nil { + return 0, w.werr + } if w.bw == nil { bw := bufWriterPool.Get().(*bufio.Writer) bw.Reset((*bufferedWriterTimeoutWriter)(w)) w.bw = bw } - return w.bw.Write(p) + n, w.werr = w.bw.Write(p) + return n, w.werr } func (w *bufferedWriter) Flush() error { @@ -302,11 +307,14 @@ func (w *bufferedWriter) Flush() error { if bw == nil { return nil } - err := bw.Flush() + if w.werr != nil { + return w.werr + } + w.werr = bw.Flush() bw.Reset(nil) bufWriterPool.Put(bw) w.bw = nil - return err + return w.werr } type bufferedWriterTimeoutWriter bufferedWriter -- cgit v1.3