summaryrefslogtreecommitdiff
path: root/src/net/http
diff options
context:
space:
mode:
authorEmmanuel T Odeke <emmanuel@orijtech.com>2020-08-22 05:47:06 -0700
committerEmmanuel Odeke <emm.odeke@gmail.com>2020-08-25 19:31:26 +0000
commit3d774611feee49aa44b4f5ed65d40497a47ad4c8 (patch)
tree81ae619585dce0c5c46ebcdb8fca339565c3907a /src/net/http
parente3d608a8664b2cb0054f4d4706cdf911fd699b82 (diff)
downloadgo-git-3d774611feee49aa44b4f5ed65d40497a47ad4c8.tar.gz
src/go.mod, net/http: update bundled and latest golang.org/x/net
Updates x/net/http2 to git rev c89045814202410a2d67ec20ecf177ec77ceae7f http2: perform connection health check https://golang.org/cl/198040 (fixes #31643) http2: use ASCII space trimming for parsing Trailer header https://golang.org/cl/231437 all: update golang.org/x/crypto to v0.0.0-20200622213623-75b288015ac9 https://golang.org/cl/239700 (updates #30965) net/http2: fix erringRoundTripper https://golang.org/cl/243257 (updates #40213) also updates the vendored version of golang.org/x/net as per $ go get golang.org/x/net@c890458142 $ go mod tidy $ go mod vendor $ go generate -run bundle std Change-Id: Iea2473ef086df760144d9656f03a0218eb9da91f Reviewed-on: https://go-review.googlesource.com/c/go/+/249842 Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com> Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/net/http')
-rw-r--r--src/net/http/h2_bundle.go70
1 files changed, 64 insertions, 6 deletions
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 81c3671f85..463e7e8ce9 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -5629,7 +5629,7 @@ func (sc *http2serverConn) newWriterAndRequestNoBody(st *http2stream, rp http2re
var trailer Header
for _, v := range rp.header["Trailer"] {
for _, key := range strings.Split(v, ",") {
- key = CanonicalHeaderKey(strings.TrimSpace(key))
+ key = CanonicalHeaderKey(textproto.TrimString(key))
switch key {
case "Transfer-Encoding", "Trailer", "Content-Length":
// Bogus. (copy of http1 rules)
@@ -6606,6 +6606,19 @@ type http2Transport struct {
// waiting for their turn.
StrictMaxConcurrentStreams bool
+ // ReadIdleTimeout is the timeout after which a health check using ping
+ // frame will be carried out if no frame is received on the connection.
+ // Note that a ping response will is considered a received frame, so if
+ // there is no other traffic on the connection, the health check will
+ // be performed every ReadIdleTimeout interval.
+ // If zero, no health check is performed.
+ ReadIdleTimeout time.Duration
+
+ // PingTimeout is the timeout after which the connection will be closed
+ // if a response to Ping is not received.
+ // Defaults to 15s.
+ PingTimeout time.Duration
+
// t1, if non-nil, is the standard library Transport using
// this transport. Its settings are used (but not its
// RoundTrip method, etc).
@@ -6629,6 +6642,14 @@ func (t *http2Transport) disableCompression() bool {
return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
}
+func (t *http2Transport) pingTimeout() time.Duration {
+ if t.PingTimeout == 0 {
+ return 15 * time.Second
+ }
+ return t.PingTimeout
+
+}
+
// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
// It returns an error if t1 has already been HTTP/2-enabled.
func http2ConfigureTransport(t1 *Transport) error {
@@ -7174,6 +7195,20 @@ func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2Client
return cc, nil
}
+func (cc *http2ClientConn) healthCheck() {
+ pingTimeout := cc.t.pingTimeout()
+ // We don't need to periodically ping in the health check, because the readLoop of ClientConn will
+ // trigger the healthCheck again if there is no frame received.
+ ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
+ defer cancel()
+ err := cc.Ping(ctx)
+ if err != nil {
+ cc.closeForLostPing()
+ cc.t.connPool().MarkDead(cc)
+ return
+ }
+}
+
func (cc *http2ClientConn) setGoAway(f *http2GoAwayFrame) {
cc.mu.Lock()
defer cc.mu.Unlock()
@@ -7345,14 +7380,12 @@ func (cc *http2ClientConn) sendGoAway() error {
return nil
}
-// Close closes the client connection immediately.
-//
-// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
-func (cc *http2ClientConn) Close() error {
+// closes the client connection immediately. In-flight requests are interrupted.
+// err is sent to streams.
+func (cc *http2ClientConn) closeForError(err error) error {
cc.mu.Lock()
defer cc.cond.Broadcast()
defer cc.mu.Unlock()
- err := errors.New("http2: client connection force closed via ClientConn.Close")
for id, cs := range cc.streams {
select {
case cs.resc <- http2resAndError{err: err}:
@@ -7365,6 +7398,20 @@ func (cc *http2ClientConn) Close() error {
return cc.tconn.Close()
}
+// Close closes the client connection immediately.
+//
+// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
+func (cc *http2ClientConn) Close() error {
+ err := errors.New("http2: client connection force closed via ClientConn.Close")
+ return cc.closeForError(err)
+}
+
+// closes the client connection immediately. In-flight requests are interrupted.
+func (cc *http2ClientConn) closeForLostPing() error {
+ err := errors.New("http2: client connection lost")
+ return cc.closeForError(err)
+}
+
const http2maxAllocFrameSize = 512 << 10
// frameBuffer returns a scratch buffer suitable for writing DATA frames.
@@ -8236,8 +8283,17 @@ func (rl *http2clientConnReadLoop) run() error {
rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse
gotReply := false // ever saw a HEADERS reply
gotSettings := false
+ readIdleTimeout := cc.t.ReadIdleTimeout
+ var t *time.Timer
+ if readIdleTimeout != 0 {
+ t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
+ defer t.Stop()
+ }
for {
f, err := cc.fr.ReadFrame()
+ if t != nil {
+ t.Reset(readIdleTimeout)
+ }
if err != nil {
cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
}
@@ -8968,6 +9024,8 @@ func http2strSliceContains(ss []string, s string) bool {
type http2erringRoundTripper struct{ err error }
+func (rt http2erringRoundTripper) RoundTripErr() error { return rt.err }
+
func (rt http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { return nil, rt.err }
// gzipReader wraps a response body so it can lazily