From 54dab50015f8f881e77ed26c0676918676fdb888 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 6 Mar 2014 00:19:02 +0900 Subject: [PATCH] Support END_SEGMENT in nghttp2_submit_data() --- lib/includes/nghttp2/nghttp2.h | 3 ++- lib/nghttp2_frame.c | 7 ++--- lib/nghttp2_session.c | 7 +++-- lib/nghttp2_submit.c | 6 ++--- tests/main.c | 1 + tests/nghttp2_session_test.c | 48 ++++++++++++++++++++++++++++++++++ tests/nghttp2_session_test.h | 1 + 7 files changed, 63 insertions(+), 10 deletions(-) diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h index e2e427da..8aa91c32 100644 --- a/lib/includes/nghttp2/nghttp2.h +++ b/lib/includes/nghttp2/nghttp2.h @@ -2032,7 +2032,8 @@ int nghttp2_submit_headers(nghttp2_session *session, uint8_t flags, * Submits one or more DATA frames to the stream |stream_id|. The * data to be sent are provided by |data_prd|. If |flags| contains * :enum:`NGHTTP2_FLAG_END_STREAM`, the last DATA frame has END_STREAM - * flag set. + * flag set. If |flags| contains :enum:`NGHTTP2_FLAG_END_SEGMENT`, the + * last DATA frame has END_SEGMENT flag set. * * This function does not take ownership of the |data_prd|. The * function copies the members of the |data_prd|. diff --git a/lib/nghttp2_frame.c b/lib/nghttp2_frame.c index 1d73af84..b63a16aa 100644 --- a/lib/nghttp2_frame.c +++ b/lib/nghttp2_frame.c @@ -186,10 +186,11 @@ void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata) { frame->hd = pdata->hd; frame->padlen = pdata->padlen; - /* flags may have NGHTTP2_FLAG_END_STREAM even if the sent chunk - is not the end of the stream */ + /* flags may have NGHTTP2_FLAG_END_STREAM or + NGHTTP2_FLAG_END_SEGMENT even if the sent chunk is not the end of + the stream */ if(!pdata->eof) { - frame->hd.flags &= ~NGHTTP2_FLAG_END_STREAM; + frame->hd.flags &= ~(NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT); } } diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index 9263aa79..bfe14251 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -4532,14 +4532,17 @@ ssize_t nghttp2_session_pack_data(nghttp2_session *session, /* Clear flags, because this may contain previous flags of previous DATA */ - frame->hd.flags &= ~(NGHTTP2_FLAG_PAD_HIGH | NGHTTP2_FLAG_PAD_LOW); - flags = 0; + frame->hd.flags &= (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT); + flags = NGHTTP2_FLAG_NONE; if(eof_flags) { frame->eof = 1; if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { flags |= NGHTTP2_FLAG_END_STREAM; } + if(frame->hd.flags & NGHTTP2_FLAG_END_SEGMENT) { + flags |= NGHTTP2_FLAG_END_SEGMENT; + } } memset(&data_frame, 0, sizeof(data_frame)); diff --git a/lib/nghttp2_submit.c b/lib/nghttp2_submit.c index f9dfd464..7d50f21e 100644 --- a/lib/nghttp2_submit.c +++ b/lib/nghttp2_submit.c @@ -309,15 +309,13 @@ int nghttp2_submit_data(nghttp2_session *session, uint8_t flags, { int rv; nghttp2_private_data *data_frame; - uint8_t nflags = 0; + uint8_t nflags = flags & (NGHTTP2_FLAG_END_STREAM | + NGHTTP2_FLAG_END_SEGMENT); data_frame = malloc(sizeof(nghttp2_private_data)); if(data_frame == NULL) { return NGHTTP2_ERR_NOMEM; } - if(flags & NGHTTP2_FLAG_END_STREAM) { - nflags |= NGHTTP2_FLAG_END_STREAM; - } nghttp2_frame_private_data_init(data_frame, nflags, stream_id, data_prd); rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_DATA, data_frame, NULL); if(rv != 0) { diff --git a/tests/main.c b/tests/main.c index 2c038721..87384207 100644 --- a/tests/main.c +++ b/tests/main.c @@ -131,6 +131,7 @@ int main(int argc, char* argv[]) !CU_add_test(pSuite, "session_upgrade", test_nghttp2_session_upgrade) || !CU_add_test(pSuite, "session_reprioritize_stream", test_nghttp2_session_reprioritize_stream) || + !CU_add_test(pSuite, "submit_data", test_nghttp2_submit_data) || !CU_add_test(pSuite, "submit_request_with_data", test_nghttp2_submit_request_with_data) || !CU_add_test(pSuite, "submit_request_without_data", diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index a1328fb3..882a7b3b 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -2231,6 +2231,54 @@ void test_nghttp2_session_reprioritize_stream(void) nghttp2_session_del(session); } +void test_nghttp2_submit_data(void) +{ + nghttp2_session *session; + nghttp2_session_callbacks callbacks; + nghttp2_data_provider data_prd; + my_user_data ud; + nghttp2_private_data *data_frame; + nghttp2_frame_hd hd; + + memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); + callbacks.send_callback = block_count_send_callback; + + data_prd.read_callback = fixed_length_data_source_read_callback; + ud.data_source_length = NGHTTP2_DATA_PAYLOAD_LENGTH * 2; + CU_ASSERT(0 == nghttp2_session_client_new(&session, &callbacks, &ud)); + + nghttp2_session_open_stream(session, 1, NGHTTP2_STREAM_FLAG_NONE, + NGHTTP2_PRI_DEFAULT, NGHTTP2_STREAM_OPENING, + NULL); + CU_ASSERT(0 == nghttp2_submit_data(session, + NGHTTP2_FLAG_END_STREAM | + NGHTTP2_FLAG_END_SEGMENT, 1, &data_prd)); + ud.block_count = 0; + CU_ASSERT(0 == nghttp2_session_send(session)); + data_frame = nghttp2_outbound_item_get_data_frame(session->aob.item); + nghttp2_frame_unpack_frame_hd(&hd, + session->aob.framebuf + + session->aob.framebufoff); + CU_ASSERT(NGHTTP2_FLAG_NONE == hd.flags); + /* frame->hd.flags has these flags */ + CU_ASSERT((NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT) == + data_frame->hd.flags); + + ud.block_count = 1; + CU_ASSERT(0 == nghttp2_session_send(session)); + data_frame = nghttp2_outbound_item_get_data_frame(session->aob.item); + nghttp2_frame_unpack_frame_hd(&hd, + session->aob.framebuf + + session->aob.framebufoff); + /* This is the last frame, so we must have following flags */ + CU_ASSERT((NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT) == hd.flags); + /* frame->hd.flags has these flags */ + CU_ASSERT((NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT) == + data_frame->hd.flags); + + nghttp2_session_del(session); +} + void test_nghttp2_submit_request_with_data(void) { nghttp2_session *session; diff --git a/tests/nghttp2_session_test.h b/tests/nghttp2_session_test.h index 26680a58..146cc620 100644 --- a/tests/nghttp2_session_test.h +++ b/tests/nghttp2_session_test.h @@ -55,6 +55,7 @@ void test_nghttp2_session_send_push_promise(void); void test_nghttp2_session_is_my_stream_id(void); void test_nghttp2_session_upgrade(void); void test_nghttp2_session_reprioritize_stream(void); +void test_nghttp2_submit_data(void); void test_nghttp2_submit_request_with_data(void); void test_nghttp2_submit_request_without_data(void); void test_nghttp2_submit_response_with_data(void);