aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2018-06-29 19:23:35 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2018-06-29 21:45:46 +0000
commitcdce82485047bd0f7f5dc31d27326bb4ca869e53 (patch)
tree38b9ae2fcd281b4f02848fc8ab17a199c41f456e /src
parentf43aa1df701d7190eeaf301d3a41e1714c516c45 (diff)
downloadgo-cdce82485047bd0f7f5dc31d27326bb4ca869e53.tar.xz
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/121695 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/net/http/clientserver_test.go1
-rw-r--r--src/net/http/h2_bundle.go32
2 files changed, 23 insertions, 10 deletions
diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go
index b894be0813..c2a2548df1 100644
--- a/src/net/http/clientserver_test.go
+++ b/src/net/http/clientserver_test.go
@@ -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) {
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index f0dd8e6c76..053f81e257 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -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
}