Ensure PRIORITY frame reception/transmission rule

This commit is contained in:
Tatsuhiro Tsujikawa 2014-01-09 22:06:38 +09:00
parent 95b0b6cb79
commit 45837a2cfa
2 changed files with 66 additions and 2 deletions

View File

@ -80,6 +80,22 @@ static int32_t nghttp2_pushed_stream_pri(nghttp2_stream *stream)
(int32_t)NGHTTP2_PRI_LOWEST : stream->pri + 1;
}
/* Returns nonzero if the |stream| is in reserved(remote) state */
static int state_reserved_remote(nghttp2_session *session,
nghttp2_stream *stream)
{
return stream->state == NGHTTP2_STREAM_RESERVED &&
!nghttp2_session_is_my_stream_id(session, stream->stream_id);
}
/* Returns nonzero if the |stream| is in reserved(local) state */
static int state_reserved_local(nghttp2_session *session,
nghttp2_stream *stream)
{
return stream->state == NGHTTP2_STREAM_RESERVED &&
nghttp2_session_is_my_stream_id(session, stream->stream_id);
}
int nghttp2_session_terminate_session(nghttp2_session *session,
nghttp2_error_code error_code)
{
@ -883,7 +899,11 @@ static int nghttp2_session_predicate_priority_send
if(stream->state == NGHTTP2_STREAM_CLOSING) {
return NGHTTP2_ERR_STREAM_CLOSING;
}
/* Sending PRIORITY to reserved state is OK */
/* PRIORITY must not be sent in reserved(local) */
if(state_reserved_local(session, stream)) {
return NGHTTP2_ERR_INVALID_STREAM_STATE;
}
/* Sending PRIORITY in reserved(remote) state is OK */
return 0;
}
@ -2133,6 +2153,10 @@ int nghttp2_session_on_priority_received(nghttp2_session *session,
if(!stream) {
return 0;
}
if(state_reserved_remote(session, stream)) {
return nghttp2_session_handle_invalid_connection(session, frame,
NGHTTP2_PROTOCOL_ERROR);
}
/* Only update priority on server side for now */
if(session->server) {
nghttp2_session_reprioritize_stream(session, stream,

View File

@ -1010,6 +1010,9 @@ void test_nghttp2_session_on_priority_received(void)
my_user_data user_data;
nghttp2_frame frame;
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.on_frame_recv_callback = on_frame_recv_callback;
callbacks.on_invalid_frame_recv_callback = on_invalid_frame_recv_callback;
nghttp2_session_server_new(&session, &callbacks, &user_data);
nghttp2_session_open_stream(session, 1, NGHTTP2_FLAG_NONE,
NGHTTP2_PRI_DEFAULT,
@ -1022,6 +1025,23 @@ void test_nghttp2_session_on_priority_received(void)
nghttp2_frame_priority_free(&frame.priority);
nghttp2_session_del(session);
/* Check that receiving PRIORITY in reserved(remote) is error */
nghttp2_session_server_new(&session, &callbacks, &user_data);
nghttp2_session_open_stream(session, 3, NGHTTP2_FLAG_NONE,
NGHTTP2_PRI_DEFAULT,
NGHTTP2_STREAM_RESERVED, NULL);
nghttp2_frame_priority_init(&frame.priority, 3, 123);
user_data.frame_recv_cb_called = 0;
user_data.invalid_frame_recv_cb_called = 0;
CU_ASSERT(0 == nghttp2_session_on_priority_received(session, &frame));
CU_ASSERT(0 == user_data.frame_recv_cb_called);
CU_ASSERT(1 == user_data.invalid_frame_recv_cb_called);
nghttp2_frame_priority_free(&frame.priority);
nghttp2_session_del(session);
}
void test_nghttp2_session_on_rst_stream_received(void)
@ -2197,11 +2217,14 @@ void test_nghttp2_submit_priority(void)
nghttp2_session *session;
nghttp2_session_callbacks callbacks;
nghttp2_stream *stream;
my_user_data ud;
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.send_callback = null_send_callback;
callbacks.on_frame_send_callback = on_frame_send_callback;
nghttp2_session_client_new(&session, &callbacks, NULL);
callbacks.on_frame_not_send_callback = on_frame_not_send_callback;
nghttp2_session_client_new(&session, &callbacks, &ud);
stream = nghttp2_session_open_stream(session, 1, NGHTTP2_FLAG_NONE,
NGHTTP2_PRI_DEFAULT,
NGHTTP2_STREAM_OPENING, NULL);
@ -2214,6 +2237,23 @@ void test_nghttp2_submit_priority(void)
CU_ASSERT(1000000007 == stream->pri);
nghttp2_session_del(session);
/* Check that transmission of PRIORITY in reserved(local) is
error */
nghttp2_session_server_new(&session, &callbacks, &ud);
stream = nghttp2_session_open_stream(session, 2, NGHTTP2_FLAG_NONE,
NGHTTP2_PRI_DEFAULT,
NGHTTP2_STREAM_RESERVED, NULL);
CU_ASSERT(0 == nghttp2_submit_priority(session, NGHTTP2_FLAG_NONE, 2, 123));
ud.frame_send_cb_called = 0;
ud.frame_not_send_cb_called = 0;
CU_ASSERT(0 == nghttp2_session_send(session));
CU_ASSERT(0 == ud.frame_send_cb_called);
CU_ASSERT(1 == ud.frame_not_send_cb_called);
nghttp2_session_del(session);
}
void test_nghttp2_submit_settings(void)