Browse Source

http2: a closed stream cannot receive data

Data sent on a closed stream is treated as a connection error of type
STREAM_CLOSED.

Updates golang/go#25023

Change-Id: I3a94414101ec08c7a3f20d49cefc0367af18017f
Reviewed-on: https://go-review.googlesource.com/111676
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
039a4258ae
2 changed files with 6 additions and 3 deletions
  1. 6 0
      http2/server.go
  2. 0 3
      http2/server_test.go

+ 6 - 0
http2/server.go

@@ -1575,6 +1575,12 @@ func (sc *serverConn) processData(f *DataFrame) error {
 		// type PROTOCOL_ERROR."
 		return ConnectionError(ErrCodeProtocol)
 	}
+	// RFC 7540, sec 6.1: If a DATA frame is received whose stream is not in
+	// "open" or "half-closed (local)" state, the recipient MUST respond with a
+	// stream error (Section 5.4.2) of type STREAM_CLOSED.
+	if state == stateClosed {
+		return streamError(id, ErrCodeStreamClosed)
+	}
 	if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
 		// This includes sending a RST_STREAM if the stream is
 		// in stateHalfClosedLocal (which currently means that

+ 0 - 3
http2/server_test.go

@@ -2396,9 +2396,6 @@ func TestServer_NoCrash_HandlerClose_Then_ClientClose(t *testing.T) {
 		// it did before.
 		st.writeData(1, true, []byte("foo"))
 
-		// Get our flow control bytes back, since the handler didn't get them.
-		st.wantWindowUpdate(0, uint32(len("foo")))
-
 		// Sent after a peer sends data anyway (admittedly the
 		// previous RST_STREAM might've still been in-flight),
 		// but they'll get the more friendly 'cancel' code