From 35229b250f0e08b8928761c4e4e5d051c3f17d6d Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 20 Aug 2013 00:11:08 +0900 Subject: [PATCH] Treat reception of DATA in reserved stream as connection error --- lib/nghttp2_session.c | 7 ++++++- tests/nghttp2_session_test.c | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index 63afa480..978e6003 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -2571,6 +2571,9 @@ int nghttp2_session_on_data_received(nghttp2_session *session, } else if(stream->state != NGHTTP2_STREAM_CLOSING) { error_code = NGHTTP2_PROTOCOL_ERROR; } + } else if(stream->state == NGHTTP2_STREAM_RESERVED) { + /* reserved (remote) and receiving DATA is connection error */ + return nghttp2_session_fail_session(session, NGHTTP2_PROTOCOL_ERROR); } else if(stream->state != NGHTTP2_STREAM_CLOSING) { /* It is OK if this is remote peer initiated stream and we did not receive END_STREAM unless stream is in @@ -2740,10 +2743,12 @@ static int nghttp2_session_check_data_recv_allowed(nghttp2_session *session, if(stream->state == NGHTTP2_STREAM_OPENED) { return 1; } - } else if(stream->state != NGHTTP2_STREAM_CLOSING) { + } else if(stream->state != NGHTTP2_STREAM_CLOSING && + stream->state != NGHTTP2_STREAM_RESERVED) { /* It is OK if this is remote peer initiated stream and we did not receive END_STREAM unless stream is in NGHTTP2_STREAM_CLOSING state. This is a race condition. */ + /* But DATA must not be received in reserved state */ return 1; } } diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index cfcc7fcf..932caf37 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -1233,6 +1233,17 @@ void test_nghttp2_session_on_data_received(void) /* CU_ASSERT(NGHTTP2_RST_STREAM == OB_CTRL_TYPE(top)); */ /* CU_ASSERT(NGHTTP2_PROTOCOL_ERROR == OB_CTRL(top)->rst_stream.error_code); */ + /* Receiving DATA against the reserved stream is subject to + connection error */ + stream = nghttp2_session_open_stream(session, 6, NGHTTP2_FLAG_NONE, + NGHTTP2_PRI_DEFAULT, + NGHTTP2_STREAM_RESERVED, NULL); + CU_ASSERT(0 == nghttp2_session_on_data_received(session, 4096, + NGHTTP2_FLAG_NONE, 6)); + top = nghttp2_session_get_ob_pq_top(session); + CU_ASSERT(NGHTTP2_GOAWAY == OB_CTRL_TYPE(top)); + CU_ASSERT(NGHTTP2_PROTOCOL_ERROR == OB_CTRL(top)->goaway.error_code); + nghttp2_session_del(session); }