Add nghttp2_option_set_no_auto_ping_ack() option
This option prevents the nghttp2 library from sending PING frame with ACK flag set in the reply to incoming PING frame. To allow the application to send PING with ACK flag set, nghttp2_submit_ping() now recognizes NGHTTP2_FLAG_PING in its flags parameter.
This commit is contained in:
parent
a21c87d11c
commit
e453759637
|
@ -55,6 +55,7 @@ APIDOCS= \
|
||||||
nghttp2_option_del.rst \
|
nghttp2_option_del.rst \
|
||||||
nghttp2_option_new.rst \
|
nghttp2_option_new.rst \
|
||||||
nghttp2_option_set_max_reserved_remote_streams.rst \
|
nghttp2_option_set_max_reserved_remote_streams.rst \
|
||||||
|
nghttp2_option_set_no_auto_ping_ack.rst \
|
||||||
nghttp2_option_set_no_auto_window_update.rst \
|
nghttp2_option_set_no_auto_window_update.rst \
|
||||||
nghttp2_option_set_no_http_messaging.rst \
|
nghttp2_option_set_no_http_messaging.rst \
|
||||||
nghttp2_option_set_no_recv_client_magic.rst \
|
nghttp2_option_set_no_recv_client_magic.rst \
|
||||||
|
|
|
@ -2251,6 +2251,20 @@ NGHTTP2_EXTERN void
|
||||||
nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
|
nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
|
||||||
uint8_t type);
|
uint8_t type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* This option prevents the library from sending PING frame with ACK
|
||||||
|
* flag set automatically when PING frame without ACK flag set is
|
||||||
|
* received. If this option is set to nonzero, the library won't send
|
||||||
|
* PING frame with ACK flag set in the response for incoming PING
|
||||||
|
* frame. The application can send PING frame with ACK flag set using
|
||||||
|
* `nghttp2_submit_ping()` with :enum:`NGHTTP2_FLAG_ACK` as flags
|
||||||
|
* parameter.
|
||||||
|
*/
|
||||||
|
NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
|
||||||
|
int val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
|
@ -3783,8 +3797,12 @@ nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
|
||||||
* received PING frame. The library automatically submits PING frame
|
* received PING frame. The library automatically submits PING frame
|
||||||
* in this case.
|
* in this case.
|
||||||
*
|
*
|
||||||
* The |flags| is currently ignored and should be
|
* The |flags| is bitwise OR of 0 or more of the following value.
|
||||||
* :enum:`NGHTTP2_FLAG_NONE`.
|
*
|
||||||
|
* * :enum:`NGHTTP2_FLAG_ACK`
|
||||||
|
*
|
||||||
|
* Unless `nghttp2_option_set_no_auto_ping_ack()` is used, the |flags|
|
||||||
|
* should be :enum:`NGHTTP2_FLAG_NONE`.
|
||||||
*
|
*
|
||||||
* If the |opaque_data| is non ``NULL``, then it should point to the 8
|
* If the |opaque_data| is non ``NULL``, then it should point to the 8
|
||||||
* bytes array of memory to specify opaque data to send with PING
|
* bytes array of memory to specify opaque data to send with PING
|
||||||
|
|
|
@ -73,3 +73,8 @@ void nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
|
||||||
option->user_recv_ext_types[type / 8] =
|
option->user_recv_ext_types[type / 8] =
|
||||||
(uint8_t)(option->user_recv_ext_types[type / 8] | (1 << (type & 0x7)));
|
(uint8_t)(option->user_recv_ext_types[type / 8] | (1 << (type & 0x7)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, int val) {
|
||||||
|
option->opt_set_mask |= NGHTTP2_OPT_NO_AUTO_PING_ACK;
|
||||||
|
option->no_auto_ping_ack = val;
|
||||||
|
}
|
||||||
|
|
|
@ -60,7 +60,8 @@ typedef enum {
|
||||||
NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC = 1 << 2,
|
NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC = 1 << 2,
|
||||||
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
|
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
|
||||||
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
|
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
|
||||||
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5
|
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5,
|
||||||
|
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6
|
||||||
} nghttp2_option_flag;
|
} nghttp2_option_flag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,6 +93,10 @@ struct nghttp2_option {
|
||||||
* NGHTTP2_OPT_NO_HTTP_MESSAGING
|
* NGHTTP2_OPT_NO_HTTP_MESSAGING
|
||||||
*/
|
*/
|
||||||
int no_http_messaging;
|
int no_http_messaging;
|
||||||
|
/**
|
||||||
|
* NGHTTP2_OPT_NO_AUTO_PING_ACK
|
||||||
|
*/
|
||||||
|
int no_auto_ping_ack;
|
||||||
/**
|
/**
|
||||||
* NGHTTP2_OPT_USER_RECV_EXT_TYPES
|
* NGHTTP2_OPT_USER_RECV_EXT_TYPES
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -416,6 +416,11 @@ static int session_new(nghttp2_session **session_ptr,
|
||||||
memcpy((*session_ptr)->user_recv_ext_types, option->user_recv_ext_types,
|
memcpy((*session_ptr)->user_recv_ext_types, option->user_recv_ext_types,
|
||||||
sizeof((*session_ptr)->user_recv_ext_types));
|
sizeof((*session_ptr)->user_recv_ext_types));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_PING_ACK) &&
|
||||||
|
option->no_auto_ping_ack) {
|
||||||
|
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_PING_ACK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(*session_ptr)->callbacks = *callbacks;
|
(*session_ptr)->callbacks = *callbacks;
|
||||||
|
@ -4364,7 +4369,8 @@ int nghttp2_session_on_ping_received(nghttp2_session *session,
|
||||||
return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
|
return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
|
||||||
"PING: stream_id != 0");
|
"PING: stream_id != 0");
|
||||||
}
|
}
|
||||||
if ((frame->hd.flags & NGHTTP2_FLAG_ACK) == 0 &&
|
if ((session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_PING_ACK) == 0 &&
|
||||||
|
(frame->hd.flags & NGHTTP2_FLAG_ACK) == 0 &&
|
||||||
!session_is_closing(session)) {
|
!session_is_closing(session)) {
|
||||||
/* Peer sent ping, so ping it back */
|
/* Peer sent ping, so ping it back */
|
||||||
rv = nghttp2_session_add_ping(session, NGHTTP2_FLAG_ACK,
|
rv = nghttp2_session_add_ping(session, NGHTTP2_FLAG_ACK,
|
||||||
|
|
|
@ -50,7 +50,8 @@ extern int nghttp2_enable_strict_preface;
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0,
|
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0,
|
||||||
NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1,
|
NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1,
|
||||||
NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2
|
NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2,
|
||||||
|
NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3
|
||||||
} nghttp2_optmask;
|
} nghttp2_optmask;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -211,8 +211,9 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
|
||||||
nvlen, NULL, stream_user_data);
|
nvlen, NULL, stream_user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags _U_,
|
int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
|
||||||
const uint8_t *opaque_data) {
|
const uint8_t *opaque_data) {
|
||||||
|
flags &= NGHTTP2_FLAG_ACK;
|
||||||
return nghttp2_session_add_ping(session, NGHTTP2_FLAG_NONE, opaque_data);
|
return nghttp2_session_add_ping(session, NGHTTP2_FLAG_NONE, opaque_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3095,6 +3095,7 @@ void test_nghttp2_session_on_ping_received(void) {
|
||||||
nghttp2_frame frame;
|
nghttp2_frame frame;
|
||||||
nghttp2_outbound_item *top;
|
nghttp2_outbound_item *top;
|
||||||
const uint8_t opaque_data[] = "01234567";
|
const uint8_t opaque_data[] = "01234567";
|
||||||
|
nghttp2_option *option;
|
||||||
|
|
||||||
user_data.frame_recv_cb_called = 0;
|
user_data.frame_recv_cb_called = 0;
|
||||||
user_data.invalid_frame_recv_cb_called = 0;
|
user_data.invalid_frame_recv_cb_called = 0;
|
||||||
|
@ -3125,6 +3126,23 @@ void test_nghttp2_session_on_ping_received(void) {
|
||||||
|
|
||||||
nghttp2_frame_ping_free(&frame.ping);
|
nghttp2_frame_ping_free(&frame.ping);
|
||||||
nghttp2_session_del(session);
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
/* Use nghttp2_option_set_no_auto_ping_ack() */
|
||||||
|
nghttp2_option_new(&option);
|
||||||
|
nghttp2_option_set_no_auto_ping_ack(option, 1);
|
||||||
|
|
||||||
|
nghttp2_session_server_new2(&session, &callbacks, &user_data, option);
|
||||||
|
nghttp2_frame_ping_init(&frame.ping, NGHTTP2_FLAG_NONE, NULL);
|
||||||
|
|
||||||
|
user_data.frame_recv_cb_called = 0;
|
||||||
|
|
||||||
|
CU_ASSERT(0 == nghttp2_session_on_ping_received(session, &frame));
|
||||||
|
CU_ASSERT(1 == user_data.frame_recv_cb_called);
|
||||||
|
CU_ASSERT(NULL == nghttp2_outbound_queue_top(&session->ob_urgent));
|
||||||
|
|
||||||
|
nghttp2_frame_ping_free(&frame.ping);
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
nghttp2_option_del(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nghttp2_session_on_goaway_received(void) {
|
void test_nghttp2_session_on_goaway_received(void) {
|
||||||
|
@ -6153,6 +6171,15 @@ void test_nghttp2_session_set_option(void) {
|
||||||
CU_ASSERT(99 == session->max_incoming_reserved_streams);
|
CU_ASSERT(99 == session->max_incoming_reserved_streams);
|
||||||
nghttp2_session_del(session);
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
/* Test for nghttp2_option_set_no_auto_ping_ack */
|
||||||
|
nghttp2_option_set_no_auto_ping_ack(option, 1);
|
||||||
|
|
||||||
|
nghttp2_session_client_new2(&session, &callbacks, NULL, option);
|
||||||
|
|
||||||
|
CU_ASSERT(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_PING_ACK);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
nghttp2_option_del(option);
|
nghttp2_option_del(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue