Support END_SEGMENT in nghttp2_submit_data()

This commit is contained in:
Tatsuhiro Tsujikawa 2014-03-06 00:19:02 +09:00
parent b60679808b
commit 54dab50015
7 changed files with 63 additions and 10 deletions

View File

@ -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 * Submits one or more DATA frames to the stream |stream_id|. The
* data to be sent are provided by |data_prd|. If |flags| contains * data to be sent are provided by |data_prd|. If |flags| contains
* :enum:`NGHTTP2_FLAG_END_STREAM`, the last DATA frame has END_STREAM * :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 * This function does not take ownership of the |data_prd|. The
* function copies the members of the |data_prd|. * function copies the members of the |data_prd|.

View File

@ -186,10 +186,11 @@ void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata)
{ {
frame->hd = pdata->hd; frame->hd = pdata->hd;
frame->padlen = pdata->padlen; frame->padlen = pdata->padlen;
/* flags may have NGHTTP2_FLAG_END_STREAM even if the sent chunk /* flags may have NGHTTP2_FLAG_END_STREAM or
is not the end of the stream */ NGHTTP2_FLAG_END_SEGMENT even if the sent chunk is not the end of
the stream */
if(!pdata->eof) { if(!pdata->eof) {
frame->hd.flags &= ~NGHTTP2_FLAG_END_STREAM; frame->hd.flags &= ~(NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT);
} }
} }

View File

@ -4532,14 +4532,17 @@ ssize_t nghttp2_session_pack_data(nghttp2_session *session,
/* Clear flags, because this may contain previous flags of previous /* Clear flags, because this may contain previous flags of previous
DATA */ DATA */
frame->hd.flags &= ~(NGHTTP2_FLAG_PAD_HIGH | NGHTTP2_FLAG_PAD_LOW); frame->hd.flags &= (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT);
flags = 0; flags = NGHTTP2_FLAG_NONE;
if(eof_flags) { if(eof_flags) {
frame->eof = 1; frame->eof = 1;
if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
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)); memset(&data_frame, 0, sizeof(data_frame));

View File

@ -309,15 +309,13 @@ int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
{ {
int rv; int rv;
nghttp2_private_data *data_frame; 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)); data_frame = malloc(sizeof(nghttp2_private_data));
if(data_frame == NULL) { if(data_frame == NULL) {
return NGHTTP2_ERR_NOMEM; 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); nghttp2_frame_private_data_init(data_frame, nflags, stream_id, data_prd);
rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_DATA, data_frame, NULL); rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_DATA, data_frame, NULL);
if(rv != 0) { if(rv != 0) {

View File

@ -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_upgrade", test_nghttp2_session_upgrade) ||
!CU_add_test(pSuite, "session_reprioritize_stream", !CU_add_test(pSuite, "session_reprioritize_stream",
test_nghttp2_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", !CU_add_test(pSuite, "submit_request_with_data",
test_nghttp2_submit_request_with_data) || test_nghttp2_submit_request_with_data) ||
!CU_add_test(pSuite, "submit_request_without_data", !CU_add_test(pSuite, "submit_request_without_data",

View File

@ -2231,6 +2231,54 @@ void test_nghttp2_session_reprioritize_stream(void)
nghttp2_session_del(session); 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) void test_nghttp2_submit_request_with_data(void)
{ {
nghttp2_session *session; nghttp2_session *session;

View File

@ -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_is_my_stream_id(void);
void test_nghttp2_session_upgrade(void); void test_nghttp2_session_upgrade(void);
void test_nghttp2_session_reprioritize_stream(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_with_data(void);
void test_nghttp2_submit_request_without_data(void); void test_nghttp2_submit_request_without_data(void);
void test_nghttp2_submit_response_with_data(void); void test_nghttp2_submit_response_with_data(void);