From a3082b7c1e0987d4bd8a8d43583972c57ae31c1f Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Mon, 27 Jan 2014 22:13:41 +0900 Subject: [PATCH] Remove nghttp2_on_data_recv_callback and nghttp2_on_data_send_callback nghttp2_data is added to nghttp2_frame union. When DATA is received, nghttp2_on_frame_recv_callback is called. When DATA is sent, nghttp2_on_frame_send_callback is called. --- lib/includes/nghttp2/nghttp2.h | 81 ++++++++++------------------------ lib/nghttp2_frame.c | 9 ++-- lib/nghttp2_frame.h | 9 ++-- lib/nghttp2_outbound_item.c | 2 +- lib/nghttp2_session.c | 69 ++++++++++++++++------------- lib/nghttp2_session.h | 8 ++-- lib/nghttp2_submit.c | 4 +- src/HttpServer.cc | 36 ++------------- src/app_helper.cc | 39 +--------------- src/app_helper.h | 8 ---- src/nghttp.cc | 2 - src/shrpx_http2_upstream.cc | 27 +++++------- tests/nghttp2_session_test.c | 81 +++++++++++++++++----------------- 13 files changed, 138 insertions(+), 237 deletions(-) diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h index 43cbf96d..ce91c987 100644 --- a/lib/includes/nghttp2/nghttp2.h +++ b/lib/includes/nghttp2/nghttp2.h @@ -579,6 +579,16 @@ typedef struct { nghttp2_data_source_read_callback read_callback; } nghttp2_data_provider; +/** + * @struct + * + * The DATA frame. The received data is delivered via + * :type:`nghttp2_on_data_chunk_recv_callback`. + */ +typedef struct { + nghttp2_frame_hd hd; +} nghttp2_data; + /** * @enum * @@ -795,6 +805,10 @@ typedef union { * The frame header, which is convenient to inspect frame header. */ nghttp2_frame_hd hd; + /** + * The DATA frame. + */ + nghttp2_data data; /** * The HEADERS frame. */ @@ -869,9 +883,9 @@ typedef ssize_t (*nghttp2_recv_callback) /** * @functypedef * - * Callback function invoked by `nghttp2_session_recv()` when a - * non-DATA frame is received. The |user_data| pointer is the third - * argument passed in to the call to `nghttp2_session_client_new()` or + * Callback function invoked by `nghttp2_session_recv()` when a aframe + * is received. The |user_data| pointer is the third argument passed + * in to the call to `nghttp2_session_client_new()` or * `nghttp2_session_server_new()`. * * If frame is HEADERS or PUSH_PROMISE, the ``nva`` and ``nvlen`` @@ -923,7 +937,7 @@ typedef int (*nghttp2_on_invalid_frame_recv_callback) * to. The |flags| is the flags of DATA frame which this data chunk is * contained. ``(flags & NGHTTP2_FLAG_END_STREAM) != 0`` does not * necessarily mean this chunk of data is the last one in the - * stream. You should use :type:`nghttp2_on_data_recv_callback` to + * stream. You should use :type:`nghttp2_on_frame_recv_callback` to * know all data frames are received. The |user_data| pointer is the * third argument passed in to the call to * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. @@ -946,24 +960,6 @@ typedef int (*nghttp2_on_data_chunk_recv_callback) (nghttp2_session *session, uint8_t flags, int32_t stream_id, const uint8_t *data, size_t len, void *user_data); -/** - * @functypedef - * - * Callback function invoked when DATA frame is received. The actual - * data it contains are received by - * :type:`nghttp2_on_data_chunk_recv_callback`. The |user_data| - * pointer is the third argument passed in to the call to - * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. - * - * The implementation of this function must return 0 if it - * succeeds. If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_recv()` and `nghttp2_session_send()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. - */ -typedef int (*nghttp2_on_data_recv_callback) -(nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, - void *user_data); - /** * @functypedef * @@ -986,10 +982,9 @@ typedef int (*nghttp2_before_frame_send_callback) /** * @functypedef * - * Callback function invoked after the non-DATA frame |frame| is sent. - * The |user_data| pointer is the third argument passed in to the call - * to `nghttp2_session_client_new()` or - * `nghttp2_session_server_new()`. + * Callback function invoked after the frame |frame| is sent. The + * |user_data| pointer is the third argument passed in to the call to + * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. * * The implementation of this function must return 0 if it * succeeds. If nonzero is returned, it is treated as fatal error and @@ -1018,22 +1013,6 @@ typedef int (*nghttp2_on_frame_not_send_callback) (nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, void *user_data); -/** - * @functypedef - * - * Callback function invoked after DATA frame is sent. The |user_data| - * pointer is the third argument passed in to the call to - * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. - * - * The implementation of this function must return 0 if it - * succeeds. If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_recv()` and `nghttp2_session_send()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. - */ -typedef int (*nghttp2_on_data_send_callback) -(nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, - void *user_data); - /** * @functypedef * @@ -1190,10 +1169,6 @@ typedef struct { * received. */ nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback; - /** - * Callback function invoked when DATA frame is received. - */ - nghttp2_on_data_recv_callback on_data_recv_callback; /** * Callback function invoked before the non-DATA frame is sent. */ @@ -1207,10 +1182,6 @@ typedef struct { * because of an error. */ nghttp2_on_frame_not_send_callback on_frame_not_send_callback; - /** - * Callback function invoked after DATA frame is sent. - */ - nghttp2_on_data_send_callback on_data_send_callback; /** * Callback function invoked when the stream is closed. */ @@ -1432,13 +1403,9 @@ void nghttp2_session_del(nghttp2_session *session); * invoked. * 6. :member:`nghttp2_session_callbacks.send_callback` is invoked one * or more times to send the frame. - * 7. If the frame is a control frame, - * :member:`nghttp2_session_callbacks.on_frame_send_callback` is + * 7. :member:`nghttp2_session_callbacks.on_frame_send_callback` is * invoked. - * 8. If the frame is a DATA frame, - * :member:`nghttp2_session_callbacks.on_data_send_callback` is - * invoked. - * 9. If the transmission of the frame triggers closure of the stream, + * 8. If the transmission of the frame triggers closure of the stream, * the stream is closed and * :member:`nghttp2_session_callbacks.on_stream_close_callback` is * invoked. @@ -1474,7 +1441,7 @@ int nghttp2_session_send(nghttp2_session *session); * :member:`nghttp2_session_callbacks.on_data_chunk_recv_callback` * is invoked. * 2. If one DATA frame is completely received, - * :member:`nghttp2_session_callbacks.on_data_recv_callback` is + * :member:`nghttp2_session_callbacks.on_frame_recv_callback` is * invoked. If the frame is the final frame of the request, * :member:`nghttp2_session_callbacks.on_request_recv_callback` * is invoked. If the reception of the frame triggers the diff --git a/lib/nghttp2_frame.c b/lib/nghttp2_frame.c index adb05650..c389d8b8 100644 --- a/lib/nghttp2_frame.c +++ b/lib/nghttp2_frame.c @@ -181,9 +181,10 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame, void nghttp2_frame_window_update_free(nghttp2_window_update *frame) {} -void nghttp2_frame_data_init(nghttp2_private_data *frame, uint8_t flags, - int32_t stream_id, - const nghttp2_data_provider *data_prd) +void nghttp2_frame_private_data_init(nghttp2_private_data *frame, + uint8_t flags, + int32_t stream_id, + const nghttp2_data_provider *data_prd) { memset(frame, 0, sizeof(nghttp2_private_data)); /* At this moment, the length of DATA frame is unknown */ @@ -191,7 +192,7 @@ void nghttp2_frame_data_init(nghttp2_private_data *frame, uint8_t flags, frame->data_prd = *data_prd; } -void nghttp2_frame_data_free(nghttp2_private_data *frame) +void nghttp2_frame_private_data_free(nghttp2_private_data *frame) {} /* diff --git a/lib/nghttp2_frame.h b/lib/nghttp2_frame.h index ec07e373..570158be 100644 --- a/lib/nghttp2_frame.h +++ b/lib/nghttp2_frame.h @@ -416,11 +416,12 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame, void nghttp2_frame_window_update_free(nghttp2_window_update *frame); -void nghttp2_frame_data_init(nghttp2_private_data *frame, uint8_t flags, - int32_t stream_id, - const nghttp2_data_provider *data_prd); +void nghttp2_frame_private_data_init(nghttp2_private_data *frame, + uint8_t flags, + int32_t stream_id, + const nghttp2_data_provider *data_prd); -void nghttp2_frame_data_free(nghttp2_private_data *frame); +void nghttp2_frame_private_data_free(nghttp2_private_data *frame); /* * Makes copy of |iv| and return the copy. The |niv| is the number of diff --git a/lib/nghttp2_outbound_item.c b/lib/nghttp2_outbound_item.c index 26782013..e1386c2f 100644 --- a/lib/nghttp2_outbound_item.c +++ b/lib/nghttp2_outbound_item.c @@ -66,7 +66,7 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item) } else if(item->frame_cat == NGHTTP2_CAT_DATA) { nghttp2_private_data *data_frame; data_frame = nghttp2_outbound_item_get_data_frame(item); - nghttp2_frame_data_free(data_frame); + nghttp2_frame_private_data_free(data_frame); } else { /* Unreachable */ assert(0); diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index da553bd9..aee44fb3 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -1387,6 +1387,20 @@ nghttp2_outbound_item* nghttp2_session_pop_next_ob_item } } +static int session_call_on_frame_send(nghttp2_session *session, + nghttp2_frame *frame) +{ + int rv; + if(session->callbacks.on_frame_send_callback) { + rv = session->callbacks.on_frame_send_callback(session, frame, + session->user_data); + if(rv != 0) { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + } + return 0; +} + /* * Called after a frame is sent. * @@ -1431,11 +1445,9 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session) CONTINUATION frame. */ frame->hd.length = session->aob.framebuflen - NGHTTP2_FRAME_HEAD_LENGTH; } - if(session->callbacks.on_frame_send_callback) { - if(session->callbacks.on_frame_send_callback(session, frame, - session->user_data) != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } + r = session_call_on_frame_send(session, frame); + if(nghttp2_is_fatal(r)) { + return r; } switch(frame->hd.type) { case NGHTTP2_HEADERS: { @@ -1573,16 +1585,18 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session) } else if(item->frame_cat == NGHTTP2_CAT_DATA) { int r; nghttp2_private_data *data_frame; + data_frame = nghttp2_outbound_item_get_data_frame(session->aob.item); - if(session->callbacks.on_data_send_callback) { - if(session->callbacks.on_data_send_callback - (session, - session->aob.framebuflen - NGHTTP2_FRAME_HEAD_LENGTH, - data_frame->eof ? data_frame->hd.flags : - (data_frame->hd.flags & (~NGHTTP2_FLAG_END_STREAM)), - data_frame->hd.stream_id, - session->user_data) != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; + if(session->callbacks.on_frame_send_callback) { + nghttp2_frame public_data_frame = { data_frame->hd }; + /* flags may have NGHTTP2_FLAG_END_STREAM even if the sent chunk + is not the end of the stream */ + if(!data_frame->eof) { + public_data_frame.hd.flags &= ~NGHTTP2_FLAG_END_STREAM; + } + r = session_call_on_frame_send(session, &public_data_frame); + if(nghttp2_is_fatal(r)) { + return r; } } if(data_frame->eof && (data_frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { @@ -3137,34 +3151,31 @@ static int session_process_window_update_frame(nghttp2_session *session) /* } */ int nghttp2_session_on_data_received(nghttp2_session *session, - uint16_t length, uint8_t flags, - int32_t stream_id) + nghttp2_frame *frame) { int rv = 0; nghttp2_stream *stream; - stream = nghttp2_session_get_stream(session, stream_id); + stream = nghttp2_session_get_stream(session, frame->hd.stream_id); if(!stream) { /* This should be treated as stream error, but it results in lots of RST_STREAM. So just ignore frame against nonexistent stream for now. */ return 0; } - if(session->callbacks.on_data_recv_callback) { - if(session->callbacks.on_data_recv_callback - (session, length, flags, stream_id, session->user_data) != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } + rv = nghttp2_session_call_on_frame_received(session, frame); + if(nghttp2_is_fatal(rv)) { + return rv; } - if(!nghttp2_session_is_my_stream_id(session, stream_id)) { - if(flags & NGHTTP2_FLAG_END_STREAM) { - rv = nghttp2_session_call_on_request_recv(session, stream_id); + if(!nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { + if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { + rv = nghttp2_session_call_on_request_recv(session, frame->hd.stream_id); if(rv != 0) { return rv; } } } - if(flags & NGHTTP2_FLAG_END_STREAM) { + if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream); if(nghttp2_is_fatal(rv)) { @@ -3178,10 +3189,8 @@ int nghttp2_session_on_data_received(nghttp2_session *session, static int nghttp2_session_process_data_frame(nghttp2_session *session) { int r; - nghttp2_frame *frame = &session->iframe.frame; - r = nghttp2_session_on_data_received(session, - frame->hd.length, frame->hd.flags, - frame->hd.stream_id); + nghttp2_frame *public_data_frame = &session->iframe.frame; + r = nghttp2_session_on_data_received(session, public_data_frame); if(nghttp2_is_fatal(r)) { return r; } else { diff --git a/lib/nghttp2_session.h b/lib/nghttp2_session.h index fab43caa..59f2a911 100644 --- a/lib/nghttp2_session.h +++ b/lib/nghttp2_session.h @@ -488,17 +488,19 @@ int nghttp2_session_on_window_update_received(nghttp2_session *session, nghttp2_frame *frame); /* - * Called when DATA is received. + * Called when DATA is received, assuming |frame| is properly + * initialized. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * * NGHTTP2_ERR_NOMEM * Out of memory. + * NGHTTP2_ERR_CALLBACK_FAILURE + * The callback function failed. */ int nghttp2_session_on_data_received(nghttp2_session *session, - uint16_t length, uint8_t flags, - int32_t stream_id); + nghttp2_frame *frame); /* * Returns nghttp2_stream* object whose stream ID is |stream_id|. It diff --git a/lib/nghttp2_submit.c b/lib/nghttp2_submit.c index e74ec94d..31e56d72 100644 --- a/lib/nghttp2_submit.c +++ b/lib/nghttp2_submit.c @@ -311,10 +311,10 @@ int nghttp2_submit_data(nghttp2_session *session, uint8_t flags, if(flags & NGHTTP2_FLAG_END_STREAM) { nflags |= NGHTTP2_FLAG_END_STREAM; } - nghttp2_frame_data_init(data_frame, nflags, stream_id, data_prd); + nghttp2_frame_private_data_init(data_frame, nflags, stream_id, data_prd); r = nghttp2_session_add_frame(session, NGHTTP2_CAT_DATA, data_frame, NULL); if(r != 0) { - nghttp2_frame_data_free(data_frame); + nghttp2_frame_private_data_free(data_frame); free(data_frame); } return r; diff --git a/src/HttpServer.cc b/src/HttpServer.cc index b1001163..96ac0411 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -853,6 +853,9 @@ int hd_on_frame_recv_callback verbose_on_frame_recv_callback(session, frame, user_data); } switch(frame->hd.type) { + case NGHTTP2_DATA: + // TODO Handle POST + break; case NGHTTP2_HEADERS: switch(frame->headers.cat) { case NGHTTP2_HCAT_REQUEST: { @@ -939,37 +942,6 @@ int on_data_chunk_recv_callback } } // namespace -namespace { -int hd_on_data_recv_callback -(nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, - void *user_data) -{ - // TODO Handle POST - auto hd = static_cast(user_data); - if(hd->get_config()->verbose) { - print_session_id(hd->session_id()); - verbose_on_data_recv_callback(session, length, flags, stream_id, - user_data); - } - return 0; -} -} // namespace - -namespace { -int hd_on_data_send_callback -(nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, - void *user_data) -{ - auto hd = static_cast(user_data); - if(hd->get_config()->verbose) { - print_session_id(hd->session_id()); - verbose_on_data_send_callback(session, length, flags, stream_id, - user_data); - } - return 0; -} -} // namespace - namespace { int on_stream_close_callback (nghttp2_session *session, int32_t stream_id, nghttp2_error_code error_code, @@ -997,8 +969,6 @@ void fill_callback(nghttp2_session_callbacks& callbacks, const Config *config) callbacks.on_frame_recv_callback = hd_on_frame_recv_callback; callbacks.before_frame_send_callback = hd_before_frame_send_callback; callbacks.on_frame_send_callback = hd_on_frame_send_callback; - callbacks.on_data_recv_callback = hd_on_data_recv_callback; - callbacks.on_data_send_callback = hd_on_data_send_callback; if(config->verbose) { callbacks.on_invalid_frame_recv_callback = verbose_on_invalid_frame_recv_callback; diff --git a/src/app_helper.cc b/src/app_helper.cc index 4c14502e..42290856 100644 --- a/src/app_helper.cc +++ b/src/app_helper.cc @@ -262,6 +262,8 @@ void print_frame(print_type ptype, const nghttp2_frame *frame) print_flags(frame->hd); } switch(frame->hd.type) { + case NGHTTP2_DATA: + break; case NGHTTP2_HEADERS: if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY) { print_frame_attr_indent(); @@ -411,43 +413,6 @@ int verbose_on_frame_send_callback return 0; } -namespace { -void print_data_frame(print_type ptype, uint16_t length, uint8_t flags, - int32_t stream_id) -{ - printf("%sDATA%s frame ", - frame_name_ansi_esc(ptype), ansi_escend()); - nghttp2_frame_hd hd = {length, stream_id, NGHTTP2_DATA, flags}; - print_frame_hd(hd); - if(flags) { - print_frame_attr_indent(); - print_flags(hd); - } -} -} // namespace - -int verbose_on_data_recv_callback -(nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, - void *user_data) -{ - print_timer(); - printf(" recv "); - print_data_frame(PRINT_RECV, length, flags, stream_id); - fflush(stdout); - return 0; -} - -int verbose_on_data_send_callback -(nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, - void *user_data) -{ - print_timer(); - printf(" send "); - print_data_frame(PRINT_SEND, length, flags, stream_id); - fflush(stdout); - return 0; -} - namespace { std::chrono::steady_clock::time_point base_tv; } // namespace diff --git a/src/app_helper.h b/src/app_helper.h index 60034750..8e54bbe8 100644 --- a/src/app_helper.h +++ b/src/app_helper.h @@ -62,14 +62,6 @@ int verbose_on_unknown_frame_recv_callback(nghttp2_session *session, int verbose_on_frame_send_callback (nghttp2_session *session, const nghttp2_frame *frame, void *user_data); -int verbose_on_data_recv_callback -(nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, - void *user_data); - -int verbose_on_data_send_callback -(nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, - void *user_data); - // Returns difference between |a| and |b| in milliseconds, assuming // |a| is more recent than |b|. template diff --git a/src/nghttp.cc b/src/nghttp.cc index 8b37ab02..5c21cc89 100644 --- a/src/nghttp.cc +++ b/src/nghttp.cc @@ -1585,8 +1585,6 @@ int run(char **uris, int n) callbacks.before_frame_send_callback = before_frame_send_callback; if(config.verbose) { callbacks.on_frame_send_callback = verbose_on_frame_send_callback; - callbacks.on_data_recv_callback = verbose_on_data_recv_callback; - callbacks.on_data_send_callback = verbose_on_data_send_callback; callbacks.on_invalid_frame_recv_callback = verbose_on_invalid_frame_recv_callback; callbacks.on_unknown_frame_recv_callback = diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc index 13ec1903..674718ed 100644 --- a/src/shrpx_http2_upstream.cc +++ b/src/shrpx_http2_upstream.cc @@ -347,6 +347,17 @@ int on_frame_recv_callback int rv; auto upstream = static_cast(user_data); switch(frame->hd.type) { + case NGHTTP2_DATA: { + auto downstream = upstream->find_downstream(frame->hd.stream_id); + if(!downstream) { + break; + } + if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { + downstream->end_upload_data(); + downstream->set_request_state(Downstream::MSG_COMPLETE); + } + break; + } case NGHTTP2_HEADERS: { if(frame->headers.cat != NGHTTP2_HCAT_REQUEST) { break; @@ -412,21 +423,6 @@ int on_data_chunk_recv_callback(nghttp2_session *session, } } // namespace -namespace { -int on_data_recv_callback(nghttp2_session *session, - uint16_t length, uint8_t flags, int32_t stream_id, - void *user_data) -{ - auto upstream = static_cast(user_data); - auto downstream = upstream->find_downstream(stream_id); - if(downstream && (flags & NGHTTP2_FLAG_END_STREAM)) { - downstream->end_upload_data(); - downstream->set_request_state(Downstream::MSG_COMPLETE); - } - return 0; -} -} // namespace - namespace { int on_frame_send_callback(nghttp2_session* session, const nghttp2_frame *frame, void *user_data) @@ -506,7 +502,6 @@ Http2Upstream::Http2Upstream(ClientHandler *handler) callbacks.on_stream_close_callback = on_stream_close_callback; callbacks.on_frame_recv_callback = on_frame_recv_callback; callbacks.on_data_chunk_recv_callback = on_data_chunk_recv_callback; - callbacks.on_data_recv_callback = on_data_recv_callback; callbacks.on_frame_send_callback = on_frame_send_callback; callbacks.on_frame_not_send_callback = on_frame_not_send_callback; callbacks.on_unknown_frame_recv_callback = on_unknown_frame_recv_callback; diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index f63d931e..6d675a14 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -66,7 +66,6 @@ typedef struct { int32_t stream_id; size_t block_count; int data_chunk_recv_cb_called; - int data_recv_cb_called; const nghttp2_frame *frame; size_t fixed_sendlen; int header_cb_called; @@ -201,15 +200,6 @@ static int pause_on_data_chunk_recv_callback(nghttp2_session *session, return NGHTTP2_ERR_PAUSE; } -static int on_data_recv_callback(nghttp2_session *session, - uint16_t length, uint8_t flags, - int32_t stream_id, void *user_data) -{ - my_user_data *ud = (my_user_data*)user_data; - ++ud->data_recv_cb_called; - return 0; -} - static ssize_t fixed_length_data_source_read_callback (nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t len, int *eof, @@ -553,7 +543,7 @@ void test_nghttp2_session_recv_data(void) memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); callbacks.send_callback = null_send_callback; callbacks.on_data_chunk_recv_callback = on_data_chunk_recv_callback; - callbacks.on_data_recv_callback = on_data_recv_callback; + callbacks.on_frame_recv_callback = on_frame_recv_callback; nghttp2_session_client_new(&session, &callbacks, &ud); @@ -568,12 +558,12 @@ void test_nghttp2_session_recv_data(void) /* stream 1 is not opened, so it must be responded with connection error. This is not mandated by the spec */ ud.data_chunk_recv_cb_called = 0; - ud.data_recv_cb_called = 0; + ud.frame_recv_cb_called = 0; rv = nghttp2_session_mem_recv(session, data, 8+4096); CU_ASSERT(8+4096 == rv); CU_ASSERT(0 == ud.data_chunk_recv_cb_called); - CU_ASSERT(0 == ud.data_recv_cb_called); + CU_ASSERT(0 == ud.frame_recv_cb_called); item = nghttp2_session_get_next_ob_item(session); CU_ASSERT(NULL == item); @@ -587,12 +577,12 @@ void test_nghttp2_session_recv_data(void) stream->local_window_size = 16383; ud.data_chunk_recv_cb_called = 0; - ud.data_recv_cb_called = 0; + ud.frame_recv_cb_called = 0; rv = nghttp2_session_mem_recv(session, data, 8+4096); CU_ASSERT(8+4096 == rv); CU_ASSERT(0 == ud.data_chunk_recv_cb_called); - CU_ASSERT(0 == ud.data_recv_cb_called); + CU_ASSERT(0 == ud.frame_recv_cb_called); item = nghttp2_session_get_next_ob_item(session); CU_ASSERT(NULL == item); @@ -600,24 +590,24 @@ void test_nghttp2_session_recv_data(void) stream->state = NGHTTP2_STREAM_OPENED; ud.data_chunk_recv_cb_called = 0; - ud.data_recv_cb_called = 0; + ud.frame_recv_cb_called = 0; rv = nghttp2_session_mem_recv(session, data, 8+4096); CU_ASSERT(8+4096 == rv); CU_ASSERT(1 == ud.data_chunk_recv_cb_called); - CU_ASSERT(1 == ud.data_recv_cb_called); + CU_ASSERT(1 == ud.frame_recv_cb_called); CU_ASSERT(NULL == nghttp2_session_get_next_ob_item(session)); ud.data_chunk_recv_cb_called = 0; - ud.data_recv_cb_called = 0; + ud.frame_recv_cb_called = 0; rv = nghttp2_session_mem_recv(session, data, 8+4096); CU_ASSERT(8+4096 == rv); /* Now we got data more than initial-window-size / 2, WINDOW_UPDATE must be queued */ CU_ASSERT(1 == ud.data_chunk_recv_cb_called); - CU_ASSERT(1 == ud.data_recv_cb_called); + CU_ASSERT(1 == ud.frame_recv_cb_called); item = nghttp2_session_get_next_ob_item(session); CU_ASSERT(NGHTTP2_WINDOW_UPDATE == OB_CTRL_TYPE(item)); CU_ASSERT(1 == OB_CTRL(item)->window_update.hd.stream_id); @@ -647,12 +637,12 @@ void test_nghttp2_session_recv_data(void) nghttp2_frame_pack_frame_hd(data, &hd); ud.data_chunk_recv_cb_called = 0; - ud.data_recv_cb_called = 0; + ud.frame_recv_cb_called = 0; rv = nghttp2_session_mem_recv(session, data, 8+4096); CU_ASSERT(8+4096 == rv); CU_ASSERT(0 == ud.data_chunk_recv_cb_called); - CU_ASSERT(0 == ud.data_recv_cb_called); + CU_ASSERT(0 == ud.frame_recv_cb_called); item = nghttp2_session_get_next_ob_item(session); CU_ASSERT(NGHTTP2_GOAWAY == OB_CTRL_TYPE(item)); CU_ASSERT(NGHTTP2_PROTOCOL_ERROR == OB_CTRL(item)->goaway.error_code); @@ -807,7 +797,6 @@ void test_nghttp2_session_continue(void) callbacks.send_callback = null_send_callback; callbacks.on_frame_recv_callback = on_frame_recv_callback; callbacks.on_data_chunk_recv_callback = pause_on_data_chunk_recv_callback; - callbacks.on_data_recv_callback = on_data_recv_callback; callbacks.on_header_callback = pause_on_header_callback; callbacks.on_end_headers_callback = on_end_headers_callback; @@ -920,24 +909,24 @@ void test_nghttp2_session_continue(void) buflen = sizeof(buffer); /* Intentionally specify larger buffer size to see pause is kicked in. */ - user_data.data_recv_cb_called = 0; + user_data.frame_recv_cb_called = 0; rv = nghttp2_session_mem_recv(session, buffer, sizeof(buffer)); CU_ASSERT(16 + NGHTTP2_FRAME_HEAD_LENGTH == rv); - CU_ASSERT(0 == user_data.data_recv_cb_called); + CU_ASSERT(0 == user_data.frame_recv_cb_called); - /* Next nghttp2_session_mem_recv invokes on_data_recv_callback and + /* Next nghttp2_session_mem_recv invokes on_frame_recv_callback and pause again in on_data_chunk_recv_callback since we pass same DATA frame. */ - user_data.data_recv_cb_called = 0; + user_data.frame_recv_cb_called = 0; rv = nghttp2_session_mem_recv(session, buffer, sizeof(buffer)); CU_ASSERT(16 + NGHTTP2_FRAME_HEAD_LENGTH == rv); - CU_ASSERT(1 == user_data.data_recv_cb_called); + CU_ASSERT(1 == user_data.frame_recv_cb_called); - /* And finally call on_data_recv_callback with 0 size input */ - user_data.data_recv_cb_called = 0; + /* And finally call on_frame_recv_callback with 0 size input */ + user_data.frame_recv_cb_called = 0; rv = nghttp2_session_mem_recv(session, NULL, 0); CU_ASSERT(0 == rv); - CU_ASSERT(1 == user_data.data_recv_cb_called); + CU_ASSERT(1 == user_data.frame_recv_cb_called); free(framedata); nghttp2_hd_deflate_free(&deflater); @@ -1720,6 +1709,7 @@ void test_nghttp2_session_on_data_received(void) my_user_data user_data; nghttp2_outbound_item *top; nghttp2_stream *stream; + nghttp2_frame frame; memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); @@ -1727,25 +1717,36 @@ void test_nghttp2_session_on_data_received(void) stream = nghttp2_session_open_stream(session, 2, NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_PRI_DEFAULT, NGHTTP2_STREAM_OPENING, NULL); - CU_ASSERT(0 == nghttp2_session_on_data_received(session, 4096, - NGHTTP2_FLAG_NONE, 2)); + + frame.hd.length = 4096; + frame.hd.flags = NGHTTP2_FLAG_NONE; + frame.hd.stream_id = 2; + + CU_ASSERT(0 == nghttp2_session_on_data_received(session, &frame)); CU_ASSERT(0 == stream->shut_flags); - CU_ASSERT(0 == nghttp2_session_on_data_received(session, 4096, - NGHTTP2_FLAG_END_STREAM, 2)); + + frame.hd.flags = NGHTTP2_FLAG_END_STREAM; + + CU_ASSERT(0 == nghttp2_session_on_data_received(session, &frame)); CU_ASSERT(NGHTTP2_SHUT_RD == stream->shut_flags); /* If NGHTTP2_STREAM_CLOSING state, DATA frame is discarded. */ stream = nghttp2_session_open_stream(session, 4, NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_PRI_DEFAULT, NGHTTP2_STREAM_CLOSING, NULL); - CU_ASSERT(0 == nghttp2_session_on_data_received(session, 4096, - NGHTTP2_FLAG_NONE, 4)); + + frame.hd.flags = NGHTTP2_FLAG_NONE; + frame.hd.stream_id = 4; + + CU_ASSERT(0 == nghttp2_session_on_data_received(session, &frame)); CU_ASSERT(NULL == nghttp2_session_get_ob_pq_top(session)); /* Check INVALID_STREAM case: DATA frame with stream ID which does not exist. */ - CU_ASSERT(0 == nghttp2_session_on_data_received(session, 4096, - NGHTTP2_FLAG_NONE, 6)); + + frame.hd.stream_id = 6; + + CU_ASSERT(0 == nghttp2_session_on_data_received(session, &frame)); top = nghttp2_session_get_ob_pq_top(session); /* DATA against nonexistent stream is just ignored for now */ CU_ASSERT(top == NULL); @@ -3224,7 +3225,7 @@ void test_nghttp2_session_stop_data_with_rst_stream(void) ud.block_count = 2; /* Sends SYN_REPLY + DATA[0] */ CU_ASSERT(0 == nghttp2_session_send(session)); - CU_ASSERT(NGHTTP2_HEADERS == ud.sent_frame_type); + CU_ASSERT(NGHTTP2_DATA == ud.sent_frame_type); /* data for DATA[1] is read from data_prd but it is not sent */ CU_ASSERT(ud.data_source_length == 8*1024); @@ -3950,7 +3951,7 @@ void test_nghttp2_session_data_backoff_by_high_pri_frame(void) ud.block_count = 2; /* Sends SYN_STREAM + DATA[0] */ CU_ASSERT(0 == nghttp2_session_send(session)); - CU_ASSERT(NGHTTP2_HEADERS == ud.sent_frame_type); + CU_ASSERT(NGHTTP2_DATA == ud.sent_frame_type); /* data for DATA[1] is read from data_prd but it is not sent */ CU_ASSERT(ud.data_source_length == 8*1024);