Hide nghttp2_session_callbacks details and provide setter like functions

To make it possible to add new callbacks without bumping so name, we
decided to hide details of nghttp2_session_callbacks.  We provide
setter like functions to set individual callback function.
This commit is contained in:
Tatsuhiro Tsujikawa 2014-08-22 20:59:50 +09:00
parent 9f6bb989e3
commit ab5b81bee1
13 changed files with 776 additions and 242 deletions

View File

@ -310,13 +310,21 @@ static int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
*/
static void setup_nghttp2_callbacks(nghttp2_session_callbacks *callbacks)
{
memset(callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks->send_callback = send_callback;
callbacks->recv_callback = recv_callback;
callbacks->on_frame_send_callback = on_frame_send_callback;
callbacks->on_frame_recv_callback = on_frame_recv_callback;
callbacks->on_stream_close_callback = on_stream_close_callback;
callbacks->on_data_chunk_recv_callback = on_data_chunk_recv_callback;
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
nghttp2_session_callbacks_set_recv_callback(callbacks, recv_callback);
nghttp2_session_callbacks_set_on_frame_send_callback
(callbacks, on_frame_send_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv_callback);
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close_callback);
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv_callback);
}
/*
@ -507,7 +515,7 @@ static void request_free(struct Request *req)
*/
static void fetch_uri(const struct URI *uri)
{
nghttp2_session_callbacks callbacks;
nghttp2_session_callbacks *callbacks;
int fd;
SSL_CTX *ssl_ctx;
SSL *ssl;
@ -519,8 +527,6 @@ static void fetch_uri(const struct URI *uri)
request_init(&req, uri);
setup_nghttp2_callbacks(&callbacks);
/* Establish connection and setup SSL */
fd = connect_to(req.host, req.port);
if(fd == -1) {
@ -551,8 +557,20 @@ static void fetch_uri(const struct URI *uri)
set_tcp_nodelay(fd);
printf("[INFO] SSL/TLS handshake completed\n");
rv = nghttp2_session_client_new(&connection.session, &callbacks,
rv = nghttp2_session_callbacks_new(&callbacks);
if(rv != 0) {
diec("nghttp2_session_callbacks_new", rv);
}
setup_nghttp2_callbacks(callbacks);
rv = nghttp2_session_client_new(&connection.session, callbacks,
&connection);
nghttp2_session_callbacks_del(callbacks);
if(rv != 0) {
diec("nghttp2_session_client_new", rv);
}

View File

@ -331,17 +331,30 @@ static SSL* create_ssl(SSL_CTX *ssl_ctx)
static void initialize_nghttp2_session(http2_session_data *session_data)
{
nghttp2_session_callbacks callbacks;
nghttp2_session_callbacks *callbacks;
memset(&callbacks, 0, sizeof(callbacks));
nghttp2_session_callbacks_new(&callbacks);
callbacks.send_callback = send_callback;
callbacks.on_frame_recv_callback = on_frame_recv_callback;
callbacks.on_data_chunk_recv_callback = on_data_chunk_recv_callback;
callbacks.on_stream_close_callback = on_stream_close_callback;
callbacks.on_header_callback = on_header_callback;
callbacks.on_begin_headers_callback = on_begin_headers_callback;
nghttp2_session_client_new(&session_data->session, &callbacks, session_data);
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv_callback);
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv_callback);
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close_callback);
nghttp2_session_callbacks_set_on_header_callback
(callbacks, on_header_callback);
nghttp2_session_callbacks_set_on_begin_headers_callback
(callbacks, on_begin_headers_callback);
nghttp2_session_client_new(&session_data->session, callbacks, session_data);
nghttp2_session_callbacks_del(callbacks);
}
static void send_client_connection_header(http2_session_data *session_data)

View File

@ -555,16 +555,27 @@ static int on_stream_close_callback(nghttp2_session *session,
static void initialize_nghttp2_session(http2_session_data *session_data)
{
nghttp2_session_callbacks callbacks;
nghttp2_session_callbacks *callbacks;
memset(&callbacks, 0, sizeof(callbacks));
nghttp2_session_callbacks_new(&callbacks);
callbacks.send_callback = send_callback;
callbacks.on_frame_recv_callback = on_frame_recv_callback;
callbacks.on_stream_close_callback = on_stream_close_callback;
callbacks.on_header_callback = on_header_callback;
callbacks.on_begin_headers_callback = on_begin_headers_callback;
nghttp2_session_server_new(&session_data->session, &callbacks, session_data);
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv_callback);
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close_callback);
nghttp2_session_callbacks_set_on_header_callback
(callbacks, on_header_callback);
nghttp2_session_callbacks_set_on_begin_headers_callback
(callbacks, on_begin_headers_callback);
nghttp2_session_server_new(&session_data->session, callbacks, session_data);
nghttp2_session_callbacks_del(callbacks);
}
/* Send HTTP/2 client connection header, which includes 24 bytes

View File

@ -41,7 +41,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c \
nghttp2_version.c \
nghttp2_priority_spec.c \
nghttp2_option.c
nghttp2_option.c \
nghttp2_callbacks.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_frame.h \
@ -52,7 +53,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_net.h \
nghttp2_hd.h nghttp2_hd_huffman.h \
nghttp2_priority_spec.h \
nghttp2_option.h
nghttp2_option.h \
nghttp2_callbacks.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
libnghttp2_la_LDFLAGS = -no-undefined \

View File

@ -1104,6 +1104,9 @@ typedef union {
* `nghttp2_session_send()` to send data to the remote endpoint. If
* the application uses solely `nghttp2_session_mem_send()` instead,
* this callback function is unnecessary.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_send_callback()`.
*/
typedef ssize_t (*nghttp2_send_callback)
(nghttp2_session *session,
@ -1129,6 +1132,9 @@ typedef ssize_t (*nghttp2_send_callback)
* `nghttp2_session_recv()` to receive data from the remote endpoint.
* If the application uses solely `nghttp2_session_mem_recv()`
* instead, this callback function is unnecessary.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_recv_callback()`.
*/
typedef ssize_t (*nghttp2_recv_callback)
(nghttp2_session *session,
@ -1161,6 +1167,9 @@ typedef ssize_t (*nghttp2_recv_callback)
* If nonzero value is returned, it is treated as fatal error and
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_frame_recv_callback()`.
*/
typedef int (*nghttp2_on_frame_recv_callback)
(nghttp2_session *session, const nghttp2_frame *frame, void *user_data);
@ -1184,6 +1193,9 @@ typedef int (*nghttp2_on_frame_recv_callback)
* 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`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_invalid_frame_recv_callback()`.
*/
typedef int (*nghttp2_on_invalid_frame_recv_callback)
(nghttp2_session *session, const nghttp2_frame *frame,
@ -1215,6 +1227,9 @@ typedef int (*nghttp2_on_invalid_frame_recv_callback)
* If nonzero is returned, it is treated as fatal error and
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_data_chunk_recv_callback()`.
*/
typedef int (*nghttp2_on_data_chunk_recv_callback)
(nghttp2_session *session, uint8_t flags, int32_t stream_id,
@ -1232,6 +1247,9 @@ typedef int (*nghttp2_on_data_chunk_recv_callback)
* 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`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_before_frame_send_callback()`.
*/
typedef int (*nghttp2_before_frame_send_callback)
(nghttp2_session *session, const nghttp2_frame *frame, void *user_data);
@ -1247,6 +1265,9 @@ typedef int (*nghttp2_before_frame_send_callback)
* 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`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_frame_send_callback()`.
*/
typedef int (*nghttp2_on_frame_send_callback)
(nghttp2_session *session, const nghttp2_frame *frame, void *user_data);
@ -1265,6 +1286,9 @@ typedef int (*nghttp2_on_frame_send_callback)
* 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`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_frame_not_send_callback()`.
*/
typedef int (*nghttp2_on_frame_not_send_callback)
(nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code,
@ -1287,6 +1311,9 @@ typedef int (*nghttp2_on_frame_not_send_callback)
* 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`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_stream_close_callback()`.
*/
typedef int (*nghttp2_on_stream_close_callback)
(nghttp2_session *session, int32_t stream_id, nghttp2_error_code error_code,
@ -1309,6 +1336,9 @@ typedef int (*nghttp2_on_stream_close_callback)
* 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`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_unknown_frame_recv_callback()`.
*/
typedef int (*nghttp2_on_unknown_frame_recv_callback)
(nghttp2_session *session,
@ -1336,6 +1366,9 @@ typedef int (*nghttp2_on_unknown_frame_recv_callback)
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
* `nghttp2_session_mem_recv()` function will immediately return
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_begin_headers_callback()`.
*/
typedef int (*nghttp2_on_begin_headers_callback)
(nghttp2_session *session, const nghttp2_frame *frame, void *user_data);
@ -1397,6 +1430,9 @@ typedef int (*nghttp2_on_begin_headers_callback)
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_header_callback()`.
*/
typedef int (*nghttp2_on_header_callback)
(nghttp2_session *session,
@ -1419,6 +1455,9 @@ typedef int (*nghttp2_on_header_callback)
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will make
* `nghttp2_session_send()` function immediately return
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_select_padding_callback()`.
*/
typedef ssize_t (*nghttp2_select_padding_callback)
(nghttp2_session *session,
@ -1426,85 +1465,183 @@ typedef ssize_t (*nghttp2_select_padding_callback)
size_t max_payloadlen,
void *user_data);
struct nghttp2_session_callbacks;
/**
* @struct
*
* Callback functions.
* Callback functions for :type:`nghttp2_session`. The details of
* this structure are intentionally hidden from the public API.
*/
typedef struct {
typedef struct nghttp2_session_callbacks nghttp2_session_callbacks;
/**
* Callback function invoked when the |session| wants to send data
* to the remote peer. This callback is not necessary if the
* application uses solely `nghttp2_session_mem_send()` to serialize
* data to transmit.
* @function
*
* Initializes |*callbacks_ptr| with NULL values.
*
* The initialized object can be used when initializing multiple
* :type:`nghttp2_session` objects.
*
* When the application finished using this object, it can use
* `nghttp2_session_callbacks_del()` to free its memory.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
nghttp2_send_callback send_callback;
int nghttp2_session_callbacks_new(nghttp2_session_callbacks **callbacks_ptr);
/**
* Callback function invoked when the |session| wants to receive
* @function
*
* Frees any resources allocated for |callbacks|. If |callbacks| is
* ``NULL``, this function does nothing.
*/
void nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks);
/**
* @function
*
* Sets callback function invoked when a session wants to send data to
* the remote peer. This callback is not necessary if the application
* uses solely `nghttp2_session_mem_send()` to serialize data to
* transmit.
*/
void nghttp2_session_callbacks_set_send_callback
(nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback);
/**
* @function
*
* Sets callback function invoked when the a session wants to receive
* data from the remote peer. This callback is not necessary if the
* application uses solely `nghttp2_session_mem_recv()` to process
* received data.
*/
nghttp2_recv_callback recv_callback;
void nghttp2_session_callbacks_set_recv_callback
(nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback);
/**
* Callback function invoked by `nghttp2_session_recv()` when a
* @function
*
* Sets callback function invoked by `nghttp2_session_recv()` when a
* frame is received.
*/
nghttp2_on_frame_recv_callback on_frame_recv_callback;
void nghttp2_session_callbacks_set_on_frame_recv_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_frame_recv_callback on_frame_recv_callback);
/**
* Callback function invoked by `nghttp2_session_recv()` when an
* @function
*
* Sets callback function invoked by `nghttp2_session_recv()` when an
* invalid non-DATA frame is received.
*/
nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback;
void nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback);
/**
* Callback function invoked when a chunk of data in DATA frame is
* received.
* @function
*
* Sets callback function invoked when a chunk of data in DATA frame
* is received.
*/
nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback;
void nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback);
/**
* Callback function invoked before a non-DATA frame is sent.
* @function
*
* Sets callback function invoked before a non-DATA frame is sent.
*/
nghttp2_before_frame_send_callback before_frame_send_callback;
void nghttp2_session_callbacks_set_before_frame_send_callback
(nghttp2_session_callbacks *cbs,
nghttp2_before_frame_send_callback before_frame_send_callback);
/**
* Callback function invoked after a frame is sent.
* @function
*
* Sets callback function invoked after a frame is sent.
*/
nghttp2_on_frame_send_callback on_frame_send_callback;
void nghttp2_session_callbacks_set_on_frame_send_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_frame_send_callback on_frame_send_callback);
/**
* The callback function invoked when a non-DATA frame is not sent
* @function
*
* Sets callback function invoked when a non-DATA frame is not sent
* because of an error.
*/
nghttp2_on_frame_not_send_callback on_frame_not_send_callback;
void nghttp2_session_callbacks_set_on_frame_not_send_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_frame_not_send_callback on_frame_not_send_callback);
/**
* Callback function invoked when the stream is closed.
* @function
*
* Sets callback function invoked when the stream is closed.
*/
nghttp2_on_stream_close_callback on_stream_close_callback;
void nghttp2_session_callbacks_set_on_stream_close_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_stream_close_callback on_stream_close_callback);
/**
* Callback function invoked when the received frame type is
* @function
*
* Sets callback function invoked when the received frame type is
* unknown.
*/
nghttp2_on_unknown_frame_recv_callback on_unknown_frame_recv_callback;
void nghttp2_session_callbacks_set_on_unknown_frame_recv_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_unknown_frame_recv_callback on_unknown_frame_recv_callback);
/**
* Callback function invoked when the reception of header block in
* HEADERS or PUSH_PROMISE is started.
* @function
*
* Sets callback function invoked when the reception of header block
* in HEADERS or PUSH_PROMISE is started.
*/
nghttp2_on_begin_headers_callback on_begin_headers_callback;
void nghttp2_session_callbacks_set_on_begin_headers_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_begin_headers_callback on_begin_headers_callback);
/**
* Callback function invoked when a header name/value pair is
* @function
*
* Sets callback function invoked when a header name/value pair is
* received.
*/
nghttp2_on_header_callback on_header_callback;
void nghttp2_session_callbacks_set_on_header_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_header_callback on_header_callback);
/**
* Callback function invoked when the library asks application how
* many padding bytes are required for the transmission of the given
* frame.
* @function
*
* Sets callback function invoked when the library asks application
* how many padding bytes are required for the transmission of the
* given frame.
*/
nghttp2_select_padding_callback select_padding_callback;
void nghttp2_session_callbacks_set_select_padding_callback
(nghttp2_session_callbacks *cbs,
nghttp2_select_padding_callback select_padding_callback);
/**
* The callback function used to determine the |length| allowed
* in `nghttp2_data_source_read_callback()`
* @function
*
* Sets callback function determine the length allowed in
* :type:`nghttp2_data_source_read_callback`.
*/
nghttp2_data_source_read_length_callback read_length_callback;
} nghttp2_session_callbacks;
void nghttp2_session_callbacks_set_data_source_read_length_callback
(nghttp2_session_callbacks *cbs,
nghttp2_data_source_read_length_callback data_source_read_length_callback);
struct nghttp2_option;
@ -1578,10 +1715,10 @@ void nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
* does not store |callbacks|. The |user_data| is an arbitrary user
* supplied data, which will be passed to the callback functions.
*
* The :member:`nghttp2_session_callbacks.send_callback` must be
* specified. If the application code uses `nghttp2_session_recv()`,
* the :member:`nghttp2_session_callbacks.recv_callback` must be
* specified. The other members of |callbacks| can be ``NULL``.
* The :type:`nghttp2_send_callback` must be specified. If the
* application code uses `nghttp2_session_recv()`, the
* :type:`nghttp2_recv_callback` must be specified. The other members
* of |callbacks| can be ``NULL``.
*
* If this function fails, |*session_ptr| is left untouched.
*
@ -1603,10 +1740,10 @@ int nghttp2_session_client_new(nghttp2_session **session_ptr,
* does not store |callbacks|. The |user_data| is an arbitrary user
* supplied data, which will be passed to the callback functions.
*
* The :member:`nghttp2_session_callbacks.send_callback` must be
* specified. If the application code uses `nghttp2_session_recv()`,
* the :member:`nghttp2_session_callbacks.recv_callback` must be
* specified. The other members of |callbacks| can be ``NULL``.
* The :type:`nghttp2_send_callback` must be specified. If the
* application code uses `nghttp2_session_recv()`, the
* :type:`nghttp2_recv_callback` must be specified. The other members
* of |callbacks| can be ``NULL``.
*
* If this function fails, |*session_ptr| is left untouched.
*
@ -1688,32 +1825,36 @@ void nghttp2_session_del(nghttp2_session *session);
* This function retrieves the highest prioritized frame from the
* outbound queue and sends it to the remote peer. It does this as
* many as possible until the user callback
* :member:`nghttp2_session_callbacks.send_callback` returns
* :type:`nghttp2_send_callback` returns
* :enum:`NGHTTP2_ERR_WOULDBLOCK` or the outbound queue becomes empty.
* This function calls several callback functions which are passed
* when initializing the |session|. Here is the simple time chart
* which tells when each callback is invoked:
*
* 1. Get the next frame to send from outbound queue.
*
* 2. Prepare transmission of the frame.
*
* 3. If the control frame cannot be sent because some preconditions
* are not met (e.g., request HEADERS cannot be sent after GOAWAY),
* :member:`nghttp2_session_callbacks.on_frame_not_send_callback`
* is invoked. Abort the following steps.
* :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort
* the following steps.
*
* 4. If the frame is HEADERS, PUSH_PROMISE or DATA,
* :member:`nghttp2_session_callbacks.select_padding_callback` is
* invoked.
* :type:`nghttp2_select_padding_callback` is invoked.
*
* 5. If the frame is request HEADERS, the stream is opened here.
* 6. :member:`nghttp2_session_callbacks.before_frame_send_callback` is
* invoked.
* 7. :member:`nghttp2_session_callbacks.send_callback` is invoked one
* or more times to send the frame.
* 8. :member:`nghttp2_session_callbacks.on_frame_send_callback` is
* invoked.
*
* 6. :type:`nghttp2_before_frame_send_callback` is invoked.
*
* 7. :type:`nghttp2_send_callback` is invoked one or more times to
* send the frame.
*
* 8. :type:`nghttp2_on_frame_send_callback` is invoked.
*
* 9. 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.
* :type:`nghttp2_on_stream_close_callback` is invoked.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@ -1731,11 +1872,10 @@ int nghttp2_session_send(nghttp2_session *session);
* Returns the serialized data to send.
*
* This function behaves like `nghttp2_session_send()` except that it
* does not use :member:`nghttp2_session_callbacks.send_callback` to
* transmit data. Instead, it assigns the pointer to the serialized
* data to the |*data_ptr| and returns its length. The other
* callbacks are called in the same way as they are in
* `nghttp2_session_send()`.
* does not use :type:`nghttp2_send_callback` to transmit data.
* Instead, it assigns the pointer to the serialized data to the
* |*data_ptr| and returns its length. The other callbacks are called
* in the same way as they are in `nghttp2_session_send()`.
*
* If no data is available to send, this function returns 0.
*
@ -1765,51 +1905,45 @@ ssize_t nghttp2_session_mem_send(nghttp2_session *session,
* Receives frames from the remote peer.
*
* This function receives as many frames as possible until the user
* callback :member:`nghttp2_session_callbacks.recv_callback` returns
* callback :type:`nghttp2_recv_callback` returns
* :enum:`NGHTTP2_ERR_WOULDBLOCK`. This function calls several
* callback functions which are passed when initializing the
* |session|. Here is the simple time chart which tells when each
* callback is invoked:
*
* 1. :member:`nghttp2_session_callbacks.recv_callback` is invoked one
* or more times to receive frame header.
* 1. :type:`nghttp2_recv_callback` is invoked one or more times to
* receive frame header.
*
* 2. If the frame is DATA frame:
*
* 1. :member:`nghttp2_session_callbacks.recv_callback` is invoked
* to receive DATA payload. For each chunk of data,
* :member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`
* is invoked.
* 1. :type:`nghttp2_recv_callback` is invoked to receive DATA
* payload. For each chunk of data,
* :type:`nghttp2_on_data_chunk_recv_callback` is invoked.
*
* 2. If one DATA frame is completely received,
* :member:`nghttp2_session_callbacks.on_frame_recv_callback` is
* invoked. If the reception of the frame triggers the
* closure of the stream,
* :member:`nghttp2_session_callbacks.on_stream_close_callback`
* is invoked.
* :type:`nghttp2_on_frame_recv_callback` is invoked. If the
* reception of the frame triggers the closure of the stream,
* :type:`nghttp2_on_stream_close_callback` is invoked.
*
* 3. If the frame is the control frame:
*
* 1. :member:`nghttp2_session_callbacks.recv_callback` is invoked
* one or more times to receive whole frame.
* 1. :type:`nghttp2_recv_callback` is invoked one or more times to
* receive whole frame.
*
* 2. If the received frame is valid, then following actions are
* taken. If the frame is either HEADERS or PUSH_PROMISE,
* :member:`nghttp2_session_callbacks.on_begin_headers_callback`
* is invoked. Then
* :member:`nghttp2_session_callbacks.on_header_callback` is
* invoked for each header name/value pair. After all name/value
* pairs are emitted successfully,
* :member:`nghttp2_session_callbacks.on_frame_recv_callback` is
* :type:`nghttp2_on_begin_headers_callback` is invoked. Then
* :type:`nghttp2_on_header_callback` is invoked for each header
* name/value pair. After all name/value pairs are emitted
* successfully, :type:`nghttp2_on_frame_recv_callback` is
* invoked. For other frames,
* :member:`nghttp2_session_callbacks.on_frame_recv_callback` is
* invoked.
* If the reception of the frame triggers the closure of the
* stream,
* :member:`nghttp2_session_callbacks.on_stream_close_callback`
* is invoked.
* :type:`nghttp2_on_frame_recv_callback` is invoked. If the
* reception of the frame triggers the closure of the stream,
* :type:`nghttp2_on_stream_close_callback` is invoked.
*
* 3. If the received frame is unpacked but is interpreted as
* invalid,
* :member:`nghttp2_session_callbacks.on_invalid_frame_recv_callback`
* is invoked.
* invalid, :type:`nghttp2_on_invalid_frame_recv_callback` is
* invoked.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@ -1830,18 +1964,17 @@ int nghttp2_session_recv(nghttp2_session *session);
* |inlen| indicates the number of bytes in the |in|.
*
* This function behaves like `nghttp2_session_recv()` except that it
* does not use :member:`nghttp2_session_callbacks.recv_callback` to
* receive data; the |in| is the only data for the invocation of this
* function. If all bytes are processed, this function returns. The
* other callbacks are called in the same way as they are in
* `nghttp2_session_recv()`.
* does not use :type:`nghttp2_recv_callback` to receive data; the
* |in| is the only data for the invocation of this function. If all
* bytes are processed, this function returns. The other callbacks
* are called in the same way as they are in `nghttp2_session_recv()`.
*
* In the current implementation, this function always tries to
* processes all input data unless either an error occurs or
* :enum:`NGHTTP2_ERR_PAUSE` is returned from
* :member:`nghttp2_session_callbacks.on_header_callback` or
* :member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`.
* If :enum:`NGHTTP2_ERR_PAUSE` is used, the return value includes the
* :type:`nghttp2_on_header_callback` or
* :type:`nghttp2_on_data_chunk_recv_callback`. If
* :enum:`NGHTTP2_ERR_PAUSE` is used, the return value includes the
* number of bytes which was used to produce the data or frame for the
* callback.
*
@ -2270,8 +2403,8 @@ int nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
* This function returns assigned stream ID if it succeeds. But
* that stream is not opened yet. The application must not submit
* frame to that stream ID before
* :member:`nghttp2_session_callbacks.before_frame_send_callback` is
* called for this frame.
* :type:`nghttp2_before_frame_send_callback` is called for this
* frame.
*
*/
int32_t nghttp2_submit_request(nghttp2_session *session,
@ -2396,8 +2529,8 @@ int nghttp2_submit_response(nghttp2_session *session,
* This function returns assigned stream ID if it succeeds and
* |stream_id| is -1. But that stream is not opened yet. The
* application must not submit frame to that stream ID before
* :member:`nghttp2_session_callbacks.before_frame_send_callback` is
* called for this frame.
* :type:`nghttp2_before_frame_send_callback` is called for this
* frame.
*
*/
int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
@ -2571,8 +2704,8 @@ int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
* This function returns assigned promised stream ID if it succeeds.
* But that stream is not opened yet. The application must not
* submit frame to that stream ID before
* :member:`nghttp2_session_callbacks.before_frame_send_callback` is
* called for this frame.
* :type:`nghttp2_before_frame_send_callback` is called for this
* frame.
*
*/
int32_t nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,

139
lib/nghttp2_callbacks.c Normal file
View File

@ -0,0 +1,139 @@
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2014 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "nghttp2_callbacks.h"
#include <stdlib.h>
int nghttp2_session_callbacks_new(nghttp2_session_callbacks **callbacks_ptr)
{
*callbacks_ptr = calloc(1, sizeof(nghttp2_session_callbacks));
if(*callbacks_ptr == NULL) {
return NGHTTP2_ERR_NOMEM;
}
return 0;
}
void nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks)
{
free(callbacks);
}
void nghttp2_session_callbacks_set_send_callback
(nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback)
{
cbs->send_callback = send_callback;
}
void nghttp2_session_callbacks_set_recv_callback
(nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback)
{
cbs->recv_callback = recv_callback;
}
void nghttp2_session_callbacks_set_on_frame_recv_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_frame_recv_callback on_frame_recv_callback)
{
cbs->on_frame_recv_callback = on_frame_recv_callback;
}
void nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback)
{
cbs->on_invalid_frame_recv_callback = on_invalid_frame_recv_callback;
}
void nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback)
{
cbs->on_data_chunk_recv_callback = on_data_chunk_recv_callback;
}
void nghttp2_session_callbacks_set_before_frame_send_callback
(nghttp2_session_callbacks *cbs,
nghttp2_before_frame_send_callback before_frame_send_callback)
{
cbs->before_frame_send_callback = before_frame_send_callback;
}
void nghttp2_session_callbacks_set_on_frame_send_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_frame_send_callback on_frame_send_callback)
{
cbs->on_frame_send_callback = on_frame_send_callback;
}
void nghttp2_session_callbacks_set_on_frame_not_send_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_frame_not_send_callback on_frame_not_send_callback)
{
cbs->on_frame_not_send_callback = on_frame_not_send_callback;
}
void nghttp2_session_callbacks_set_on_stream_close_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_stream_close_callback on_stream_close_callback)
{
cbs->on_stream_close_callback = on_stream_close_callback;
}
void nghttp2_session_callbacks_set_on_unknown_frame_recv_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_unknown_frame_recv_callback on_unknown_frame_recv_callback)
{
cbs->on_unknown_frame_recv_callback = on_unknown_frame_recv_callback;
}
void nghttp2_session_callbacks_set_on_begin_headers_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_begin_headers_callback on_begin_headers_callback)
{
cbs->on_begin_headers_callback = on_begin_headers_callback;
}
void nghttp2_session_callbacks_set_on_header_callback
(nghttp2_session_callbacks *cbs,
nghttp2_on_header_callback on_header_callback)
{
cbs->on_header_callback = on_header_callback;
}
void nghttp2_session_callbacks_set_select_padding_callback
(nghttp2_session_callbacks *cbs,
nghttp2_select_padding_callback select_padding_callback)
{
cbs->select_padding_callback = select_padding_callback;
}
void nghttp2_session_callbacks_set_data_source_read_length_callback
(nghttp2_session_callbacks *cbs,
nghttp2_data_source_read_length_callback data_source_read_length_callback)
{
cbs->read_length_callback = data_source_read_length_callback;
}

112
lib/nghttp2_callbacks.h Normal file
View File

@ -0,0 +1,112 @@
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2014 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef NGHTTP2_CALLBACKS_H
#define NGHTTP2_CALLBACKS_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
/*
* Callback functions.
*/
struct nghttp2_session_callbacks {
/**
* Callback function invoked when the session wants to send data to
* the remote peer. This callback is not necessary if the
* application uses solely `nghttp2_session_mem_send()` to serialize
* data to transmit.
*/
nghttp2_send_callback send_callback;
/**
* Callback function invoked when the session wants to receive data
* from the remote peer. This callback is not necessary if the
* application uses solely `nghttp2_session_mem_recv()` to process
* received data.
*/
nghttp2_recv_callback recv_callback;
/**
* Callback function invoked by `nghttp2_session_recv()` when a
* frame is received.
*/
nghttp2_on_frame_recv_callback on_frame_recv_callback;
/**
* Callback function invoked by `nghttp2_session_recv()` when an
* invalid non-DATA frame is received.
*/
nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback;
/**
* Callback function invoked when a chunk of data in DATA frame is
* received.
*/
nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback;
/**
* Callback function invoked before a non-DATA frame is sent.
*/
nghttp2_before_frame_send_callback before_frame_send_callback;
/**
* Callback function invoked after a frame is sent.
*/
nghttp2_on_frame_send_callback on_frame_send_callback;
/**
* The callback function invoked when a non-DATA frame is not sent
* because of an error.
*/
nghttp2_on_frame_not_send_callback on_frame_not_send_callback;
/**
* Callback function invoked when the stream is closed.
*/
nghttp2_on_stream_close_callback on_stream_close_callback;
/**
* Callback function invoked when the received frame type is
* unknown.
*/
nghttp2_on_unknown_frame_recv_callback on_unknown_frame_recv_callback;
/**
* Callback function invoked when the reception of header block in
* HEADERS or PUSH_PROMISE is started.
*/
nghttp2_on_begin_headers_callback on_begin_headers_callback;
/**
* Callback function invoked when a header name/value pair is
* received.
*/
nghttp2_on_header_callback on_header_callback;
/**
* Callback function invoked when the library asks application how
* many padding bytes are required for the transmission of the given
* frame.
*/
nghttp2_select_padding_callback select_padding_callback;
/**
* The callback function used to determine the length allowed in
* `nghttp2_data_source_read_callback()`
*/
nghttp2_data_source_read_length_callback read_length_callback;
};
#endif /* NGHTTP2_CALLBACKS_H */

View File

@ -38,6 +38,7 @@
#include "nghttp2_outbound_item.h"
#include "nghttp2_int.h"
#include "nghttp2_buf.h"
#include "nghttp2_callbacks.h"
/*
* Option flags.

View File

@ -213,19 +213,29 @@ void remove_stream_write_timeout(Stream *stream)
}
} // namespace
namespace {
void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config);
} // namespace
class Sessions {
public:
Sessions(event_base *evbase, const Config *config, SSL_CTX *ssl_ctx)
: evbase_(evbase),
config_(config),
ssl_ctx_(ssl_ctx),
callbacks_(nullptr),
next_session_id_(1)
{}
{
nghttp2_session_callbacks_new(&callbacks_);
fill_callback(callbacks_, config_);
}
~Sessions()
{
for(auto handler : handlers_) {
delete handler;
}
nghttp2_session_callbacks_del(callbacks_);
}
void add_handler(Http2Handler *handler)
{
@ -269,6 +279,10 @@ public:
}
return session_id;
}
const nghttp2_session_callbacks* get_callbacks() const
{
return callbacks_;
}
void accept_connection(int fd)
{
int val = 1;
@ -297,6 +311,7 @@ private:
event_base *evbase_;
const Config *config_;
SSL_CTX *ssl_ctx_;
nghttp2_session_callbacks *callbacks_;
int64_t next_session_id_;
};
@ -311,10 +326,6 @@ void on_session_closed(Http2Handler *hd, int64_t session_id)
}
} // namespace
namespace {
void fill_callback(nghttp2_session_callbacks& callbacks, const Config *config);
} // namespace
Http2Handler::Http2Handler(Sessions *sessions,
int fd, SSL *ssl, int64_t session_id)
: session_id_(session_id),
@ -724,9 +735,8 @@ void settings_timeout_cb(evutil_socket_t fd, short what, void *arg)
int Http2Handler::on_connect()
{
int r;
nghttp2_session_callbacks callbacks;
fill_callback(callbacks, sessions_->get_config());
r = nghttp2_session_server_new(&session_, &callbacks, this);
r = nghttp2_session_server_new(&session_, sessions_->get_callbacks(), this);
if(r != 0) {
return r;
}
@ -1436,23 +1446,37 @@ int on_stream_close_callback
} // namespace
namespace {
void fill_callback(nghttp2_session_callbacks& callbacks, const Config *config)
void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config)
{
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.on_stream_close_callback = on_stream_close_callback;
callbacks.on_frame_recv_callback = hd_on_frame_recv_callback;
callbacks.on_frame_send_callback = hd_on_frame_send_callback;
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, hd_on_frame_recv_callback);
nghttp2_session_callbacks_set_on_frame_send_callback
(callbacks, hd_on_frame_send_callback);
if(config->verbose) {
callbacks.on_invalid_frame_recv_callback =
verbose_on_invalid_frame_recv_callback;
callbacks.on_unknown_frame_recv_callback =
verbose_on_unknown_frame_recv_callback;
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
(callbacks, verbose_on_invalid_frame_recv_callback);
nghttp2_session_callbacks_set_on_unknown_frame_recv_callback
(callbacks, verbose_on_unknown_frame_recv_callback);
}
callbacks.on_data_chunk_recv_callback = on_data_chunk_recv_callback;
callbacks.on_header_callback = on_header_callback;
callbacks.on_begin_headers_callback = on_begin_headers_callback;
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv_callback);
nghttp2_session_callbacks_set_on_header_callback
(callbacks, on_header_callback);
nghttp2_session_callbacks_set_on_begin_headers_callback
(callbacks, on_begin_headers_callback);
if(config->padding) {
callbacks.select_padding_callback = select_padding_callback;
nghttp2_session_callbacks_set_select_padding_callback
(callbacks, select_padding_callback);
}
}
} // namespace

View File

@ -102,13 +102,26 @@ void Http2Session::on_connect()
{
int rv;
nghttp2_session_callbacks callbacks = {0};
callbacks.on_frame_recv_callback = on_frame_recv_callback;
callbacks.on_data_chunk_recv_callback = on_data_chunk_recv_callback;
callbacks.on_stream_close_callback = on_stream_close_callback;
callbacks.on_header_callback = on_header_callback;
nghttp2_session_callbacks *callbacks;
nghttp2_session_client_new(&session_, &callbacks, client_);
nghttp2_session_callbacks_new(&callbacks);
util::auto_delete<nghttp2_session_callbacks*> callbacks_deleter
(callbacks, nghttp2_session_callbacks_del);
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv_callback);
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv_callback);
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close_callback);
nghttp2_session_callbacks_set_on_header_callback
(callbacks, on_header_callback);
nghttp2_session_client_new(&session_, callbacks, client_);
nghttp2_settings_entry iv[2];
iv[0].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;

View File

@ -1829,22 +1829,41 @@ ssize_t file_read_callback
namespace {
int run(char **uris, int n)
{
nghttp2_session_callbacks callbacks;
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.on_stream_close_callback = on_stream_close_callback;
callbacks.on_frame_recv_callback = on_frame_recv_callback2;
nghttp2_session_callbacks *callbacks;
nghttp2_session_callbacks_new(&callbacks);
util::auto_delete<nghttp2_session_callbacks*> cbsdel
(callbacks, nghttp2_session_callbacks_del);
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv_callback2);
if(config.verbose) {
callbacks.on_frame_send_callback = verbose_on_frame_send_callback;
callbacks.on_invalid_frame_recv_callback =
verbose_on_invalid_frame_recv_callback;
callbacks.on_unknown_frame_recv_callback =
verbose_on_unknown_frame_recv_callback;
nghttp2_session_callbacks_set_on_frame_send_callback
(callbacks, verbose_on_frame_send_callback);
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
(callbacks, verbose_on_invalid_frame_recv_callback);
nghttp2_session_callbacks_set_on_unknown_frame_recv_callback
(callbacks, verbose_on_unknown_frame_recv_callback);
}
callbacks.on_data_chunk_recv_callback = on_data_chunk_recv_callback;
callbacks.on_begin_headers_callback = on_begin_headers_callback;
callbacks.on_header_callback = on_header_callback;
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv_callback);
nghttp2_session_callbacks_set_on_begin_headers_callback
(callbacks, on_begin_headers_callback);
nghttp2_session_callbacks_set_on_header_callback
(callbacks, on_header_callback);
if(config.padding) {
callbacks.select_padding_callback = select_padding_callback;
nghttp2_session_callbacks_set_select_padding_callback
(callbacks, select_padding_callback);
}
std::string prev_scheme;
@ -1886,7 +1905,7 @@ int run(char **uris, int n)
port != prev_port) {
if(!requests.empty()) {
if (communicate(prev_scheme, prev_host, prev_port,
std::move(requests), &callbacks) != 0) {
std::move(requests), callbacks) != 0) {
++failures;
}
requests.clear();
@ -1901,7 +1920,7 @@ int run(char **uris, int n)
}
if(!requests.empty()) {
if (communicate(prev_scheme, prev_host, prev_port, std::move(requests),
&callbacks) != 0) {
callbacks) != 0) {
++failures;
}
}

View File

@ -1390,21 +1390,46 @@ int Http2Session::on_connect()
return -1;
}
}
nghttp2_session_callbacks callbacks;
memset(&callbacks, 0, sizeof(callbacks));
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_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;
callbacks.on_header_callback = on_header_callback;
callbacks.on_begin_headers_callback = on_begin_headers_callback;
if(get_config()->padding) {
callbacks.select_padding_callback = http::select_padding_callback;
nghttp2_session_callbacks *callbacks;
rv = nghttp2_session_callbacks_new(&callbacks);
if(rv != 0) {
return -1;
}
rv = nghttp2_session_client_new2(&session_, &callbacks, this,
util::auto_delete<nghttp2_session_callbacks*> callbacks_deleter
(callbacks, nghttp2_session_callbacks_del);
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv_callback);
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv_callback);
nghttp2_session_callbacks_set_on_frame_send_callback
(callbacks, on_frame_send_callback);
nghttp2_session_callbacks_set_on_frame_not_send_callback
(callbacks, on_frame_not_send_callback);
nghttp2_session_callbacks_set_on_unknown_frame_recv_callback
(callbacks, on_unknown_frame_recv_callback);
nghttp2_session_callbacks_set_on_header_callback
(callbacks, on_header_callback);
nghttp2_session_callbacks_set_on_begin_headers_callback
(callbacks, on_begin_headers_callback);
if(get_config()->padding) {
nghttp2_session_callbacks_set_select_padding_callback
(callbacks, http::select_padding_callback);
}
rv = nghttp2_session_client_new2(&session_, callbacks, this,
get_config()->http2_option);
if(rv != 0) {

View File

@ -645,22 +645,46 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
handler->set_upstream_timeouts(&get_config()->http2_upstream_read_timeout,
&get_config()->upstream_write_timeout);
nghttp2_session_callbacks callbacks;
memset(&callbacks, 0, sizeof(callbacks));
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_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;
callbacks.on_header_callback = on_header_callback;
callbacks.on_begin_headers_callback = on_begin_headers_callback;
int rv;
nghttp2_session_callbacks *callbacks;
rv = nghttp2_session_callbacks_new(&callbacks);
assert(rv == 0);
util::auto_delete<nghttp2_session_callbacks*> callbacks_deleter
(callbacks, nghttp2_session_callbacks_del);
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv_callback);
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv_callback);
nghttp2_session_callbacks_set_on_frame_send_callback
(callbacks, on_frame_send_callback);
nghttp2_session_callbacks_set_on_frame_not_send_callback
(callbacks, on_frame_not_send_callback);
nghttp2_session_callbacks_set_on_unknown_frame_recv_callback
(callbacks, on_unknown_frame_recv_callback);
nghttp2_session_callbacks_set_on_header_callback
(callbacks, on_header_callback);
nghttp2_session_callbacks_set_on_begin_headers_callback
(callbacks, on_begin_headers_callback);
if(get_config()->padding) {
callbacks.select_padding_callback = http::select_padding_callback;
nghttp2_session_callbacks_set_select_padding_callback
(callbacks, http::select_padding_callback);
}
int rv;
rv = nghttp2_session_server_new2(&session_, &callbacks, this,
rv = nghttp2_session_server_new2(&session_, callbacks, this,
get_config()->http2_option);
assert(rv == 0);