1
0
mirror of https://github.com/golang/go synced 2024-11-17 18:54:42 -07:00

net/http: clear reference to the request context after transport getConn

Clears wannConn ctx and prevents pending dialConnFor after connection delivered or canceled.

Updates #50798

Change-Id: I9a681ac0f222be56571fa768700220f6b5ee0888
GitHub-Last-Rev: fd6c83ab07
GitHub-Pull-Request: golang/go#61524
Reviewed-on: https://go-review.googlesource.com/c/go/+/512196
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Alexander Yastrebov 2023-07-25 10:53:58 +00:00 committed by Gopher Robot
parent c738344171
commit 38a0c5bdb4

View File

@ -1205,7 +1205,6 @@ func (t *Transport) dial(ctx context.Context, network, addr string) (net.Conn, e
type wantConn struct {
cm connectMethod
key connectMethodKey // cm.key()
ctx context.Context // context for dial
ready chan struct{} // closed when pc, err pair is delivered
// hooks for testing to know when dials are done
@ -1214,7 +1213,8 @@ type wantConn struct {
beforeDial func()
afterDial func()
mu sync.Mutex // protects pc, err, close(ready)
mu sync.Mutex // protects ctx, pc, err, close(ready)
ctx context.Context // context for dial, cleared after delivered or canceled
pc *persistConn
err error
}
@ -1229,6 +1229,13 @@ func (w *wantConn) waiting() bool {
}
}
// getCtxForDial returns context for dial or nil if connection was delivered or canceled.
func (w *wantConn) getCtxForDial() context.Context {
w.mu.Lock()
defer w.mu.Unlock()
return w.ctx
}
// tryDeliver attempts to deliver pc, err to w and reports whether it succeeded.
func (w *wantConn) tryDeliver(pc *persistConn, err error) bool {
w.mu.Lock()
@ -1238,6 +1245,7 @@ func (w *wantConn) tryDeliver(pc *persistConn, err error) bool {
return false
}
w.ctx = nil
w.pc = pc
w.err = err
if w.pc == nil && w.err == nil {
@ -1255,6 +1263,7 @@ func (w *wantConn) cancel(t *Transport, err error) {
close(w.ready) // catch misbehavior in future delivery
}
pc := w.pc
w.ctx = nil
w.pc = nil
w.err = err
w.mu.Unlock()
@ -1463,8 +1472,12 @@ func (t *Transport) queueForDial(w *wantConn) {
// If the dial is canceled or unsuccessful, dialConnFor decrements t.connCount[w.cm.key()].
func (t *Transport) dialConnFor(w *wantConn) {
defer w.afterDial()
ctx := w.getCtxForDial()
if ctx == nil {
return
}
pc, err := t.dialConn(w.ctx, w.cm)
pc, err := t.dialConn(ctx, w.cm)
delivered := w.tryDeliver(pc, err)
if err == nil && (!delivered || pc.alt != nil) {
// pconn was not passed to w,