From 79f79c34deba28934d42d4a1b2ab72d124d737a2 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 1 May 2019 02:47:14 +0000 Subject: [PATCH] net/http: update bundled x/net/http2 Updates x/net/http2 to git rev 1da14a5a36f220ea3f03470682b737b1dfd5de22 for: http2: make empty method mean GET https://golang.org/cl/169557 (Fixes golang/go#31061) http2: don't hang a stream if trailers values are not provided https://golang.org/cl/161958 Change-Id: I628af8c6d07d19e8f19ee37637243f6c242ef3a1 Reviewed-on: https://go-review.googlesource.com/c/go/+/174677 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Dmitri Shuralyov --- src/net/http/h2_bundle.go | 28 ++++++++++++++++++++++------ src/net/http/socks_bundle.go | 2 +- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go index 262beb7068a29..e85250d1ae884 100644 --- a/src/net/http/h2_bundle.go +++ b/src/net/http/h2_bundle.go @@ -1,5 +1,5 @@ // Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. -//go:generate bundle -o h2_bundle.go -prefix http2 -underscore golang.org/x/net/http2 +//go:generate bundle -o h2_bundle.go -prefix http2 golang.org/x/net/http2 // Package http2 implements the HTTP/2 protocol. // @@ -1885,7 +1885,7 @@ func (f *http2Framer) WriteData(streamID uint32, endStream bool, data []byte) er return f.WriteDataPadded(streamID, endStream, data, nil) } -// WriteData writes a DATA frame with optional padding. +// WriteDataPadded writes a DATA frame with optional padding. // // If pad is nil, the padding bit is not sent. // The length of pad must not exceed 255 bytes. @@ -5870,7 +5870,16 @@ type http2chunkWriter struct{ rws *http2responseWriterState } func (cw http2chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) } -func (rws *http2responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 } +func (rws *http2responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 } + +func (rws *http2responseWriterState) hasNonemptyTrailers() bool { + for _, trailer := range rws.trailers { + if _, ok := rws.handlerHeader[trailer]; ok { + return true + } + } + return false +} // declareTrailer is called for each Trailer header when the // response header is written. It notes that a header will need to be @@ -5970,7 +5979,10 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { rws.promoteUndeclaredTrailers() } - endStream := rws.handlerDone && !rws.hasTrailers() + // only send trailers if they have actually been defined by the + // server handler. + hasNonemptyTrailers := rws.hasNonemptyTrailers() + endStream := rws.handlerDone && !hasNonemptyTrailers if len(p) > 0 || endStream { // only send a 0 byte DATA frame if we're ending the stream. if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil { @@ -5979,7 +5991,7 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { } } - if rws.handlerDone && rws.hasTrailers() { + if rws.handlerDone && hasNonemptyTrailers { err = rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{ streamID: rws.stream.id, h: rws.handlerHeader, @@ -7834,7 +7846,11 @@ func (cc *http2ClientConn) encodeHeaders(req *Request, addGzipHeader bool, trail // followed by the query production (see Sections 3.3 and 3.4 of // [RFC3986]). f(":authority", host) - f(":method", req.Method) + m := req.Method + if m == "" { + m = MethodGet + } + f(":method", m) if req.Method != "CONNECT" { f(":path", path) f(":scheme", req.URL.Scheme) diff --git a/src/net/http/socks_bundle.go b/src/net/http/socks_bundle.go index 3a947a0c9179b..e6640dd404df2 100644 --- a/src/net/http/socks_bundle.go +++ b/src/net/http/socks_bundle.go @@ -453,7 +453,7 @@ func (up *socksUsernamePassword) Authenticate(ctx context.Context, rw io.ReadWri b = append(b, up.Username...) b = append(b, byte(len(up.Password))) b = append(b, up.Password...) - // TODO(mikio): handle IO deadlines and cancellation if + // TODO(mikio): handle IO deadlines and cancelation if // necessary if _, err := rw.Write(b); err != nil { return err