From e79de111a4d22939ff30c258143ea923bd4ae6be Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 28 Feb 2012 23:27:10 +0900 Subject: [PATCH] Added spdylay_submit_syn_reply --- lib/includes/spdylay/spdylay.h | 21 ++++++++++++++++++ lib/spdylay_submit.c | 32 ++++++++++++++++++++++++++++ tests/main.c | 1 + tests/spdylay_session_test.c | 39 ++++++++++++++++++++++++++++++++++ tests/spdylay_session_test.h | 1 + 5 files changed, 94 insertions(+) diff --git a/lib/includes/spdylay/spdylay.h b/lib/includes/spdylay/spdylay.h index 03854445..43e9852a 100644 --- a/lib/includes/spdylay/spdylay.h +++ b/lib/includes/spdylay/spdylay.h @@ -651,6 +651,27 @@ int spdylay_submit_syn_stream(spdylay_session *session, uint8_t flags, int32_t assoc_stream_id, uint8_t pri, const char **nv, void *stream_user_data); +/* + * Submits SYN_REPLY frame. The |flags| is bitwise OR of the following + * values: + * + * SPDYLAY_CTRL_FLAG_FIN + * + * If |flags| includes SPDYLAY_CTRL_FLAG_FIN, this frame has FIN flag + * set. + * + * The stream this frame belongs to is given in |stream_id|. The |nv| + * is the name/value pairs in this frame. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * SPDYLAY_ERR_NOMEM + * Out of memory. + */ +int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags, + int32_t stream_id, const char **nv); + /* * Submits HEADERS frame. The |flags| is bitwise OR of the following * values: diff --git a/lib/spdylay_submit.c b/lib/spdylay_submit.c index b7ae364d..762cd11e 100644 --- a/lib/spdylay_submit.c +++ b/lib/spdylay_submit.c @@ -107,6 +107,38 @@ int spdylay_submit_syn_stream(spdylay_session *session, uint8_t flags, pri, nv, NULL, stream_user_data); } +int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags, + int32_t stream_id, const char **nv) +{ + int r; + spdylay_frame *frame; + char **nv_copy; + uint8_t flags_copy; + frame = malloc(sizeof(spdylay_frame)); + if(frame == NULL) { + return SPDYLAY_ERR_NOMEM; + } + nv_copy = spdylay_frame_nv_copy(nv); + if(nv_copy == NULL) { + free(frame); + return SPDYLAY_ERR_NOMEM; + } + spdylay_frame_nv_downcase(nv_copy); + spdylay_frame_nv_sort(nv_copy); + flags_copy = 0; + if(flags & SPDYLAY_CTRL_FLAG_FIN) { + flags_copy |= SPDYLAY_CTRL_FLAG_FIN; + } + spdylay_frame_syn_reply_init(&frame->syn_reply, session->version, flags_copy, + stream_id, nv_copy); + r = spdylay_session_add_frame(session, SPDYLAY_SYN_REPLY, frame, NULL); + if(r != 0) { + spdylay_frame_syn_reply_free(&frame->syn_reply); + free(frame); + } + return r; +} + int spdylay_submit_headers(spdylay_session *session, uint8_t flags, int32_t stream_id, const char **nv) { diff --git a/tests/main.c b/tests/main.c index e7304f4f..58632d6f 100644 --- a/tests/main.c +++ b/tests/main.c @@ -94,6 +94,7 @@ int main(int argc, char* argv[]) test_spdylay_submit_request_with_null_data_read_callback) || !CU_add_test(pSuite, "submit_syn_stream", test_spdylay_submit_syn_stream) || + !CU_add_test(pSuite, "submit_syn_reply", test_spdylay_submit_syn_reply) || !CU_add_test(pSuite, "submit_headers", test_spdylay_submit_headers) || !CU_add_test(pSuite, "session_reply_fail", test_spdylay_session_reply_fail) || diff --git a/tests/spdylay_session_test.c b/tests/spdylay_session_test.c index 99bf0436..56b70ebf 100644 --- a/tests/spdylay_session_test.c +++ b/tests/spdylay_session_test.c @@ -681,6 +681,45 @@ void test_spdylay_submit_syn_stream() spdylay_session_del(session); } +void test_spdylay_submit_syn_reply() +{ + spdylay_session *session; + spdylay_session_callbacks callbacks; + const char *nv[] = { "version", "HTTP/1.1", NULL }; + my_user_data ud; + spdylay_outbound_item *item; + spdylay_stream *stream; + + memset(&callbacks, 0, sizeof(spdylay_session_callbacks)); + callbacks.send_callback = null_send_callback; + callbacks.on_ctrl_send_callback = on_ctrl_send_callback; + + CU_ASSERT(0 == spdylay_session_server_new(&session, SPDYLAY_PROTO_SPDY2, + &callbacks, &ud)); + CU_ASSERT(0 == spdylay_submit_syn_reply(session, SPDYLAY_CTRL_FLAG_FIN, 1, + nv)); + item = spdylay_session_get_next_ob_item(session); + CU_ASSERT(0 == strcmp("version", item->frame->syn_reply.nv[0])); + CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == item->frame->syn_reply.hd.flags); + + ud.ctrl_send_cb_called = 0; + ud.sent_frame_type = 0; + CU_ASSERT(0 == spdylay_session_send(session)); + CU_ASSERT(0 == ud.ctrl_send_cb_called); + + stream = spdylay_session_open_stream(session, 1, SPDYLAY_CTRL_FLAG_NONE, 3, + SPDYLAY_STREAM_OPENING, NULL); + + CU_ASSERT(0 == spdylay_submit_syn_reply(session, SPDYLAY_CTRL_FLAG_FIN, 1, + nv)); + CU_ASSERT(0 == spdylay_session_send(session)); + CU_ASSERT(1 == ud.ctrl_send_cb_called); + CU_ASSERT(SPDYLAY_SYN_REPLY == ud.sent_frame_type); + CU_ASSERT(stream->shut_flags & SPDYLAY_SHUT_WR); + + spdylay_session_del(session); +} + void test_spdylay_submit_headers() { spdylay_session *session; diff --git a/tests/spdylay_session_test.h b/tests/spdylay_session_test.h index e464e233..8b2ba2b8 100644 --- a/tests/spdylay_session_test.h +++ b/tests/spdylay_session_test.h @@ -39,6 +39,7 @@ void test_spdylay_submit_response_with_null_data_read_callback(); void test_spdylay_submit_request_with_data(); void test_spdylay_submit_request_with_null_data_read_callback(); void test_spdylay_submit_syn_stream(); +void test_spdylay_submit_syn_reply(); void test_spdylay_submit_headers(); void test_spdylay_session_reply_fail(); void test_spdylay_session_on_headers_received();