Issue stream error with the status code STREAM_IN_USE if multiple SYN_REPLY

frames are received for the same active stream ID.
This commit is contained in:
Tatsuhiro Tsujikawa 2012-03-11 22:42:22 +09:00
parent ce6dc1303e
commit 6024106695
2 changed files with 34 additions and 7 deletions

View File

@ -1529,6 +1529,7 @@ int spdylay_session_on_syn_reply_received(spdylay_session *session,
{
int r = 0;
int valid = 0;
int status_code = SPDYLAY_PROTOCOL_ERROR;
spdylay_stream *stream;
if(!spdylay_session_check_version(session, frame->syn_reply.hd.version)) {
return 0;
@ -1554,13 +1555,21 @@ int spdylay_session_on_syn_reply_received(spdylay_session *session,
that we queued RST_STREAM but it has not been sent. It will
eventually sent, so we just ignore this frame. */
valid = 1;
} else {
if(session->version == SPDYLAY_PROTO_SPDY3) {
/* SPDY/3 spec says if multiple SYN_REPLY frames for the
same active stream ID are received, the receiver must
issue a stream error with the status code
STREAM_IN_USE. */
status_code = SPDYLAY_STREAM_IN_USE;
}
}
}
}
if(!valid) {
r = spdylay_session_handle_invalid_stream
(session, frame->syn_reply.stream_id, SPDYLAY_SYN_REPLY, frame,
SPDYLAY_PROTOCOL_ERROR);
status_code);
}
return r;
}

View File

@ -473,20 +473,19 @@ void test_spdylay_session_on_syn_stream_received_with_push()
void test_spdylay_session_on_syn_reply_received()
{
spdylay_session *session;
spdylay_session_callbacks callbacks = {
NULL,
NULL,
on_ctrl_recv_callback,
on_invalid_ctrl_recv_callback
};
spdylay_session_callbacks callbacks;
my_user_data user_data;
const char *nv[] = { NULL };
const char *upcase_nv[] = { "version", "http/1.1", "methoD", "get", NULL };
spdylay_frame frame;
spdylay_stream *stream;
spdylay_outbound_item *item;
user_data.ctrl_recv_cb_called = 0;
user_data.invalid_ctrl_recv_cb_called = 0;
memset(&callbacks, 0, sizeof(spdylay_session_callbacks));
callbacks.on_ctrl_recv_callback = on_ctrl_recv_callback;
callbacks.on_invalid_ctrl_recv_callback = on_invalid_ctrl_recv_callback;
spdylay_session_client_new(&session, SPDYLAY_PROTO_SPDY2, &callbacks,
&user_data);
spdylay_session_open_stream(session, 1, SPDYLAY_CTRL_FLAG_NONE, 0,
@ -527,6 +526,25 @@ void test_spdylay_session_on_syn_reply_received()
spdylay_frame_syn_reply_free(&frame.syn_reply);
spdylay_session_del(session);
spdylay_session_client_new(&session, SPDYLAY_PROTO_SPDY3, &callbacks,
&user_data);
/* Multiple SYN_REPLY frames for the same active stream ID */
spdylay_session_open_stream(session, 1, SPDYLAY_CTRL_FLAG_NONE, 0,
SPDYLAY_STREAM_OPENED, NULL);
spdylay_frame_syn_reply_init(&frame.syn_reply, SPDYLAY_PROTO_SPDY3,
SPDYLAY_CTRL_FLAG_NONE, 1, dup_nv(nv));
user_data.invalid_ctrl_recv_cb_called = 0;
CU_ASSERT(0 == spdylay_session_on_syn_reply_received(session, &frame));
CU_ASSERT(1 == user_data.invalid_ctrl_recv_cb_called);
item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(SPDYLAY_RST_STREAM == item->frame_type);
CU_ASSERT(SPDYLAY_STREAM_IN_USE == item->frame->rst_stream.status_code);
spdylay_frame_syn_reply_free(&frame.syn_reply);
spdylay_session_del(session);
}
void test_spdylay_session_send_syn_stream()