diff options
author | Filippo Valsorda <filippo@golang.org> | 2020-02-12 19:41:50 -0500 |
---|---|---|
committer | Filippo Valsorda <filippo@golang.org> | 2020-02-12 19:41:50 -0500 |
commit | fdf5e5b5905f5cff6687dff77fe64a93cd419d0c (patch) | |
tree | 487a8753359567e01742238a0581000565121806 | |
parent | 71468339f76309218dff12a130c19022df5e9317 (diff) | |
parent | a7acf9af07bdc288129fa5756768b41f312d05f4 (diff) | |
download | go-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.go | 2 | ||||
-rw-r--r-- | src/net/http/transport.go | 15 | ||||
-rw-r--r-- | src/net/http/transport_test.go | 56 | ||||
-rw-r--r-- | src/runtime/os_windows.go | 9 |
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") |