diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index 59a5feec..455ba539 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -2151,6 +2151,8 @@ static ssize_t inflate_header_block(nghttp2_session *session, ssize_t rv; int inflate_flags; nghttp2_nv nv; + nghttp2_stream *stream; + *readlen_ptr = 0; DEBUGF(fprintf(stderr, "processing header block %zu bytes\n", inlen)); @@ -2163,15 +2165,26 @@ static ssize_t inflate_header_block(nghttp2_session *session, } if(rv < 0) { if(session->iframe.state == NGHTTP2_IB_READ_HEADER_BLOCK) { - rv = nghttp2_session_handle_invalid_connection - (session, frame, NGHTTP2_COMPRESSION_ERROR); - } else { - rv = nghttp2_session_terminate_session(session, - NGHTTP2_COMPRESSION_ERROR); + stream = nghttp2_session_get_stream(session, frame->hd.stream_id); + + if(stream && stream->state != NGHTTP2_STREAM_CLOSING) { + /* Adding RST_STREAM here is very important. It prevents + from invoking subsequent callbacks for the same stream + ID. */ + rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id, + NGHTTP2_COMPRESSION_ERROR); + + if(nghttp2_is_fatal(rv)) { + return rv; + } + } } - if(rv != 0) { + rv = nghttp2_session_terminate_session(session, + NGHTTP2_COMPRESSION_ERROR); + if(nghttp2_is_fatal(rv)) { return rv; } + return NGHTTP2_ERR_HEADER_COMP; } in += rv; diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index 14ed7bd7..354ec17c 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -879,8 +879,8 @@ void test_nghttp2_session_recv_premature_headers(void) item = nghttp2_session_get_next_ob_item(session); CU_ASSERT(NULL != item); - CU_ASSERT(NGHTTP2_GOAWAY == OB_CTRL_TYPE(item)); - CU_ASSERT(NGHTTP2_COMPRESSION_ERROR == OB_CTRL(item)->goaway.error_code); + CU_ASSERT(NGHTTP2_RST_STREAM == OB_CTRL_TYPE(item)); + CU_ASSERT(NGHTTP2_COMPRESSION_ERROR == OB_CTRL(item)->rst_stream.error_code); nghttp2_bufs_free(&bufs); nghttp2_hd_deflate_free(&deflater);