diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h index f801b7a6..2b85e913 100644 --- a/lib/includes/nghttp2/nghttp2.h +++ b/lib/includes/nghttp2/nghttp2.h @@ -832,8 +832,13 @@ typedef int (*nghttp2_on_data_chunk_recv_callback) * Callback function invoked when DATA frame is received. The actual * data it contains are received by * :type:`nghttp2_on_data_chunk_recv_callback`. + * + * 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 void (*nghttp2_on_data_recv_callback) +typedef int (*nghttp2_on_data_recv_callback) (nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, void *user_data); diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index b6572bf0..4d811121 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -2626,8 +2626,10 @@ int nghttp2_session_on_data_received(nghttp2_session *session, if(stream->state == NGHTTP2_STREAM_OPENED) { valid = 1; if(session->callbacks.on_data_recv_callback) { - session->callbacks.on_data_recv_callback - (session, length, flags, stream_id, session->user_data); + if(session->callbacks.on_data_recv_callback + (session, length, flags, stream_id, session->user_data) != 0) { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } } } else if(stream->state != NGHTTP2_STREAM_CLOSING) { error_code = NGHTTP2_PROTOCOL_ERROR; @@ -2641,8 +2643,10 @@ int nghttp2_session_on_data_received(nghttp2_session *session, NGHTTP2_STREAM_CLOSING state. This is a race condition. */ valid = 1; if(session->callbacks.on_data_recv_callback) { - session->callbacks.on_data_recv_callback - (session, length, flags, stream_id, session->user_data); + if(session->callbacks.on_data_recv_callback + (session, length, flags, stream_id, session->user_data) != 0) { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } } if(flags & NGHTTP2_FLAG_END_STREAM) { nghttp2_session_call_on_request_recv(session, stream_id); diff --git a/src/HttpServer.cc b/src/HttpServer.cc index a63ca1a3..24815298 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -762,7 +762,7 @@ int on_data_chunk_recv_callback } // namespace namespace { -void hd_on_data_recv_callback +int hd_on_data_recv_callback (nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, void *user_data) { @@ -772,6 +772,7 @@ void hd_on_data_recv_callback print_session_id(hd->session_id()); on_data_recv_callback(session, length, flags, stream_id, user_data); } + return 0; } } // namespace diff --git a/src/app_helper.cc b/src/app_helper.cc index 73679f01..ac77b7d8 100644 --- a/src/app_helper.cc +++ b/src/app_helper.cc @@ -413,7 +413,7 @@ void print_data_frame(print_type ptype, uint16_t length, uint8_t flags, } } // namespace -void on_data_recv_callback +int on_data_recv_callback (nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, void *user_data) { @@ -421,6 +421,7 @@ void on_data_recv_callback printf(" recv "); print_data_frame(PRINT_RECV, length, flags, stream_id); fflush(stdout); + return 0; } void on_data_send_callback diff --git a/src/app_helper.h b/src/app_helper.h index ce4487e2..e3a1678c 100644 --- a/src/app_helper.h +++ b/src/app_helper.h @@ -64,7 +64,7 @@ void on_unknown_frame_recv_callback(nghttp2_session *session, void on_frame_send_callback (nghttp2_session *session, nghttp2_frame *frame, void *user_data); -void on_data_recv_callback +int on_data_recv_callback (nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, void *user_data); diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index 25d16058..96f336f0 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -175,12 +175,13 @@ static int on_data_chunk_recv_callback(nghttp2_session *session, return 0; } -static void on_data_recv_callback(nghttp2_session *session, - uint16_t length, uint8_t flags, - int32_t stream_id, void *user_data) +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