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
|
* Validates SYN_STREAM frame |frame|. This function returns 0 if it
|
||||||
* succeeds, or non-zero spdylay_status_code.
|
* 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)) {
|
if(!spdylay_session_is_new_peer_stream_id(session, frame->stream_id)) {
|
||||||
return SPDYLAY_PROTOCOL_ERROR;
|
return SPDYLAY_PROTOCOL_ERROR;
|
||||||
}
|
}
|
||||||
if(frame->hd.version != SPDYLAY_PROTO_VERSION) {
|
if(!spdylay_session_check_version(frame->hd.version)) {
|
||||||
return SPDYLAY_UNSUPPORTED_VERSION;
|
return SPDYLAY_UNSUPPORTED_VERSION;
|
||||||
}
|
}
|
||||||
if(session->server) {
|
if(session->server) {
|
||||||
|
@ -988,9 +1015,13 @@ static int spdylay_session_validate_syn_stream(spdylay_session *session,
|
||||||
follow it. */
|
follow it. */
|
||||||
return SPDYLAY_REFUSED_STREAM;
|
return SPDYLAY_REFUSED_STREAM;
|
||||||
}
|
}
|
||||||
|
if(!spdylay_session_check_nv(frame->nv)) {
|
||||||
|
return SPDYLAY_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int spdylay_session_handle_invalid_stream
|
static int spdylay_session_handle_invalid_stream
|
||||||
(spdylay_session *session,
|
(spdylay_session *session,
|
||||||
int32_t stream_id,
|
int32_t stream_id,
|
||||||
|
@ -1070,14 +1101,6 @@ int spdylay_session_on_syn_stream_received(spdylay_session *session,
|
||||||
return r;
|
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,
|
int spdylay_session_on_syn_reply_received(spdylay_session *session,
|
||||||
spdylay_frame *frame)
|
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)) {
|
if(!spdylay_session_check_version(frame->syn_reply.hd.version)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
stream = spdylay_session_get_stream(session, frame->syn_reply.stream_id);
|
if((stream = spdylay_session_get_stream(session,
|
||||||
if(stream && (stream->shut_flags & SPDYLAY_SHUT_RD) == 0) {
|
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(spdylay_session_is_my_stream_id(session, frame->syn_reply.stream_id)) {
|
||||||
if(stream->state == SPDYLAY_STREAM_OPENING) {
|
if(stream->state == SPDYLAY_STREAM_OPENING) {
|
||||||
valid = 1;
|
valid = 1;
|
||||||
|
@ -1190,9 +1215,10 @@ int spdylay_session_on_headers_received(spdylay_session *session,
|
||||||
if(!spdylay_session_check_version(frame->headers.hd.version)) {
|
if(!spdylay_session_check_version(frame->headers.hd.version)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
stream = spdylay_session_get_stream(session, frame->headers.stream_id);
|
if((stream = spdylay_session_get_stream(session,
|
||||||
/* First we check readability from this stream. */
|
frame->headers.stream_id)) &&
|
||||||
if(stream && (stream->shut_flags & SPDYLAY_SHUT_RD) == 0) {
|
(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(spdylay_session_is_my_stream_id(session, frame->headers.stream_id)) {
|
||||||
if(stream->state == SPDYLAY_STREAM_OPENED) {
|
if(stream->state == SPDYLAY_STREAM_OPENED) {
|
||||||
valid = 1;
|
valid = 1;
|
||||||
|
|
|
@ -310,6 +310,7 @@ void test_spdylay_session_on_syn_stream_received()
|
||||||
spdylay_session_callbacks callbacks;
|
spdylay_session_callbacks callbacks;
|
||||||
my_user_data user_data;
|
my_user_data user_data;
|
||||||
const char *nv[] = { NULL };
|
const char *nv[] = { NULL };
|
||||||
|
const char *upcase_nv[] = { "version", "http/1.1", "methoD", "get", NULL };
|
||||||
spdylay_frame frame;
|
spdylay_frame frame;
|
||||||
spdylay_stream *stream;
|
spdylay_stream *stream;
|
||||||
int32_t stream_id = 1;
|
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(0 == spdylay_session_on_syn_stream_received(session, &frame));
|
||||||
CU_ASSERT(2 == user_data.invalid_ctrl_recv_cb_called);
|
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_frame_syn_stream_free(&frame.syn_stream);
|
||||||
spdylay_session_del(session);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
@ -409,6 +418,7 @@ void test_spdylay_session_on_syn_reply_received()
|
||||||
};
|
};
|
||||||
my_user_data user_data;
|
my_user_data user_data;
|
||||||
const char *nv[] = { NULL };
|
const char *nv[] = { NULL };
|
||||||
|
const char *upcase_nv[] = { "version", "http/1.1", "methoD", "get", NULL };
|
||||||
spdylay_frame frame;
|
spdylay_frame frame;
|
||||||
spdylay_stream *stream;
|
spdylay_stream *stream;
|
||||||
user_data.ctrl_recv_cb_called = 0;
|
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);
|
CU_ASSERT(2 == user_data.invalid_ctrl_recv_cb_called);
|
||||||
|
|
||||||
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
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);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,6 +593,7 @@ void test_spdylay_session_on_headers_received()
|
||||||
spdylay_session_callbacks callbacks;
|
spdylay_session_callbacks callbacks;
|
||||||
my_user_data user_data;
|
my_user_data user_data;
|
||||||
const char *nv[] = { NULL };
|
const char *nv[] = { NULL };
|
||||||
|
const char *upcase_nv[] = { "version", "http/1.1", "methoD", "get", NULL };
|
||||||
spdylay_frame frame;
|
spdylay_frame frame;
|
||||||
memset(&callbacks, 0, sizeof(spdylay_session_callbacks));
|
memset(&callbacks, 0, sizeof(spdylay_session_callbacks));
|
||||||
callbacks.on_ctrl_recv_callback = on_ctrl_recv_callback;
|
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);
|
CU_ASSERT(2 == user_data.invalid_ctrl_recv_cb_called);
|
||||||
|
|
||||||
spdylay_frame_headers_free(&frame.headers);
|
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);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue