Respond RST_STREAM with PROTOCOL_ERROR when upper cased name is present in nv.
This commit is contained in:
parent
f71572b835
commit
938f51964d
|
@ -949,6 +949,33 @@ static int spdylay_session_is_new_peer_stream_id(spdylay_session *session,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns non-zero iff version == SPDYLAY_PROTO_VERSION
|
||||
*/
|
||||
static int spdylay_session_check_version(uint16_t version)
|
||||
{
|
||||
return version == SPDYLAY_PROTO_VERSION;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns non-zero iff name/value pairs |nv| are good shape.
|
||||
* Currently, we only checks whether names are lower cased. The spdy/2
|
||||
* spec requires that names must be lower cased.
|
||||
*/
|
||||
static int spdylay_session_check_nv(char **nv)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; nv[i]; i += 2) {
|
||||
int j;
|
||||
for(j = 0; nv[i][j] != '\0'; ++j) {
|
||||
if('A' <= nv[i][j] && nv[i][j] <= 'Z') {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validates SYN_STREAM frame |frame|. This function returns 0 if it
|
||||
* succeeds, or non-zero spdylay_status_code.
|
||||
|
@ -959,7 +986,7 @@ static int spdylay_session_validate_syn_stream(spdylay_session *session,
|
|||
if(!spdylay_session_is_new_peer_stream_id(session, frame->stream_id)) {
|
||||
return SPDYLAY_PROTOCOL_ERROR;
|
||||
}
|
||||
if(frame->hd.version != SPDYLAY_PROTO_VERSION) {
|
||||
if(!spdylay_session_check_version(frame->hd.version)) {
|
||||
return SPDYLAY_UNSUPPORTED_VERSION;
|
||||
}
|
||||
if(session->server) {
|
||||
|
@ -988,9 +1015,13 @@ static int spdylay_session_validate_syn_stream(spdylay_session *session,
|
|||
follow it. */
|
||||
return SPDYLAY_REFUSED_STREAM;
|
||||
}
|
||||
if(!spdylay_session_check_nv(frame->nv)) {
|
||||
return SPDYLAY_PROTOCOL_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int spdylay_session_handle_invalid_stream
|
||||
(spdylay_session *session,
|
||||
int32_t stream_id,
|
||||
|
@ -1070,14 +1101,6 @@ int spdylay_session_on_syn_stream_received(spdylay_session *session,
|
|||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns non-zero iff version == SPDYLAY_PROTOCOL_ERROR.
|
||||
*/
|
||||
static int spdylay_session_check_version(uint16_t version)
|
||||
{
|
||||
return version == SPDYLAY_PROTO_VERSION;
|
||||
}
|
||||
|
||||
int spdylay_session_on_syn_reply_received(spdylay_session *session,
|
||||
spdylay_frame *frame)
|
||||
{
|
||||
|
@ -1087,8 +1110,10 @@ int spdylay_session_on_syn_reply_received(spdylay_session *session,
|
|||
if(!spdylay_session_check_version(frame->syn_reply.hd.version)) {
|
||||
return 0;
|
||||
}
|
||||
stream = spdylay_session_get_stream(session, frame->syn_reply.stream_id);
|
||||
if(stream && (stream->shut_flags & SPDYLAY_SHUT_RD) == 0) {
|
||||
if((stream = spdylay_session_get_stream(session,
|
||||
frame->syn_reply.stream_id)) &&
|
||||
(stream->shut_flags & SPDYLAY_SHUT_RD) == 0 &&
|
||||
spdylay_session_check_nv(frame->syn_reply.nv)) {
|
||||
if(spdylay_session_is_my_stream_id(session, frame->syn_reply.stream_id)) {
|
||||
if(stream->state == SPDYLAY_STREAM_OPENING) {
|
||||
valid = 1;
|
||||
|
@ -1190,9 +1215,10 @@ int spdylay_session_on_headers_received(spdylay_session *session,
|
|||
if(!spdylay_session_check_version(frame->headers.hd.version)) {
|
||||
return 0;
|
||||
}
|
||||
stream = spdylay_session_get_stream(session, frame->headers.stream_id);
|
||||
/* First we check readability from this stream. */
|
||||
if(stream && (stream->shut_flags & SPDYLAY_SHUT_RD) == 0) {
|
||||
if((stream = spdylay_session_get_stream(session,
|
||||
frame->headers.stream_id)) &&
|
||||
(stream->shut_flags & SPDYLAY_SHUT_RD) == 0 &&
|
||||
spdylay_session_check_nv(frame->headers.nv)) {
|
||||
if(spdylay_session_is_my_stream_id(session, frame->headers.stream_id)) {
|
||||
if(stream->state == SPDYLAY_STREAM_OPENED) {
|
||||
valid = 1;
|
||||
|
|
|
@ -310,6 +310,7 @@ void test_spdylay_session_on_syn_stream_received()
|
|||
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;
|
||||
int32_t stream_id = 1;
|
||||
|
@ -341,6 +342,14 @@ void test_spdylay_session_on_syn_stream_received()
|
|||
CU_ASSERT(0 == spdylay_session_on_syn_stream_received(session, &frame));
|
||||
CU_ASSERT(2 == user_data.invalid_ctrl_recv_cb_called);
|
||||
|
||||
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||
|
||||
/* Upper cased name/value pairs */
|
||||
spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_FLAG_NONE, 3, 0, 3,
|
||||
dup_nv(upcase_nv));
|
||||
CU_ASSERT(0 == spdylay_session_on_syn_stream_received(session, &frame));
|
||||
CU_ASSERT(3 == user_data.invalid_ctrl_recv_cb_called);
|
||||
|
||||
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||
spdylay_session_del(session);
|
||||
}
|
||||
|
@ -409,6 +418,7 @@ void test_spdylay_session_on_syn_reply_received()
|
|||
};
|
||||
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;
|
||||
user_data.ctrl_recv_cb_called = 0;
|
||||
|
@ -441,6 +451,17 @@ void test_spdylay_session_on_syn_reply_received()
|
|||
CU_ASSERT(2 == user_data.invalid_ctrl_recv_cb_called);
|
||||
|
||||
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
||||
|
||||
/* Upper cased name/value pairs */
|
||||
spdylay_session_open_stream(session, 5, SPDYLAY_FLAG_NONE, 0,
|
||||
SPDYLAY_STREAM_OPENING, NULL);
|
||||
spdylay_frame_syn_reply_init(&frame.syn_reply, SPDYLAY_FLAG_NONE, 5,
|
||||
dup_nv(upcase_nv));
|
||||
CU_ASSERT(0 == spdylay_session_on_syn_reply_received(session, &frame));
|
||||
CU_ASSERT(3 == user_data.invalid_ctrl_recv_cb_called);
|
||||
|
||||
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
||||
|
||||
spdylay_session_del(session);
|
||||
}
|
||||
|
||||
|
@ -572,6 +593,7 @@ void test_spdylay_session_on_headers_received()
|
|||
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;
|
||||
memset(&callbacks, 0, sizeof(spdylay_session_callbacks));
|
||||
callbacks.on_ctrl_recv_callback = on_ctrl_recv_callback;
|
||||
|
@ -629,6 +651,18 @@ void test_spdylay_session_on_headers_received()
|
|||
CU_ASSERT(2 == user_data.invalid_ctrl_recv_cb_called);
|
||||
|
||||
spdylay_frame_headers_free(&frame.headers);
|
||||
|
||||
/* Upper cased name/value pairs */
|
||||
spdylay_session_open_stream(session, 5, SPDYLAY_FLAG_NONE, 0,
|
||||
SPDYLAY_STREAM_OPENED, NULL);
|
||||
spdylay_frame_headers_init(&frame.headers, SPDYLAY_FLAG_NONE, 5,
|
||||
dup_nv(upcase_nv));
|
||||
|
||||
CU_ASSERT(0 == spdylay_session_on_headers_received(session, &frame));
|
||||
CU_ASSERT(3 == user_data.invalid_ctrl_recv_cb_called);
|
||||
|
||||
spdylay_frame_headers_free(&frame.headers);
|
||||
|
||||
spdylay_session_del(session);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue