aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/transport.go
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2021-03-23 16:43:18 +0100
committerFilippo Valsorda <filippo@golang.org>2021-03-23 16:43:18 +0100
commit229a39e347178614d2b5c103cbdc96b7f30a015a (patch)
tree74cd619fe213fe2047d4ae31d8a99cdee9e84208 /src/net/http/transport.go
parent055f1da6e6b96d4de842fd80773dea6d977fc025 (diff)
parentdcffdac515a1d409bcb61783d57ddb137b4741b9 (diff)
downloadgo-229a39e347178614d2b5c103cbdc96b7f30a015a.tar.gz
go-229a39e347178614d2b5c103cbdc96b7f30a015a.zip
[dev.boringcrypto.go1.15] all: merge go1.15.10 into dev.boringcrypto.go1.15
Change-Id: I2ac6b45dbfcfdaf956f2f4b11b60f8d24130141b
Diffstat (limited to 'src/net/http/transport.go')
-rw-r--r--src/net/http/transport.go31
1 files changed, 19 insertions, 12 deletions
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index d37b52b13d..6e430b9885 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -766,7 +766,8 @@ func (t *Transport) CancelRequest(req *Request) {
}
// Cancel an in-flight request, recording the error value.
-func (t *Transport) cancelRequest(key cancelKey, err error) {
+// Returns whether the request was canceled.
+func (t *Transport) cancelRequest(key cancelKey, err error) bool {
t.reqMu.Lock()
cancel := t.reqCanceler[key]
delete(t.reqCanceler, key)
@@ -774,6 +775,8 @@ func (t *Transport) cancelRequest(key cancelKey, err error) {
if cancel != nil {
cancel(err)
}
+
+ return cancel != nil
}
//
@@ -2087,18 +2090,17 @@ func (pc *persistConn) readLoop() {
}
if !hasBody || bodyWritable {
- pc.t.setReqCanceler(rc.cancelKey, nil)
+ replaced := pc.t.replaceReqCanceler(rc.cancelKey, nil)
// Put the idle conn back into the pool before we send the response
// so if they process it quickly and make another request, they'll
// get this same conn. But we use the unbuffered channel 'rc'
// to guarantee that persistConn.roundTrip got out of its select
// potentially waiting for this persistConn to close.
- // but after
alive = alive &&
!pc.sawEOF &&
pc.wroteRequest() &&
- tryPutIdleConn(trace)
+ replaced && tryPutIdleConn(trace)
if bodyWritable {
closeErr = errCallerOwnsConn
@@ -2160,12 +2162,12 @@ func (pc *persistConn) readLoop() {
// reading the response body. (or for cancellation or death)
select {
case bodyEOF := <-waitForBodyRead:
- pc.t.setReqCanceler(rc.cancelKey, nil) // before pc might return to idle pool
+ replaced := pc.t.replaceReqCanceler(rc.cancelKey, nil) // before pc might return to idle pool
alive = alive &&
bodyEOF &&
!pc.sawEOF &&
pc.wroteRequest() &&
- tryPutIdleConn(trace)
+ replaced && tryPutIdleConn(trace)
if bodyEOF {
eofc <- struct{}{}
}
@@ -2560,6 +2562,8 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
var respHeaderTimer <-chan time.Time
cancelChan := req.Request.Cancel
ctxDoneChan := req.Context().Done()
+ pcClosed := pc.closech
+ canceled := false
for {
testHookWaitResLoop()
select {
@@ -2579,11 +2583,14 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
defer timer.Stop() // prevent leaks
respHeaderTimer = timer.C
}
- case <-pc.closech:
- if debugRoundTrip {
- req.logf("closech recv: %T %#v", pc.closed, pc.closed)
+ case <-pcClosed:
+ pcClosed = nil
+ if canceled || pc.t.replaceReqCanceler(req.cancelKey, nil) {
+ if debugRoundTrip {
+ req.logf("closech recv: %T %#v", pc.closed, pc.closed)
+ }
+ return nil, pc.mapRoundTripError(req, startBytesWritten, pc.closed)
}
- return nil, pc.mapRoundTripError(req, startBytesWritten, pc.closed)
case <-respHeaderTimer:
if debugRoundTrip {
req.logf("timeout waiting for response headers.")
@@ -2602,10 +2609,10 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
}
return re.res, nil
case <-cancelChan:
- pc.t.cancelRequest(req.cancelKey, errRequestCanceled)
+ canceled = pc.t.cancelRequest(req.cancelKey, errRequestCanceled)
cancelChan = nil
case <-ctxDoneChan:
- pc.t.cancelRequest(req.cancelKey, req.Context().Err())
+ canceled = pc.t.cancelRequest(req.cancelKey, req.Context().Err())
cancelChan = nil
ctxDoneChan = nil
}