Browse Source

http2: receiving too much data is a protocol error

Updates golang/go#25023

Change-Id: Icd37dfef1b9558b0e774f1637c5566fb444666d5
Reviewed-on: https://go-review.googlesource.com/111679
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Michael Fraenkel 7 years ago
parent
commit
9ef9f5bb98
2 changed files with 23 additions and 1 deletions
  1. 4 1
      http2/server.go
  2. 19 0
      http2/server_test.go

+ 4 - 1
http2/server.go

@@ -1608,7 +1608,10 @@ func (sc *serverConn) processData(f *DataFrame) 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 streamError(id, ErrCodeStreamClosed)
+		// 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 streamError(id, ErrCodeProtocol)
 	}
 	}
 	if f.Length > 0 {
 	if f.Length > 0 {
 		// Check whether the client has flow control quota.
 		// Check whether the client has flow control quota.

+ 19 - 0
http2/server_test.go

@@ -3764,3 +3764,22 @@ func TestIssue20704Race(t *testing.T) {
 		resp.Body.Close()
 		resp.Body.Close()
 	}
 	}
 }
 }
+
+func TestServer_Rejects_TooSmall(t *testing.T) {
+	testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
+		return nil
+	}, func(st *serverTester) {
+		st.writeHeaders(HeadersFrameParam{
+			StreamID: 1, // clients send odd numbers
+			BlockFragment: st.encodeHeader(
+				":method", "POST",
+				"content-length", "4",
+			),
+			EndStream:  false, // to say DATA frames are coming
+			EndHeaders: true,
+		})
+		st.writeData(1, true, []byte("12345"))
+
+		st.wantRSTStream(1, ErrCodeProtocol)
+	})
+}