aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2020-02-12 19:41:50 -0500
committerFilippo Valsorda <filippo@golang.org>2020-02-12 19:41:50 -0500
commitfdf5e5b5905f5cff6687dff77fe64a93cd419d0c (patch)
tree487a8753359567e01742238a0581000565121806
parent71468339f76309218dff12a130c19022df5e9317 (diff)
parenta7acf9af07bdc288129fa5756768b41f312d05f4 (diff)
downloadgo-fdf5e5b5905f5cff6687dff77fe64a93cd419d0c.tar.gz
go-fdf5e5b5905f5cff6687dff77fe64a93cd419d0c.zip
[dev.boringcrypto.go1.13] all: merge go1.13.8 into dev.boringcrypto.go1.13
Change-Id: I2d377641aacc93a60d3de5e643c6a65068424755
-rw-r--r--src/crypto/x509/pkcs8.go2
-rw-r--r--src/net/http/transport.go15
-rw-r--r--src/net/http/transport_test.go56
-rw-r--r--src/runtime/os_windows.go9
4 files changed, 74 insertions, 8 deletions
diff --git a/src/crypto/x509/pkcs8.go b/src/crypto/x509/pkcs8.go
index d37fc9e1b3..ec4ab10c57 100644
--- a/src/crypto/x509/pkcs8.go
+++ b/src/crypto/x509/pkcs8.go
@@ -79,7 +79,7 @@ func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
}
}
-// MarshalPKCS8PrivateKey converts an RSA private key to PKCS#8, ASN.1 DER form.
+// MarshalPKCS8PrivateKey converts a private key to PKCS#8, ASN.1 DER form.
//
// The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey
// and ed25519.PrivateKey. Unsupported key types result in an error.
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 903e0b51ef..db8ec4b2c6 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -542,8 +542,9 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) {
_, isH2DialError := pconn.alt.(http2erringRoundTripper)
if http2isNoCachedConnError(err) || isH2DialError {
- t.removeIdleConn(pconn)
- t.decConnsPerHost(pconn.cacheKey)
+ if t.removeIdleConn(pconn) {
+ t.decConnsPerHost(pconn.cacheKey)
+ }
}
if !pconn.shouldRetryRequest(req, err) {
// Issue 16465: return underlying net.Conn.Read error from peek,
@@ -966,26 +967,28 @@ func (t *Transport) queueForIdleConn(w *wantConn) (delivered bool) {
}
// removeIdleConn marks pconn as dead.
-func (t *Transport) removeIdleConn(pconn *persistConn) {
+func (t *Transport) removeIdleConn(pconn *persistConn) bool {
t.idleMu.Lock()
defer t.idleMu.Unlock()
- t.removeIdleConnLocked(pconn)
+ return t.removeIdleConnLocked(pconn)
}
// t.idleMu must be held.
-func (t *Transport) removeIdleConnLocked(pconn *persistConn) {
+func (t *Transport) removeIdleConnLocked(pconn *persistConn) bool {
if pconn.idleTimer != nil {
pconn.idleTimer.Stop()
}
t.idleLRU.remove(pconn)
key := pconn.cacheKey
pconns := t.idleConn[key]
+ var removed bool
switch len(pconns) {
case 0:
// Nothing
case 1:
if pconns[0] == pconn {
delete(t.idleConn, key)
+ removed = true
}
default:
for i, v := range pconns {
@@ -996,9 +999,11 @@ func (t *Transport) removeIdleConnLocked(pconn *persistConn) {
// conns at the end.
copy(pconns[i:], pconns[i+1:])
t.idleConn[key] = pconns[:len(pconns)-1]
+ removed = true
break
}
}
+ return removed
}
func (t *Transport) setReqCanceler(r *Request, fn func(error)) {
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index d0b12b3cb0..9f31e83e31 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -5832,3 +5832,59 @@ func TestDontCacheBrokenHTTP2Conn(t *testing.T) {
t.Errorf("GotConn calls = %v; want %v", got, want)
}
}
+
+// Issue 34941
+// When the client has too many concurrent requests on a single connection,
+// http.http2noCachedConnError is reported on multiple requests. There should
+// only be one decrement regardless of the number of failures.
+func TestTransportDecrementConnWhenIdleConnRemoved(t *testing.T) {
+ defer afterTest(t)
+
+ h := HandlerFunc(func(w ResponseWriter, r *Request) {
+ _, err := w.Write([]byte("foo"))
+ if err != nil {
+ t.Fatalf("Write: %v", err)
+ }
+ })
+
+ ts := httptest.NewUnstartedServer(h)
+ ts.TLS = &tls.Config{NextProtos: []string{"h2"}}
+ ts.StartTLS()
+ defer ts.Close()
+
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
+ tr.MaxConnsPerHost = 1
+ if err := ExportHttp2ConfigureTransport(tr); err != nil {
+ t.Fatalf("ExportHttp2ConfigureTransport: %v", err)
+ }
+
+ errCh := make(chan error, 300)
+ doReq := func() {
+ resp, err := c.Get(ts.URL)
+ if err != nil {
+ errCh <- fmt.Errorf("request failed: %v", err)
+ return
+ }
+ defer resp.Body.Close()
+ _, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ errCh <- fmt.Errorf("read body failed: %v", err)
+ }
+ }
+
+ var wg sync.WaitGroup
+ for i := 0; i < 300; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ doReq()
+ }()
+ }
+ wg.Wait()
+ close(errCh)
+
+ for err := range errCh {
+ t.Errorf("error occurred: %v", err)
+ }
+}
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index 6897933e30..2cf81f61a9 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -263,8 +263,9 @@ func loadOptionalSyscalls() {
func monitorSuspendResume() {
const (
- _DEVICE_NOTIFY_CALLBACK = 2
- _ERROR_FILE_NOT_FOUND = 2
+ _DEVICE_NOTIFY_CALLBACK = 2
+ _ERROR_FILE_NOT_FOUND = 2
+ _ERROR_INVALID_PARAMETERS = 87
)
type _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS struct {
callback uintptr
@@ -302,6 +303,10 @@ func monitorSuspendResume() {
// also have their clock on "program time", and therefore
// don't want or need this anyway.
return
+ case _ERROR_INVALID_PARAMETERS:
+ // This is seen when running in Windows Docker.
+ // See issue 36557.
+ return
default:
println("runtime: PowerRegisterSuspendResumeNotification failed with errno=", ret)
throw("runtime: PowerRegisterSuspendResumeNotification failure")