]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: update bundled http2
authorBrad Fitzpatrick <bradfitz@golang.org>
Fri, 29 Jun 2018 19:23:35 +0000 (19:23 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 29 Jun 2018 21:45:46 +0000 (21:45 +0000)
Updates http2 to x/net/http2 git rev 97aa3a539 for:

    http2: dynamic table updates must occur first
    https://golang.org/cl/111681

    http2: receiving too much data is a protocol error
    https://golang.org/cl/111679

    http2: correct overflow protection
    https://golang.org/cl/111675

    http2: make Server send GOAWAY if Handler sets "Connection: close" header
    https://golang.org/cl/121415

Fixes #20977

Change-Id: I9b8659b5191409ed007e2d911913763bcbabb7cc
Reviewed-on: https://go-review.googlesource.com/121695
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/http/clientserver_test.go
src/net/http/h2_bundle.go

index b894be0813da1cd075f0704c84a0979c19c6168a..c2a2548df11a26278608d7add4576bfb8e639e76 100644 (file)
@@ -1232,7 +1232,6 @@ func TestH12_AutoGzipWithDumpResponse(t *testing.T) {
                        h := w.Header()
                        h.Set("Content-Encoding", "gzip")
                        h.Set("Content-Length", "23")
-                       h.Set("Connection", "keep-alive")
                        io.WriteString(w, "\x1f\x8b\b\x00\x00\x00\x00\x00\x00\x00s\xf3\xf7\a\x00\xab'\xd4\x1a\x03\x00\x00\x00")
                },
                EarlyCheckResponse: func(proto string, res *Response) {
index f0dd8e6c761a1c1b6d7c5b872020947ec67c908b..053f81e257871386ed7d1baaf1610ef377343024 100644 (file)
@@ -1290,12 +1290,12 @@ func (f *http2flow) take(n int32) {
 // add adds n bytes (positive or negative) to the flow control window.
 // It returns false if the sum would exceed 2^31-1.
 func (f *http2flow) add(n int32) bool {
-       remain := (1<<31 - 1) - f.n
-       if n > remain {
-               return false
+       sum := f.n + n
+       if (sum > n) == (f.n > 0) {
+               f.n = sum
+               return true
        }
-       f.n += n
-       return true
+       return false
 }
 
 const http2frameHeaderLen = 9
@@ -5302,7 +5302,10 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error {
        // Sender sending more than they'd declared?
        if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
                st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
-               return http2streamError(id, http2ErrCodeStreamClosed)
+               // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
+               // value of a content-length header field does not equal the sum of the
+               // DATA frame payload lengths that form the body.
+               return http2streamError(id, http2ErrCodeProtocol)
        }
        if f.Length > 0 {
                // Check whether the client has flow control quota.
@@ -6038,6 +6041,19 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
                        http2foreachHeaderElement(v, rws.declareTrailer)
                }
 
+               // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),
+               // but respect "Connection" == "close" to mean sending a GOAWAY and tearing
+               // down the TCP connection when idle, like we do for HTTP/1.
+               // TODO: remove more Connection-specific header fields here, in addition
+               // to "Connection".
+               if _, ok := rws.snapHeader["Connection"]; ok {
+                       v := rws.snapHeader.Get("Connection")
+                       delete(rws.snapHeader, "Connection")
+                       if v == "close" {
+                               rws.conn.startGracefulShutdown()
+                       }
+               }
+
                endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
                err = rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{
                        streamID:      rws.stream.id,
@@ -6845,9 +6861,7 @@ func (http2noCachedConnError) Error() string { return "http2: no cached connecti
 // or its equivalent renamed type in net/http2's h2_bundle.go. Both types
 // may coexist in the same running program.
 func http2isNoCachedConnError(err error) bool {
-       _, ok := err.(interface {
-               IsHTTP2NoCachedConnError()
-       })
+       _, ok := err.(interface{ IsHTTP2NoCachedConnError() })
        return ok
 }