Commit cdce8248 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http: update bundled http2

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/121695Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent f43aa1df
...@@ -1232,7 +1232,6 @@ func TestH12_AutoGzipWithDumpResponse(t *testing.T) { ...@@ -1232,7 +1232,6 @@ func TestH12_AutoGzipWithDumpResponse(t *testing.T) {
h := w.Header() h := w.Header()
h.Set("Content-Encoding", "gzip") h.Set("Content-Encoding", "gzip")
h.Set("Content-Length", "23") 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") 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) { EarlyCheckResponse: func(proto string, res *Response) {
......
...@@ -1290,12 +1290,12 @@ func (f *http2flow) take(n int32) { ...@@ -1290,12 +1290,12 @@ func (f *http2flow) take(n int32) {
// add adds n bytes (positive or negative) to the flow control window. // add adds n bytes (positive or negative) to the flow control window.
// It returns false if the sum would exceed 2^31-1. // It returns false if the sum would exceed 2^31-1.
func (f *http2flow) add(n int32) bool { func (f *http2flow) add(n int32) bool {
remain := (1<<31 - 1) - f.n sum := f.n + n
if n > remain { if (sum > n) == (f.n > 0) {
return false f.n = sum
return true
} }
f.n += n return false
return true
} }
const http2frameHeaderLen = 9 const http2frameHeaderLen = 9
...@@ -5302,7 +5302,10 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error { ...@@ -5302,7 +5302,10 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error {
// Sender sending more than they'd declared? // Sender sending more than they'd declared?
if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { 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)) 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 { if f.Length > 0 {
// Check whether the client has flow control quota. // Check whether the client has flow control quota.
...@@ -6038,6 +6041,19 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { ...@@ -6038,6 +6041,19 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
http2foreachHeaderElement(v, rws.declareTrailer) 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 endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
err = rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{ err = rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{
streamID: rws.stream.id, streamID: rws.stream.id,
...@@ -6845,9 +6861,7 @@ func (http2noCachedConnError) Error() string { return "http2: no cached connecti ...@@ -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 // or its equivalent renamed type in net/http2's h2_bundle.go. Both types
// may coexist in the same running program. // may coexist in the same running program.
func http2isNoCachedConnError(err error) bool { func http2isNoCachedConnError(err error) bool {
_, ok := err.(interface { _, ok := err.(interface{ IsHTTP2NoCachedConnError() })
IsHTTP2NoCachedConnError()
})
return ok return ok
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment