From db3e8a7f6b46e537bbaf6b29080cad0d683d6c8a Mon Sep 17 00:00:00 2001 From: B Tasker <88340935+btasker@users.noreply.github.com> Date: Tue, 18 Apr 2023 13:23:52 +0100 Subject: [PATCH] fix: if the only stream in a connection times out, prevent re-use to abandon the connection. This commit mitigates some raciness which can occur when an established connection fails. Without it, the connection can continue to be drawn from the connection pool, leading to subsequent requests failing. --- http2/transport.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/http2/transport.go b/http2/transport.go index f965579f7d..c577b5def9 100644 --- a/http2/transport.go +++ b/http2/transport.go @@ -1444,8 +1444,22 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { respHeaderRecv = nil respHeaderTimer = nil // keep waiting for END_STREAM case <-cs.abort: + // If this was the only active stream, mark the connection + // as not for re-use in order to address raciness if the caller + // tries to call closeIdleConnections() before the stream has been + // removed + if len(cc.streams) == 1 { + cc.doNotReuse = true + } return cs.abortErr case <-ctx.Done(): + // If this was the only active stream, mark the connection + // as not for re-use in order to address raciness if the caller + // tries to call closeIdleConnections() before the stream has been + // removed + if len(cc.streams) == 1 { + cc.doNotReuse = true + } return ctx.Err() case <-cs.reqCancel: return errRequestCanceled