Add test to submit DATA frame twice

This commit adds test to submit DATA frame twice and fixes the bug
that 2nd DATA is not sent.
This commit is contained in:
Tatsuhiro Tsujikawa 2014-08-25 23:46:17 +09:00
parent 4c5c6749a0
commit 4c11cd0671
4 changed files with 81 additions and 3 deletions

View File

@ -2160,12 +2160,21 @@ static int session_after_frame_sent(nghttp2_session *session)
}
}
/* On EOF, we have already detached data if stream is not NULL.
If stream is NULL, we cannot detach data. Please note that
application may issue nghttp2_submit_data() in
on_frame_send_callback, which attach data to stream. We don't
want to detach it. */
if(data_frame->eof) {
active_outbound_item_reset(aob);
return 0;
}
/* If session is closed or RST_STREAM was queued, we won't send
further data. */
if(data_frame->eof ||
nghttp2_session_predicate_data_send(session,
if(nghttp2_session_predicate_data_send(session,
data_frame->hd.stream_id) != 0) {
if(stream) {
rv = nghttp2_stream_detach_data(stream, &session->ob_pq,
session->last_cycle);

View File

@ -144,6 +144,8 @@ int main(int argc, char* argv[])
!CU_add_test(pSuite, "submit_data", test_nghttp2_submit_data) ||
!CU_add_test(pSuite, "submit_data_read_length_too_large",
test_nghttp2_submit_data_read_length_too_large) ||
!CU_add_test(pSuite, "submit_data_twice",
test_nghttp2_submit_data_twice) ||
!CU_add_test(pSuite, "submit_request_with_data",
test_nghttp2_submit_request_with_data) ||
!CU_add_test(pSuite, "submit_request_without_data",

View File

@ -3207,6 +3207,72 @@ void test_nghttp2_submit_data_read_length_smallest(void)
nghttp2_session_del(session);
}
static ssize_t submit_data_twice_data_source_read_callback
(nghttp2_session *session, int32_t stream_id,
uint8_t *buf, size_t len, uint32_t *data_flags,
nghttp2_data_source *source, void *user_data)
{
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
return nghttp2_min(len, 16);
}
static int submit_data_twice_on_frame_send_callback(nghttp2_session *session,
const nghttp2_frame *frame,
void *user_data)
{
static int called = 0;
int rv;
nghttp2_data_provider data_prd;
if(called == 0) {
called = 1;
data_prd.read_callback = submit_data_twice_data_source_read_callback;
rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM,
frame->hd.stream_id, &data_prd);
CU_ASSERT(0 == rv);
}
return 0;
}
void test_nghttp2_submit_data_twice(void)
{
nghttp2_session *session;
nghttp2_session_callbacks callbacks;
nghttp2_data_provider data_prd;
my_user_data ud;
accumulator acc;
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.send_callback = accumulator_send_callback;
callbacks.on_frame_send_callback = submit_data_twice_on_frame_send_callback;
data_prd.read_callback = submit_data_twice_data_source_read_callback;
acc.length = 0;
ud.acc = &acc;
CU_ASSERT(0 == nghttp2_session_client_new(&session, &callbacks, &ud));
nghttp2_session_open_stream(session, 1, NGHTTP2_STREAM_FLAG_NONE,
&pri_spec_default, NGHTTP2_STREAM_OPENING,
NULL);
CU_ASSERT(0 == nghttp2_submit_data(session,
NGHTTP2_FLAG_NONE, 1, &data_prd));
CU_ASSERT(0 == nghttp2_session_send(session));
fprintf(stderr, "acc.length=%zu\n", acc.length);
/* We should have sent 2 DATA frame with 16 bytes payload each */
CU_ASSERT(NGHTTP2_FRAME_HDLEN * 2 + 16 * 2 == acc.length);
nghttp2_session_del(session);
}
void test_nghttp2_submit_request_with_data(void)
{
nghttp2_session *session;

View File

@ -64,6 +64,7 @@ void test_nghttp2_session_reprioritize_stream(void);
void test_nghttp2_submit_data(void);
void test_nghttp2_submit_data_read_length_too_large(void);
void test_nghttp2_submit_data_read_length_smallest(void);
void test_nghttp2_submit_data_twice(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);