Merge pull request #1063 from nghttp2/error_callback2

Error callback2
This commit is contained in:
Tatsuhiro Tsujikawa 2017-11-21 21:25:53 +09:00 committed by GitHub
commit ee8bfddfc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 94 additions and 20 deletions

View File

@ -81,6 +81,7 @@ APIDOCS= \
nghttp2_session_callbacks_set_before_frame_send_callback.rst \ nghttp2_session_callbacks_set_before_frame_send_callback.rst \
nghttp2_session_callbacks_set_data_source_read_length_callback.rst \ nghttp2_session_callbacks_set_data_source_read_length_callback.rst \
nghttp2_session_callbacks_set_error_callback.rst \ nghttp2_session_callbacks_set_error_callback.rst \
nghttp2_session_callbacks_set_error_callback2.rst \
nghttp2_session_callbacks_set_on_begin_frame_callback.rst \ nghttp2_session_callbacks_set_on_begin_frame_callback.rst \
nghttp2_session_callbacks_set_on_begin_headers_callback.rst \ nghttp2_session_callbacks_set_on_begin_headers_callback.rst \
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst \ nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst \

View File

@ -387,6 +387,11 @@ typedef enum {
* Indicates that a processing was canceled. * Indicates that a processing was canceled.
*/ */
NGHTTP2_ERR_CANCEL = -535, NGHTTP2_ERR_CANCEL = -535,
/**
* When a local endpoint expects to receive SETTINGS frame, it
* receives an other type of frame.
*/
NGHTTP2_ERR_SETTINGS_EXPECTED = -536,
/** /**
* The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is * The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
* under unexpected condition and processing was terminated (e.g., * under unexpected condition and processing was terminated (e.g.,
@ -1987,6 +1992,9 @@ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
* of length |len|. |len| does not include the sentinel NULL * of length |len|. |len| does not include the sentinel NULL
* character. * character.
* *
* This function is deprecated. The new application should use
* :type:`nghttp2_error_callback2`.
*
* The format of error message may change between nghttp2 library * The format of error message may change between nghttp2 library
* versions. The application should not depend on the particular * versions. The application should not depend on the particular
* format. * format.
@ -2003,6 +2011,33 @@ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg, typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg,
size_t len, void *user_data); size_t len, void *user_data);
/**
* @functypedef
*
* Callback function invoked when library provides the error code, and
* message. This callback is solely for debugging purpose.
* |lib_error_code| is one of error code defined in
* :enum:`nghttp2_error`. The |msg| is typically NULL-terminated
* string of length |len|, and intended for human consumption. |len|
* does not include the sentinel NULL character.
*
* The format of error message may change between nghttp2 library
* versions. The application should not depend on the particular
* format.
*
* Normally, application should return 0 from this callback. If fatal
* error occurred while doing something in this callback, application
* should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
* library will return immediately with return value
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if nonzero value
* is returned from this callback, they are treated as
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
* rely on this details.
*/
typedef int (*nghttp2_error_callback2)(nghttp2_session *session,
int lib_error_code, const char *msg,
size_t len, void *user_data);
struct nghttp2_session_callbacks; struct nghttp2_session_callbacks;
/** /**
@ -2267,10 +2302,30 @@ nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
* *
* Sets callback function invoked when library tells error message to * Sets callback function invoked when library tells error message to
* the application. * the application.
*
* This function is deprecated. The new application should use
* `nghttp2_session_callbacks_set_error_callback2()`.
*
* If both :type:`nghttp2_error_callback` and
* :type:`nghttp2_error_callback2` are set, the latter takes
* precedence.
*/ */
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback( NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback(
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback); nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback);
/**
* @function
*
* Sets callback function invoked when library tells error code, and
* message to the application.
*
* If both :type:`nghttp2_error_callback` and
* :type:`nghttp2_error_callback2` are set, the latter takes
* precedence.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2(
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2);
/** /**
* @functypedef * @functypedef
* *

View File

@ -168,3 +168,8 @@ void nghttp2_session_callbacks_set_error_callback(
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) { nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) {
cbs->error_callback = error_callback; cbs->error_callback = error_callback;
} }
void nghttp2_session_callbacks_set_error_callback2(
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) {
cbs->error_callback2 = error_callback2;
}

View File

@ -119,6 +119,7 @@ struct nghttp2_session_callbacks {
nghttp2_unpack_extension_callback unpack_extension_callback; nghttp2_unpack_extension_callback unpack_extension_callback;
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback; nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
nghttp2_error_callback error_callback; nghttp2_error_callback error_callback;
nghttp2_error_callback2 error_callback2;
}; };
#endif /* NGHTTP2_CALLBACKS_H */ #endif /* NGHTTP2_CALLBACKS_H */

View File

@ -322,6 +322,9 @@ const char *nghttp2_strerror(int error_code) {
return "Internal error"; return "Internal error";
case NGHTTP2_ERR_CANCEL: case NGHTTP2_ERR_CANCEL:
return "Cancel"; return "Cancel";
case NGHTTP2_ERR_SETTINGS_EXPECTED:
return "When a local endpoint expects to receive SETTINGS frame, it "
"receives an other type of frame";
case NGHTTP2_ERR_NOMEM: case NGHTTP2_ERR_NOMEM:
return "Out of memory"; return "Out of memory";
case NGHTTP2_ERR_CALLBACK_FAILURE: case NGHTTP2_ERR_CALLBACK_FAILURE:

View File

@ -148,14 +148,16 @@ static int check_ext_type_set(const uint8_t *ext_types, uint8_t type) {
} }
static int session_call_error_callback(nghttp2_session *session, static int session_call_error_callback(nghttp2_session *session,
const char *fmt, ...) { int lib_error_code, const char *fmt,
...) {
size_t bufsize; size_t bufsize;
va_list ap; va_list ap;
char *buf; char *buf;
int rv; int rv;
nghttp2_mem *mem; nghttp2_mem *mem;
if (!session->callbacks.error_callback) { if (!session->callbacks.error_callback &&
!session->callbacks.error_callback2) {
return 0; return 0;
} }
@ -189,8 +191,13 @@ static int session_call_error_callback(nghttp2_session *session,
return 0; return 0;
} }
rv = session->callbacks.error_callback(session, buf, (size_t)rv, if (session->callbacks.error_callback2) {
session->user_data); rv = session->callbacks.error_callback2(session, lib_error_code, buf,
(size_t)rv, session->user_data);
} else {
rv = session->callbacks.error_callback(session, buf, (size_t)rv,
session->user_data);
}
nghttp2_mem_free(mem, buf); nghttp2_mem_free(mem, buf);
@ -3608,7 +3615,7 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
nv.name->base, (int)nv.value->len, nv.value->base); nv.name->base, (int)nv.value->len, nv.value->base);
rv2 = session_call_error_callback( rv2 = session_call_error_callback(
session, session, NGHTTP2_ERR_HTTP_HEADER,
"Ignoring received invalid HTTP header field: frame type: " "Ignoring received invalid HTTP header field: frame type: "
"%u, stream: %d, name: [%.*s], value: [%.*s]", "%u, stream: %d, name: [%.*s], value: [%.*s]",
frame->hd.type, frame->hd.stream_id, (int)nv.name->len, frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
@ -3626,8 +3633,9 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
nv.name->base, (int)nv.value->len, nv.value->base); nv.name->base, (int)nv.value->len, nv.value->base);
rv = session_call_error_callback( rv = session_call_error_callback(
session, "Invalid HTTP header field was received: frame type: " session, NGHTTP2_ERR_HTTP_HEADER,
"%u, stream: %d, name: [%.*s], value: [%.*s]", "Invalid HTTP header field was received: frame type: "
"%u, stream: %d, name: [%.*s], value: [%.*s]",
frame->hd.type, frame->hd.stream_id, (int)nv.name->len, frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
nv.name->base, (int)nv.value->len, nv.value->base); nv.name->base, (int)nv.value->len, nv.value->base);
@ -5345,9 +5353,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe->state = NGHTTP2_IB_IGN_ALL; iframe->state = NGHTTP2_IB_IGN_ALL;
rv = session_call_error_callback( rv = session_call_error_callback(
session, "Remote peer returned unexpected data while we expected " session, NGHTTP2_ERR_SETTINGS_EXPECTED,
"SETTINGS frame. Perhaps, peer does not support HTTP/2 " "Remote peer returned unexpected data while we expected "
"properly."); "SETTINGS frame. Perhaps, peer does not support HTTP/2 "
"properly.");
if (nghttp2_is_fatal(rv)) { if (nghttp2_is_fatal(rv)) {
return rv; return rv;

View File

@ -1749,8 +1749,8 @@ void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config) {
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
callbacks, verbose_on_invalid_frame_recv_callback); callbacks, verbose_on_invalid_frame_recv_callback);
nghttp2_session_callbacks_set_error_callback(callbacks, nghttp2_session_callbacks_set_error_callback2(callbacks,
verbose_error_callback); verbose_error_callback);
} }
nghttp2_session_callbacks_set_on_data_chunk_recv_callback( nghttp2_session_callbacks_set_on_data_chunk_recv_callback(

View File

@ -425,8 +425,8 @@ int verbose_on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
return 0; return 0;
} }
int verbose_error_callback(nghttp2_session *session, const char *msg, int verbose_error_callback(nghttp2_session *session, int lib_error_code,
size_t len, void *user_data) { const char *msg, size_t len, void *user_data) {
print_timer(); print_timer();
fprintf(outfile, " [ERROR] %.*s\n", (int)len, msg); fprintf(outfile, " [ERROR] %.*s\n", (int)len, msg);
fflush(outfile); fflush(outfile);

View File

@ -60,8 +60,8 @@ int verbose_on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
int32_t stream_id, const uint8_t *data, int32_t stream_id, const uint8_t *data,
size_t len, void *user_data); size_t len, void *user_data);
int verbose_error_callback(nghttp2_session *session, const char *msg, int verbose_error_callback(nghttp2_session *session, int lib_error_code,
size_t len, void *user_data); const char *msg, size_t len, void *user_data);
// Returns difference between |a| and |b| in milliseconds, assuming // Returns difference between |a| and |b| in milliseconds, assuming
// |a| is more recent than |b|. // |a| is more recent than |b|.

View File

@ -2458,8 +2458,8 @@ int run(char **uris, int n) {
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
callbacks, verbose_on_invalid_frame_recv_callback); callbacks, verbose_on_invalid_frame_recv_callback);
nghttp2_session_callbacks_set_error_callback(callbacks, nghttp2_session_callbacks_set_error_callback2(callbacks,
verbose_error_callback); verbose_error_callback);
} }
nghttp2_session_callbacks_set_on_data_chunk_recv_callback( nghttp2_session_callbacks_set_on_data_chunk_recv_callback(

View File

@ -957,8 +957,8 @@ nghttp2_session_callbacks *create_http2_upstream_callbacks() {
} }
if (config->http2.upstream.debug.frame_debug) { if (config->http2.upstream.debug.frame_debug) {
nghttp2_session_callbacks_set_error_callback(callbacks, nghttp2_session_callbacks_set_error_callback2(callbacks,
verbose_error_callback); verbose_error_callback);
} }
return callbacks; return callbacks;