Add nghttp2_option_set_max_deflate_dynamic_table_size() API function

nghttp2_option_set_max_deflate_dynamic_table_size function sets the
maximum dynamic table size for header block deflater.  The default
value is 4KiB.
This commit is contained in:
Tatsuhiro Tsujikawa 2016-09-11 22:13:59 +09:00
parent 905e16cb99
commit 392256e542
5 changed files with 80 additions and 17 deletions

View File

@ -2532,6 +2532,19 @@ NGHTTP2_EXTERN void
nghttp2_option_set_max_send_header_block_length(nghttp2_option *option, nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
size_t val); size_t val);
/**
* @function
*
* This option sets the maximum dynamic table size for deflating
* header fields. The default value is 4KiB. In HTTP/2, receiver of
* deflated header block can specify maximum dynamic table size. The
* actual maximum size is the minimum of the size receiver specified
* and this option value.
*/
NGHTTP2_EXTERN void
nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
size_t val);
/** /**
* @function * @function
* *

View File

@ -101,3 +101,9 @@ void nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
option->opt_set_mask |= NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH; option->opt_set_mask |= NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH;
option->max_send_header_block_length = val; option->max_send_header_block_length = val;
} }
void nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
size_t val) {
option->opt_set_mask |= NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE;
option->max_deflate_dynamic_table_size = val;
}

View File

@ -64,6 +64,7 @@ typedef enum {
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6, NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7, NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7,
NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8, NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8,
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
} nghttp2_option_flag; } nghttp2_option_flag;
/** /**
@ -74,6 +75,10 @@ struct nghttp2_option {
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH * NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
*/ */
size_t max_send_header_block_length; size_t max_send_header_block_length;
/**
* NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE
*/
size_t max_deflate_dynamic_table_size;
/** /**
* Bitwise OR of nghttp2_option_flag to determine that which fields * Bitwise OR of nghttp2_option_flag to determine that which fields
* are specified. * are specified.

View File

@ -390,6 +390,8 @@ static int session_new(nghttp2_session **session_ptr,
const nghttp2_option *option, nghttp2_mem *mem) { const nghttp2_option *option, nghttp2_mem *mem) {
int rv; int rv;
size_t nbuffer; size_t nbuffer;
size_t max_deflate_dynamic_table_size =
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
if (mem == NULL) { if (mem == NULL) {
mem = nghttp2_mem_default(); mem = nghttp2_mem_default();
@ -407,19 +409,6 @@ static int session_new(nghttp2_session **session_ptr,
/* next_stream_id is initialized in either /* next_stream_id is initialized in either
nghttp2_session_client_new2 or nghttp2_session_server_new2 */ nghttp2_session_client_new2 or nghttp2_session_server_new2 */
rv = nghttp2_hd_deflate_init(&(*session_ptr)->hd_deflater, mem);
if (rv != 0) {
goto fail_hd_deflater;
}
rv = nghttp2_hd_inflate_init(&(*session_ptr)->hd_inflater, mem);
if (rv != 0) {
goto fail_hd_inflater;
}
rv = nghttp2_map_init(&(*session_ptr)->streams, mem);
if (rv != 0) {
goto fail_map;
}
nghttp2_stream_init(&(*session_ptr)->root, 0, NGHTTP2_STREAM_FLAG_NONE, nghttp2_stream_init(&(*session_ptr)->root, 0, NGHTTP2_STREAM_FLAG_NONE,
NGHTTP2_STREAM_IDLE, NGHTTP2_DEFAULT_WEIGHT, 0, 0, NULL, NGHTTP2_STREAM_IDLE, NGHTTP2_DEFAULT_WEIGHT, 0, 0, NULL,
mem); mem);
@ -502,6 +491,24 @@ static int session_new(nghttp2_session **session_ptr,
(*session_ptr)->max_send_header_block_length = (*session_ptr)->max_send_header_block_length =
option->max_send_header_block_length; option->max_send_header_block_length;
} }
if (option->opt_set_mask & NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE) {
max_deflate_dynamic_table_size = option->max_deflate_dynamic_table_size;
}
}
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
max_deflate_dynamic_table_size, mem);
if (rv != 0) {
goto fail_hd_deflater;
}
rv = nghttp2_hd_inflate_init(&(*session_ptr)->hd_inflater, mem);
if (rv != 0) {
goto fail_hd_inflater;
}
rv = nghttp2_map_init(&(*session_ptr)->streams, mem);
if (rv != 0) {
goto fail_map;
} }
nbuffer = ((*session_ptr)->max_send_header_block_length + nbuffer = ((*session_ptr)->max_send_header_block_length +

View File

@ -6666,33 +6666,45 @@ void test_nghttp2_session_set_option(void) {
nghttp2_session *session; nghttp2_session *session;
nghttp2_session_callbacks callbacks; nghttp2_session_callbacks callbacks;
nghttp2_option *option; nghttp2_option *option;
nghttp2_hd_deflater *deflater;
nghttp2_option_new(&option); int rv;
nghttp2_option_set_no_auto_window_update(option, 1);
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.send_callback = null_send_callback;
/* Test for nghttp2_option_set_no_auto_window_update */
nghttp2_option_new(&option);
nghttp2_option_set_no_auto_window_update(option, 1);
nghttp2_session_client_new2(&session, &callbacks, NULL, option); nghttp2_session_client_new2(&session, &callbacks, NULL, option);
CU_ASSERT(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE); CU_ASSERT(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE);
nghttp2_session_del(session); nghttp2_session_del(session);
nghttp2_option_del(option);
/* Test for nghttp2_option_set_peer_max_concurrent_streams */
nghttp2_option_new(&option);
nghttp2_option_set_peer_max_concurrent_streams(option, 100); nghttp2_option_set_peer_max_concurrent_streams(option, 100);
nghttp2_session_client_new2(&session, &callbacks, NULL, option); nghttp2_session_client_new2(&session, &callbacks, NULL, option);
CU_ASSERT(100 == session->remote_settings.max_concurrent_streams); CU_ASSERT(100 == session->remote_settings.max_concurrent_streams);
nghttp2_session_del(session); nghttp2_session_del(session);
nghttp2_option_del(option);
/* Test for nghttp2_option_set_max_reserved_remote_streams */
nghttp2_option_new(&option);
nghttp2_option_set_max_reserved_remote_streams(option, 99); nghttp2_option_set_max_reserved_remote_streams(option, 99);
nghttp2_session_client_new2(&session, &callbacks, NULL, option); nghttp2_session_client_new2(&session, &callbacks, NULL, option);
CU_ASSERT(99 == session->max_incoming_reserved_streams); CU_ASSERT(99 == session->max_incoming_reserved_streams);
nghttp2_session_del(session); nghttp2_session_del(session);
nghttp2_option_del(option);
/* Test for nghttp2_option_set_no_auto_ping_ack */ /* Test for nghttp2_option_set_no_auto_ping_ack */
nghttp2_option_new(&option);
nghttp2_option_set_no_auto_ping_ack(option, 1); nghttp2_option_set_no_auto_ping_ack(option, 1);
nghttp2_session_client_new2(&session, &callbacks, NULL, option); nghttp2_session_client_new2(&session, &callbacks, NULL, option);
@ -6700,7 +6712,27 @@ void test_nghttp2_session_set_option(void) {
CU_ASSERT(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_PING_ACK); CU_ASSERT(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_PING_ACK);
nghttp2_session_del(session); nghttp2_session_del(session);
nghttp2_option_del(option);
/* Test for nghttp2_option_set_max_deflate_dynamic_table_size */
nghttp2_option_new(&option);
nghttp2_option_set_max_deflate_dynamic_table_size(option, 0);
nghttp2_session_client_new2(&session, &callbacks, NULL, option);
deflater = &session->hd_deflater;
rv = nghttp2_submit_request(session, NULL, reqnv, ARRLEN(reqnv), NULL, NULL);
CU_ASSERT(1 == rv);
rv = nghttp2_session_send(session);
CU_ASSERT(0 == rv);
CU_ASSERT(0 == deflater->deflate_hd_table_bufsize_max);
CU_ASSERT(0 == deflater->ctx.hd_table_bufsize);
nghttp2_session_del(session);
nghttp2_option_del(option); nghttp2_option_del(option);
} }