Merge branch 'set-max-deflate-dynamic-table-size'
This commit is contained in:
commit
e464b10fc3
|
@ -142,6 +142,10 @@ OPTIONS = [
|
||||||
"frontend-http2-connection-window-size",
|
"frontend-http2-connection-window-size",
|
||||||
"backend-http2-window-size",
|
"backend-http2-window-size",
|
||||||
"backend-http2-connection-window-size",
|
"backend-http2-connection-window-size",
|
||||||
|
"frontend-http2-encoder-dynamic-table-size",
|
||||||
|
"frontend-http2-decoder-dynamic-table-size",
|
||||||
|
"backend-http2-encoder-dynamic-table-size",
|
||||||
|
"backend-http2-decoder-dynamic-table-size",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGVARS = [
|
LOGVARS = [
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -4583,7 +4596,7 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
|
||||||
*
|
*
|
||||||
* Initializes |*deflater_ptr| for deflating name/values pairs.
|
* Initializes |*deflater_ptr| for deflating name/values pairs.
|
||||||
*
|
*
|
||||||
* The |deflate_hd_table_bufsize_max| is the upper bound of header
|
* The |max_deflate_dynamic_table_size| is the upper bound of header
|
||||||
* table size the deflater will use.
|
* table size the deflater will use.
|
||||||
*
|
*
|
||||||
* If this function fails, |*deflater_ptr| is left untouched.
|
* If this function fails, |*deflater_ptr| is left untouched.
|
||||||
|
@ -4594,8 +4607,9 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
|
||||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
NGHTTP2_EXTERN int
|
||||||
size_t deflate_hd_table_bufsize_max);
|
nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
||||||
|
size_t max_deflate_dynamic_table_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
|
@ -4612,9 +4626,10 @@ NGHTTP2_EXTERN int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
||||||
* The library code does not refer to |mem| pointer after this
|
* The library code does not refer to |mem| pointer after this
|
||||||
* function returns, so the application can safely free it.
|
* function returns, so the application can safely free it.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
|
NGHTTP2_EXTERN int
|
||||||
size_t deflate_hd_table_bufsize_max,
|
nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
|
||||||
nghttp2_mem *mem);
|
size_t max_deflate_dynamic_table_size,
|
||||||
|
nghttp2_mem *mem);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
|
@ -4627,18 +4642,18 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
* Changes header table size of the |deflater| to
|
* Changes header table size of the |deflater| to
|
||||||
* |settings_hd_table_bufsize_max| bytes. This may trigger eviction
|
* |settings_max_dynamic_table_size| bytes. This may trigger eviction
|
||||||
* in the dynamic table.
|
* in the dynamic table.
|
||||||
*
|
*
|
||||||
* The |settings_hd_table_bufsize_max| should be the value received in
|
* The |settings_max_dynamic_table_size| should be the value received
|
||||||
* SETTINGS_HEADER_TABLE_SIZE.
|
* in SETTINGS_HEADER_TABLE_SIZE.
|
||||||
*
|
*
|
||||||
* The deflater never uses more memory than
|
* The deflater never uses more memory than
|
||||||
* ``deflate_hd_table_bufsize_max`` bytes specified in
|
* ``max_deflate_dynamic_table_size`` bytes specified in
|
||||||
* `nghttp2_hd_deflate_new()`. Therefore, if
|
* `nghttp2_hd_deflate_new()`. Therefore, if
|
||||||
* |settings_hd_table_bufsize_max| > ``deflate_hd_table_bufsize_max``,
|
* |settings_max_dynamic_table_size| >
|
||||||
* resulting maximum table size becomes
|
* ``max_deflate_dynamic_table_size``, resulting maximum table size
|
||||||
* ``deflate_hd_table_bufsize_max``.
|
* becomes ``max_deflate_dynamic_table_size``.
|
||||||
*
|
*
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
* negative error codes:
|
* negative error codes:
|
||||||
|
@ -4648,7 +4663,7 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int
|
NGHTTP2_EXTERN int
|
||||||
nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
||||||
size_t settings_hd_table_bufsize_max);
|
size_t settings_max_dynamic_table_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
|
@ -4819,8 +4834,8 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
|
||||||
* Changes header table size in the |inflater|. This may trigger
|
* Changes header table size in the |inflater|. This may trigger
|
||||||
* eviction in the dynamic table.
|
* eviction in the dynamic table.
|
||||||
*
|
*
|
||||||
* The |settings_hd_table_bufsize_max| should be the value transmitted
|
* The |settings_max_dynamic_table_size| should be the value
|
||||||
* in SETTINGS_HEADER_TABLE_SIZE.
|
* transmitted in SETTINGS_HEADER_TABLE_SIZE.
|
||||||
*
|
*
|
||||||
* This function must not be called while header block is being
|
* This function must not be called while header block is being
|
||||||
* inflated. In other words, this function must be called after
|
* inflated. In other words, this function must be called after
|
||||||
|
@ -4841,7 +4856,7 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int
|
NGHTTP2_EXTERN int
|
||||||
nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
||||||
size_t settings_hd_table_bufsize_max);
|
size_t settings_max_dynamic_table_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum
|
* @enum
|
||||||
|
|
|
@ -684,7 +684,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||||
size_t deflate_hd_table_bufsize_max,
|
size_t max_deflate_dynamic_table_size,
|
||||||
nghttp2_mem *mem) {
|
nghttp2_mem *mem) {
|
||||||
int rv;
|
int rv;
|
||||||
rv = hd_context_init(&deflater->ctx, mem);
|
rv = hd_context_init(&deflater->ctx, mem);
|
||||||
|
@ -694,14 +694,14 @@ int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||||
|
|
||||||
hd_map_init(&deflater->map);
|
hd_map_init(&deflater->map);
|
||||||
|
|
||||||
if (deflate_hd_table_bufsize_max < NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE) {
|
if (max_deflate_dynamic_table_size < NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE) {
|
||||||
deflater->notify_table_size_change = 1;
|
deflater->notify_table_size_change = 1;
|
||||||
deflater->ctx.hd_table_bufsize_max = deflate_hd_table_bufsize_max;
|
deflater->ctx.hd_table_bufsize_max = max_deflate_dynamic_table_size;
|
||||||
} else {
|
} else {
|
||||||
deflater->notify_table_size_change = 0;
|
deflater->notify_table_size_change = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
deflater->deflate_hd_table_bufsize_max = deflate_hd_table_bufsize_max;
|
deflater->deflate_hd_table_bufsize_max = max_deflate_dynamic_table_size;
|
||||||
deflater->min_hd_table_bufsize_max = UINT32_MAX;
|
deflater->min_hd_table_bufsize_max = UINT32_MAX;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1225,9 +1225,9 @@ static void hd_context_shrink_table_size(nghttp2_hd_context *context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_change_table_size(
|
||||||
size_t settings_hd_table_bufsize_max) {
|
nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size) {
|
||||||
size_t next_bufsize = nghttp2_min(settings_hd_table_bufsize_max,
|
size_t next_bufsize = nghttp2_min(settings_max_dynamic_table_size,
|
||||||
deflater->deflate_hd_table_bufsize_max);
|
deflater->deflate_hd_table_bufsize_max);
|
||||||
|
|
||||||
deflater->ctx.hd_table_bufsize_max = next_bufsize;
|
deflater->ctx.hd_table_bufsize_max = next_bufsize;
|
||||||
|
@ -1241,8 +1241,8 @@ int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
int nghttp2_hd_inflate_change_table_size(
|
||||||
size_t settings_hd_table_bufsize_max) {
|
nghttp2_hd_inflater *inflater, size_t settings_max_dynamic_table_size) {
|
||||||
switch (inflater->state) {
|
switch (inflater->state) {
|
||||||
case NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE:
|
case NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE:
|
||||||
case NGHTTP2_HD_STATE_INFLATE_START:
|
case NGHTTP2_HD_STATE_INFLATE_START:
|
||||||
|
@ -1258,16 +1258,16 @@ int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
||||||
strictly smaller than the current negotiated maximum size,
|
strictly smaller than the current negotiated maximum size,
|
||||||
encoder must send dynamic table size update. In other cases, we
|
encoder must send dynamic table size update. In other cases, we
|
||||||
cannot expect it to do so. */
|
cannot expect it to do so. */
|
||||||
if (inflater->ctx.hd_table_bufsize_max > settings_hd_table_bufsize_max) {
|
if (inflater->ctx.hd_table_bufsize_max > settings_max_dynamic_table_size) {
|
||||||
inflater->state = NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE;
|
inflater->state = NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE;
|
||||||
/* Remember minimum value, and validate that encoder sends the
|
/* Remember minimum value, and validate that encoder sends the
|
||||||
value less than or equal to this. */
|
value less than or equal to this. */
|
||||||
inflater->min_hd_table_bufsize_max = settings_hd_table_bufsize_max;
|
inflater->min_hd_table_bufsize_max = settings_max_dynamic_table_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
inflater->settings_hd_table_bufsize_max = settings_hd_table_bufsize_max;
|
inflater->settings_hd_table_bufsize_max = settings_max_dynamic_table_size;
|
||||||
|
|
||||||
inflater->ctx.hd_table_bufsize_max = settings_hd_table_bufsize_max;
|
inflater->ctx.hd_table_bufsize_max = settings_max_dynamic_table_size;
|
||||||
|
|
||||||
hd_context_shrink_table_size(&inflater->ctx, NULL);
|
hd_context_shrink_table_size(&inflater->ctx, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -288,7 +288,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
||||||
/*
|
/*
|
||||||
* Initializes |deflater| for deflating name/values pairs.
|
* Initializes |deflater| for deflating name/values pairs.
|
||||||
*
|
*
|
||||||
* The encoder only uses up to |deflate_hd_table_bufsize_max| bytes
|
* The encoder only uses up to |max_deflate_dynamic_table_size| bytes
|
||||||
* for header table even if the larger value is specified later in
|
* for header table even if the larger value is specified later in
|
||||||
* nghttp2_hd_change_table_size().
|
* nghttp2_hd_change_table_size().
|
||||||
*
|
*
|
||||||
|
@ -299,7 +299,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||||
size_t deflate_hd_table_bufsize_max,
|
size_t max_deflate_dynamic_table_size,
|
||||||
nghttp2_mem *mem);
|
nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 +
|
||||||
|
|
|
@ -96,6 +96,7 @@ Config::Config()
|
||||||
num_worker(1),
|
num_worker(1),
|
||||||
max_concurrent_streams(100),
|
max_concurrent_streams(100),
|
||||||
header_table_size(-1),
|
header_table_size(-1),
|
||||||
|
encoder_header_table_size(-1),
|
||||||
window_bits(-1),
|
window_bits(-1),
|
||||||
connection_window_bits(-1),
|
connection_window_bits(-1),
|
||||||
port(0),
|
port(0),
|
||||||
|
@ -231,6 +232,7 @@ public:
|
||||||
config_(config),
|
config_(config),
|
||||||
ssl_ctx_(ssl_ctx),
|
ssl_ctx_(ssl_ctx),
|
||||||
callbacks_(nullptr),
|
callbacks_(nullptr),
|
||||||
|
option_(nullptr),
|
||||||
next_session_id_(1),
|
next_session_id_(1),
|
||||||
tstamp_cached_(ev_now(loop)),
|
tstamp_cached_(ev_now(loop)),
|
||||||
cached_date_(util::http_date(tstamp_cached_)) {
|
cached_date_(util::http_date(tstamp_cached_)) {
|
||||||
|
@ -238,6 +240,13 @@ public:
|
||||||
|
|
||||||
fill_callback(callbacks_, config_);
|
fill_callback(callbacks_, config_);
|
||||||
|
|
||||||
|
nghttp2_option_new(&option_);
|
||||||
|
|
||||||
|
if (config_->encoder_header_table_size != -1) {
|
||||||
|
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||||
|
option_, config_->encoder_header_table_size);
|
||||||
|
}
|
||||||
|
|
||||||
ev_timer_init(&release_fd_timer_, release_fd_cb, 0., RELEASE_FD_TIMEOUT);
|
ev_timer_init(&release_fd_timer_, release_fd_cb, 0., RELEASE_FD_TIMEOUT);
|
||||||
release_fd_timer_.data = this;
|
release_fd_timer_.data = this;
|
||||||
}
|
}
|
||||||
|
@ -246,6 +255,7 @@ public:
|
||||||
for (auto handler : handlers_) {
|
for (auto handler : handlers_) {
|
||||||
delete handler;
|
delete handler;
|
||||||
}
|
}
|
||||||
|
nghttp2_option_del(option_);
|
||||||
nghttp2_session_callbacks_del(callbacks_);
|
nghttp2_session_callbacks_del(callbacks_);
|
||||||
}
|
}
|
||||||
void add_handler(Http2Handler *handler) { handlers_.insert(handler); }
|
void add_handler(Http2Handler *handler) { handlers_.insert(handler); }
|
||||||
|
@ -283,6 +293,7 @@ public:
|
||||||
return session_id;
|
return session_id;
|
||||||
}
|
}
|
||||||
const nghttp2_session_callbacks *get_callbacks() const { return callbacks_; }
|
const nghttp2_session_callbacks *get_callbacks() const { return callbacks_; }
|
||||||
|
const nghttp2_option *get_option() const { return option_; }
|
||||||
void accept_connection(int fd) {
|
void accept_connection(int fd) {
|
||||||
util::make_socket_nodelay(fd);
|
util::make_socket_nodelay(fd);
|
||||||
SSL *ssl = nullptr;
|
SSL *ssl = nullptr;
|
||||||
|
@ -408,6 +419,7 @@ private:
|
||||||
const Config *config_;
|
const Config *config_;
|
||||||
SSL_CTX *ssl_ctx_;
|
SSL_CTX *ssl_ctx_;
|
||||||
nghttp2_session_callbacks *callbacks_;
|
nghttp2_session_callbacks *callbacks_;
|
||||||
|
nghttp2_option *option_;
|
||||||
ev_timer release_fd_timer_;
|
ev_timer release_fd_timer_;
|
||||||
int64_t next_session_id_;
|
int64_t next_session_id_;
|
||||||
ev_tstamp tstamp_cached_;
|
ev_tstamp tstamp_cached_;
|
||||||
|
@ -825,7 +837,8 @@ int Http2Handler::on_write() { return write_(*this); }
|
||||||
int Http2Handler::connection_made() {
|
int Http2Handler::connection_made() {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = nghttp2_session_server_new(&session_, sessions_->get_callbacks(), this);
|
r = nghttp2_session_server_new2(&session_, sessions_->get_callbacks(), this,
|
||||||
|
sessions_->get_option());
|
||||||
|
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -69,6 +69,7 @@ struct Config {
|
||||||
size_t num_worker;
|
size_t num_worker;
|
||||||
size_t max_concurrent_streams;
|
size_t max_concurrent_streams;
|
||||||
ssize_t header_table_size;
|
ssize_t header_table_size;
|
||||||
|
ssize_t encoder_header_table_size;
|
||||||
int window_bits;
|
int window_bits;
|
||||||
int connection_window_bits;
|
int connection_window_bits;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
|
|
|
@ -95,6 +95,7 @@ constexpr auto anchors = std::array<Anchor, 5>{{
|
||||||
Config::Config()
|
Config::Config()
|
||||||
: header_table_size(-1),
|
: header_table_size(-1),
|
||||||
min_header_table_size(std::numeric_limits<uint32_t>::max()),
|
min_header_table_size(std::numeric_limits<uint32_t>::max()),
|
||||||
|
encoder_header_table_size(-1),
|
||||||
padding(0),
|
padding(0),
|
||||||
max_concurrent_streams(100),
|
max_concurrent_streams(100),
|
||||||
peer_max_concurrent_streams(100),
|
peer_max_concurrent_streams(100),
|
||||||
|
@ -2619,6 +2620,11 @@ Options:
|
||||||
the last value, that minimum value is set in SETTINGS
|
the last value, that minimum value is set in SETTINGS
|
||||||
frame payload before the last value, to simulate
|
frame payload before the last value, to simulate
|
||||||
multiple header table size change.
|
multiple header table size change.
|
||||||
|
--encoder-header-table-size=<SIZE>
|
||||||
|
Specify encoder header table size. The decoder (server)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which server specified.
|
||||||
-b, --padding=<N>
|
-b, --padding=<N>
|
||||||
Add at most <N> bytes to a frame payload as padding.
|
Add at most <N> bytes to a frame payload as padding.
|
||||||
Specify 0 to disable padding.
|
Specify 0 to disable padding.
|
||||||
|
@ -2695,6 +2701,7 @@ int main(int argc, char **argv) {
|
||||||
{"no-push", no_argument, &flag, 11},
|
{"no-push", no_argument, &flag, 11},
|
||||||
{"max-concurrent-streams", required_argument, &flag, 12},
|
{"max-concurrent-streams", required_argument, &flag, 12},
|
||||||
{"expect-continue", no_argument, &flag, 13},
|
{"expect-continue", no_argument, &flag, 13},
|
||||||
|
{"encoder-header-table-size", required_argument, &flag, 14},
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
int c = getopt_long(argc, argv, "M:Oab:c:d:gm:np:r:hH:vst:uw:W:",
|
int c = getopt_long(argc, argv, "M:Oab:c:d:gm:np:r:hH:vst:uw:W:",
|
||||||
|
@ -2813,16 +2820,21 @@ int main(int argc, char **argv) {
|
||||||
case 'm':
|
case 'm':
|
||||||
config.multiply = strtoul(optarg, nullptr, 10);
|
config.multiply = strtoul(optarg, nullptr, 10);
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c': {
|
||||||
errno = 0;
|
auto n = util::parse_uint_with_unit(optarg);
|
||||||
config.header_table_size = util::parse_uint_with_unit(optarg);
|
if (n == -1) {
|
||||||
if (config.header_table_size == -1) {
|
|
||||||
std::cerr << "-c: Bad option value: " << optarg << std::endl;
|
std::cerr << "-c: Bad option value: " << optarg << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
config.min_header_table_size =
|
if (n > std::numeric_limits<uint32_t>::max()) {
|
||||||
std::min(config.min_header_table_size, config.header_table_size);
|
std::cerr << "-c: Value too large. It should be less than or equal to "
|
||||||
|
<< std::numeric_limits<uint32_t>::max() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.header_table_size = n;
|
||||||
|
config.min_header_table_size = std::min(config.min_header_table_size, n);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case '?':
|
case '?':
|
||||||
util::show_candidates(argv[optind - 1], long_options);
|
util::show_candidates(argv[optind - 1], long_options);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -2896,6 +2908,23 @@ int main(int argc, char **argv) {
|
||||||
// expect-continue option
|
// expect-continue option
|
||||||
config.expect_continue = true;
|
config.expect_continue = true;
|
||||||
break;
|
break;
|
||||||
|
case 14: {
|
||||||
|
// encoder-header-table-size option
|
||||||
|
auto n = util::parse_uint_with_unit(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "--encoder-header-table-size: Bad option value: "
|
||||||
|
<< optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (n > std::numeric_limits<uint32_t>::max()) {
|
||||||
|
std::cerr << "--encoder-header-table-size: Value too large. It "
|
||||||
|
"should be less than or equal to "
|
||||||
|
<< std::numeric_limits<uint32_t>::max() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.encoder_header_table_size = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2916,6 +2945,11 @@ int main(int argc, char **argv) {
|
||||||
nghttp2_option_set_peer_max_concurrent_streams(
|
nghttp2_option_set_peer_max_concurrent_streams(
|
||||||
config.http2_option, config.peer_max_concurrent_streams);
|
config.http2_option, config.peer_max_concurrent_streams);
|
||||||
|
|
||||||
|
if (config.encoder_header_table_size != -1) {
|
||||||
|
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||||
|
config.http2_option, config.encoder_header_table_size);
|
||||||
|
}
|
||||||
|
|
||||||
struct sigaction act {};
|
struct sigaction act {};
|
||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &act, nullptr);
|
sigaction(SIGPIPE, &act, nullptr);
|
||||||
|
|
|
@ -72,6 +72,7 @@ struct Config {
|
||||||
nghttp2_option *http2_option;
|
nghttp2_option *http2_option;
|
||||||
int64_t header_table_size;
|
int64_t header_table_size;
|
||||||
int64_t min_header_table_size;
|
int64_t min_header_table_size;
|
||||||
|
int64_t encoder_header_table_size;
|
||||||
size_t padding;
|
size_t padding;
|
||||||
size_t max_concurrent_streams;
|
size_t max_concurrent_streams;
|
||||||
ssize_t peer_max_concurrent_streams;
|
ssize_t peer_max_concurrent_streams;
|
||||||
|
|
|
@ -124,6 +124,11 @@ Options:
|
||||||
--no-tls Disable SSL/TLS.
|
--no-tls Disable SSL/TLS.
|
||||||
-c, --header-table-size=<SIZE>
|
-c, --header-table-size=<SIZE>
|
||||||
Specify decoder header table size.
|
Specify decoder header table size.
|
||||||
|
--encoder-header-table-size=<SIZE>
|
||||||
|
Specify encoder header table size. The decoder (client)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which client specified.
|
||||||
--color Force colored log output.
|
--color Force colored log output.
|
||||||
-p, --push=<PATH>=<PUSH_PATH,...>
|
-p, --push=<PATH>=<PUSH_PATH,...>
|
||||||
Push resources <PUSH_PATH>s when <PATH> is requested.
|
Push resources <PUSH_PATH>s when <PATH> is requested.
|
||||||
|
@ -219,6 +224,7 @@ int main(int argc, char **argv) {
|
||||||
{"echo-upload", no_argument, &flag, 8},
|
{"echo-upload", no_argument, &flag, 8},
|
||||||
{"mime-types-file", required_argument, &flag, 9},
|
{"mime-types-file", required_argument, &flag, 9},
|
||||||
{"no-content-length", no_argument, &flag, 10},
|
{"no-content-length", no_argument, &flag, 10},
|
||||||
|
{"encoder-header-table-size", required_argument, &flag, 11},
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
int c = getopt_long(argc, argv, "DVb:c:d:ehm:n:p:va:w:W:", long_options,
|
int c = getopt_long(argc, argv, "DVb:c:d:ehm:n:p:va:w:W:", long_options,
|
||||||
|
@ -276,14 +282,20 @@ int main(int argc, char **argv) {
|
||||||
case 'v':
|
case 'v':
|
||||||
config.verbose = true;
|
config.verbose = true;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c': {
|
||||||
errno = 0;
|
auto n = util::parse_uint_with_unit(optarg);
|
||||||
config.header_table_size = util::parse_uint_with_unit(optarg);
|
if (n == -1) {
|
||||||
if (config.header_table_size == -1) {
|
|
||||||
std::cerr << "-c: Bad option value: " << optarg << std::endl;
|
std::cerr << "-c: Bad option value: " << optarg << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
if (n > std::numeric_limits<uint32_t>::max()) {
|
||||||
|
std::cerr << "-c: Value too large. It should be less than or equal to "
|
||||||
|
<< std::numeric_limits<uint32_t>::max() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.header_table_size = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'p':
|
case 'p':
|
||||||
if (parse_push_config(config, optarg) != 0) {
|
if (parse_push_config(config, optarg) != 0) {
|
||||||
std::cerr << "-p: Bad option value: " << optarg << std::endl;
|
std::cerr << "-p: Bad option value: " << optarg << std::endl;
|
||||||
|
@ -375,6 +387,23 @@ int main(int argc, char **argv) {
|
||||||
// no-content-length option
|
// no-content-length option
|
||||||
config.no_content_length = true;
|
config.no_content_length = true;
|
||||||
break;
|
break;
|
||||||
|
case 11: {
|
||||||
|
// encoder-header-table-size option
|
||||||
|
auto n = util::parse_uint_with_unit(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "--encoder-header-table-size: Bad option value: "
|
||||||
|
<< optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (n > std::numeric_limits<uint32_t>::max()) {
|
||||||
|
std::cerr << "--encoder-header-table-size: Value too large. It "
|
||||||
|
"should be less than or equal to "
|
||||||
|
<< std::numeric_limits<uint32_t>::max() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.encoder_header_table_size = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
72
src/shrpx.cc
72
src/shrpx.cc
|
@ -1345,14 +1345,21 @@ void fill_default_config(Config *config) {
|
||||||
upstreamconf.connection_window_size = 64_k - 1;
|
upstreamconf.connection_window_size = 64_k - 1;
|
||||||
upstreamconf.max_concurrent_streams = 100;
|
upstreamconf.max_concurrent_streams = 100;
|
||||||
|
|
||||||
|
upstreamconf.encoder_dynamic_table_size = 4_k;
|
||||||
|
upstreamconf.decoder_dynamic_table_size = 4_k;
|
||||||
|
|
||||||
nghttp2_option_new(&upstreamconf.option);
|
nghttp2_option_new(&upstreamconf.option);
|
||||||
nghttp2_option_set_no_auto_window_update(upstreamconf.option, 1);
|
nghttp2_option_set_no_auto_window_update(upstreamconf.option, 1);
|
||||||
nghttp2_option_set_no_recv_client_magic(upstreamconf.option, 1);
|
nghttp2_option_set_no_recv_client_magic(upstreamconf.option, 1);
|
||||||
|
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||||
|
upstreamconf.option, upstreamconf.encoder_dynamic_table_size);
|
||||||
|
|
||||||
// For API endpoint, we enable automatic window update. This is
|
// For API endpoint, we enable automatic window update. This is
|
||||||
// because we are a sink.
|
// because we are a sink.
|
||||||
nghttp2_option_new(&upstreamconf.alt_mode_option);
|
nghttp2_option_new(&upstreamconf.alt_mode_option);
|
||||||
nghttp2_option_set_no_recv_client_magic(upstreamconf.alt_mode_option, 1);
|
nghttp2_option_set_no_recv_client_magic(upstreamconf.alt_mode_option, 1);
|
||||||
|
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||||
|
upstreamconf.alt_mode_option, upstreamconf.encoder_dynamic_table_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1367,9 +1374,14 @@ void fill_default_config(Config *config) {
|
||||||
downstreamconf.connection_window_size = (1u << 31) - 1;
|
downstreamconf.connection_window_size = (1u << 31) - 1;
|
||||||
downstreamconf.max_concurrent_streams = 100;
|
downstreamconf.max_concurrent_streams = 100;
|
||||||
|
|
||||||
|
downstreamconf.encoder_dynamic_table_size = 4_k;
|
||||||
|
downstreamconf.decoder_dynamic_table_size = 4_k;
|
||||||
|
|
||||||
nghttp2_option_new(&downstreamconf.option);
|
nghttp2_option_new(&downstreamconf.option);
|
||||||
nghttp2_option_set_no_auto_window_update(downstreamconf.option, 1);
|
nghttp2_option_set_no_auto_window_update(downstreamconf.option, 1);
|
||||||
nghttp2_option_set_peer_max_concurrent_streams(downstreamconf.option, 100);
|
nghttp2_option_set_peer_max_concurrent_streams(downstreamconf.option, 100);
|
||||||
|
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||||
|
downstreamconf.option, downstreamconf.encoder_dynamic_table_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &loggingconf = config->logging;
|
auto &loggingconf = config->logging;
|
||||||
|
@ -2053,6 +2065,36 @@ HTTP/2 and SPDY:
|
||||||
be adjusted using --frontend-http2-window-size option as
|
be adjusted using --frontend-http2-window-size option as
|
||||||
well. This option is only effective on recent Linux
|
well. This option is only effective on recent Linux
|
||||||
platform.
|
platform.
|
||||||
|
--frontend-http2-encoder-dynamic-table-size=<SIZE>
|
||||||
|
Specify the maximum dynamic table size of HPACK encoder
|
||||||
|
in the frontend HTTP/2 connection. The decoder (client)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which client specified.
|
||||||
|
Default: )"
|
||||||
|
<< util::utos_unit(
|
||||||
|
get_config()->http2.upstream.encoder_dynamic_table_size) << R"(
|
||||||
|
--frontend-http2-decoder-dynamic-table-size=<SIZE>
|
||||||
|
Specify the maximum dynamic table size of HPACK decoder
|
||||||
|
in the frontend HTTP/2 connection.
|
||||||
|
Default: )"
|
||||||
|
<< util::utos_unit(
|
||||||
|
get_config()->http2.upstream.decoder_dynamic_table_size) << R"(
|
||||||
|
--backend-http2-encoder-dynamic-table-size=<SIZE>
|
||||||
|
Specify the maximum dynamic table size of HPACK encoder
|
||||||
|
in the backend HTTP/2 connection. The decoder (backend)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which backend specified.
|
||||||
|
Default: )"
|
||||||
|
<< util::utos_unit(
|
||||||
|
get_config()->http2.downstream.encoder_dynamic_table_size) << R"(
|
||||||
|
--backend-http2-decoder-dynamic-table-size=<SIZE>
|
||||||
|
Specify the maximum dynamic table size of HPACK decoder
|
||||||
|
in the backend HTTP/2 connection.
|
||||||
|
Default: )"
|
||||||
|
<< util::utos_unit(
|
||||||
|
get_config()->http2.downstream.decoder_dynamic_table_size) << R"(
|
||||||
|
|
||||||
Mode:
|
Mode:
|
||||||
(default mode)
|
(default mode)
|
||||||
|
@ -2875,6 +2917,14 @@ int main(int argc, char **argv) {
|
||||||
134},
|
134},
|
||||||
{SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE.c_str(),
|
{SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE.c_str(),
|
||||||
required_argument, &flag, 135},
|
required_argument, &flag, 135},
|
||||||
|
{SHRPX_OPT_FRONTEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE.c_str(),
|
||||||
|
required_argument, &flag, 136},
|
||||||
|
{SHRPX_OPT_FRONTEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE.c_str(),
|
||||||
|
required_argument, &flag, 137},
|
||||||
|
{SHRPX_OPT_BACKEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE.c_str(),
|
||||||
|
required_argument, &flag, 138},
|
||||||
|
{SHRPX_OPT_BACKEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE.c_str(),
|
||||||
|
required_argument, &flag, 139},
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
|
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
@ -3512,6 +3562,28 @@ int main(int argc, char **argv) {
|
||||||
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
||||||
StringRef{optarg});
|
StringRef{optarg});
|
||||||
break;
|
break;
|
||||||
|
case 136:
|
||||||
|
// --frontend-http2-encoder-dynamic-table-size
|
||||||
|
cmdcfgs.emplace_back(
|
||||||
|
SHRPX_OPT_FRONTEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE,
|
||||||
|
StringRef{optarg});
|
||||||
|
break;
|
||||||
|
case 137:
|
||||||
|
// --frontend-http2-decoder-dynamic-table-size
|
||||||
|
cmdcfgs.emplace_back(
|
||||||
|
SHRPX_OPT_FRONTEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE,
|
||||||
|
StringRef{optarg});
|
||||||
|
break;
|
||||||
|
case 138:
|
||||||
|
// --backend-http2-encoder-dynamic-table-size
|
||||||
|
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE,
|
||||||
|
StringRef{optarg});
|
||||||
|
break;
|
||||||
|
case 139:
|
||||||
|
// --backend-http2-decoder-dynamic-table-size
|
||||||
|
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE,
|
||||||
|
StringRef{optarg});
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1733,9 +1733,29 @@ int option_lookup_token(const char *name, size_t namelen) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 40:
|
||||||
|
switch (name[39]) {
|
||||||
|
case 'e':
|
||||||
|
if (util::strieq_l("backend-http2-decoder-dynamic-table-siz", name, 39)) {
|
||||||
|
return SHRPX_OPTID_BACKEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE;
|
||||||
|
}
|
||||||
|
if (util::strieq_l("backend-http2-encoder-dynamic-table-siz", name, 39)) {
|
||||||
|
return SHRPX_OPTID_BACKEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 41:
|
case 41:
|
||||||
switch (name[40]) {
|
switch (name[40]) {
|
||||||
case 'e':
|
case 'e':
|
||||||
|
if (util::strieq_l("frontend-http2-decoder-dynamic-table-siz", name,
|
||||||
|
40)) {
|
||||||
|
return SHRPX_OPTID_FRONTEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE;
|
||||||
|
}
|
||||||
|
if (util::strieq_l("frontend-http2-encoder-dynamic-table-siz", name,
|
||||||
|
40)) {
|
||||||
|
return SHRPX_OPTID_FRONTEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE;
|
||||||
|
}
|
||||||
if (util::strieq_l("frontend-http2-optimize-write-buffer-siz", name,
|
if (util::strieq_l("frontend-http2-optimize-write-buffer-siz", name,
|
||||||
40)) {
|
40)) {
|
||||||
return SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WRITE_BUFFER_SIZE;
|
return SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WRITE_BUFFER_SIZE;
|
||||||
|
@ -2773,6 +2793,38 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
case SHRPX_OPTID_FRONTEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE:
|
||||||
|
if (parse_uint_with_unit(&config->http2.upstream.encoder_dynamic_table_size,
|
||||||
|
opt, optarg) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||||
|
config->http2.upstream.option,
|
||||||
|
config->http2.upstream.encoder_dynamic_table_size);
|
||||||
|
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||||
|
config->http2.upstream.alt_mode_option,
|
||||||
|
config->http2.upstream.encoder_dynamic_table_size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
case SHRPX_OPTID_FRONTEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE:
|
||||||
|
return parse_uint_with_unit(
|
||||||
|
&config->http2.upstream.decoder_dynamic_table_size, opt, optarg);
|
||||||
|
case SHRPX_OPTID_BACKEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE:
|
||||||
|
if (parse_uint_with_unit(
|
||||||
|
&config->http2.downstream.encoder_dynamic_table_size, opt,
|
||||||
|
optarg) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||||
|
config->http2.downstream.option,
|
||||||
|
config->http2.downstream.encoder_dynamic_table_size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
case SHRPX_OPTID_BACKEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE:
|
||||||
|
return parse_uint_with_unit(
|
||||||
|
&config->http2.downstream.decoder_dynamic_table_size, opt, optarg);
|
||||||
case SHRPX_OPTID_CONF:
|
case SHRPX_OPTID_CONF:
|
||||||
LOG(WARN) << "conf: ignored";
|
LOG(WARN) << "conf: ignored";
|
||||||
|
|
||||||
|
|
|
@ -299,6 +299,14 @@ constexpr auto SHRPX_OPT_BACKEND_HTTP2_WINDOW_SIZE =
|
||||||
StringRef::from_lit("backend-http2-window-size");
|
StringRef::from_lit("backend-http2-window-size");
|
||||||
constexpr auto SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE =
|
constexpr auto SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE =
|
||||||
StringRef::from_lit("backend-http2-connection-window-size");
|
StringRef::from_lit("backend-http2-connection-window-size");
|
||||||
|
constexpr auto SHRPX_OPT_FRONTEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE =
|
||||||
|
StringRef::from_lit("frontend-http2-encoder-dynamic-table-size");
|
||||||
|
constexpr auto SHRPX_OPT_FRONTEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE =
|
||||||
|
StringRef::from_lit("frontend-http2-decoder-dynamic-table-size");
|
||||||
|
constexpr auto SHRPX_OPT_BACKEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE =
|
||||||
|
StringRef::from_lit("backend-http2-encoder-dynamic-table-size");
|
||||||
|
constexpr auto SHRPX_OPT_BACKEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE =
|
||||||
|
StringRef::from_lit("backend-http2-decoder-dynamic-table-size");
|
||||||
|
|
||||||
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
||||||
|
|
||||||
|
@ -595,9 +603,11 @@ struct Http2Config {
|
||||||
nghttp2_option *option;
|
nghttp2_option *option;
|
||||||
nghttp2_option *alt_mode_option;
|
nghttp2_option *alt_mode_option;
|
||||||
nghttp2_session_callbacks *callbacks;
|
nghttp2_session_callbacks *callbacks;
|
||||||
|
size_t max_concurrent_streams;
|
||||||
|
size_t encoder_dynamic_table_size;
|
||||||
|
size_t decoder_dynamic_table_size;
|
||||||
int32_t window_size;
|
int32_t window_size;
|
||||||
int32_t connection_window_size;
|
int32_t connection_window_size;
|
||||||
size_t max_concurrent_streams;
|
|
||||||
bool optimize_write_buffer_size;
|
bool optimize_write_buffer_size;
|
||||||
bool optimize_window_size;
|
bool optimize_window_size;
|
||||||
} upstream;
|
} upstream;
|
||||||
|
@ -607,6 +617,8 @@ struct Http2Config {
|
||||||
} timeout;
|
} timeout;
|
||||||
nghttp2_option *option;
|
nghttp2_option *option;
|
||||||
nghttp2_session_callbacks *callbacks;
|
nghttp2_session_callbacks *callbacks;
|
||||||
|
size_t encoder_dynamic_table_size;
|
||||||
|
size_t decoder_dynamic_table_size;
|
||||||
int32_t window_size;
|
int32_t window_size;
|
||||||
int32_t connection_window_size;
|
int32_t connection_window_size;
|
||||||
size_t max_concurrent_streams;
|
size_t max_concurrent_streams;
|
||||||
|
@ -795,6 +807,8 @@ enum {
|
||||||
SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_BITS,
|
SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_BITS,
|
||||||
SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
||||||
SHRPX_OPTID_BACKEND_HTTP2_CONNECTIONS_PER_WORKER,
|
SHRPX_OPTID_BACKEND_HTTP2_CONNECTIONS_PER_WORKER,
|
||||||
|
SHRPX_OPTID_BACKEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE,
|
||||||
|
SHRPX_OPTID_BACKEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE,
|
||||||
SHRPX_OPTID_BACKEND_HTTP2_MAX_CONCURRENT_STREAMS,
|
SHRPX_OPTID_BACKEND_HTTP2_MAX_CONCURRENT_STREAMS,
|
||||||
SHRPX_OPTID_BACKEND_HTTP2_SETTINGS_TIMEOUT,
|
SHRPX_OPTID_BACKEND_HTTP2_SETTINGS_TIMEOUT,
|
||||||
SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS,
|
SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS,
|
||||||
|
@ -832,8 +846,10 @@ enum {
|
||||||
SHRPX_OPTID_FRONTEND_FRAME_DEBUG,
|
SHRPX_OPTID_FRONTEND_FRAME_DEBUG,
|
||||||
SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS,
|
SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS,
|
||||||
SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
||||||
|
SHRPX_OPTID_FRONTEND_HTTP2_DECODER_DYNAMIC_TABLE_SIZE,
|
||||||
SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER,
|
SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER,
|
||||||
SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER,
|
SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER,
|
||||||
|
SHRPX_OPTID_FRONTEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE,
|
||||||
SHRPX_OPTID_FRONTEND_HTTP2_MAX_CONCURRENT_STREAMS,
|
SHRPX_OPTID_FRONTEND_HTTP2_MAX_CONCURRENT_STREAMS,
|
||||||
SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WINDOW_SIZE,
|
SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WINDOW_SIZE,
|
||||||
SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WRITE_BUFFER_SIZE,
|
SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WRITE_BUFFER_SIZE,
|
||||||
|
|
|
@ -1569,7 +1569,7 @@ int Http2Session::connection_made() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<nghttp2_settings_entry, 3> entry;
|
std::array<nghttp2_settings_entry, 4> entry;
|
||||||
size_t nentry = 2;
|
size_t nentry = 2;
|
||||||
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||||
entry[0].value = http2conf.downstream.max_concurrent_streams;
|
entry[0].value = http2conf.downstream.max_concurrent_streams;
|
||||||
|
@ -1583,6 +1583,13 @@ int Http2Session::connection_made() {
|
||||||
++nentry;
|
++nentry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (http2conf.downstream.decoder_dynamic_table_size !=
|
||||||
|
NGHTTP2_DEFAULT_HEADER_TABLE_SIZE) {
|
||||||
|
entry[nentry].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
|
||||||
|
entry[nentry].value = http2conf.downstream.decoder_dynamic_table_size;
|
||||||
|
++nentry;
|
||||||
|
}
|
||||||
|
|
||||||
rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
|
rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
|
||||||
nentry);
|
nentry);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
|
|
|
@ -939,7 +939,9 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||||
flow_control_ = true;
|
flow_control_ = true;
|
||||||
|
|
||||||
// TODO Maybe call from outside?
|
// TODO Maybe call from outside?
|
||||||
std::array<nghttp2_settings_entry, 2> entry;
|
std::array<nghttp2_settings_entry, 3> entry;
|
||||||
|
size_t nentry = 2;
|
||||||
|
|
||||||
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||||
entry[0].value = http2conf.upstream.max_concurrent_streams;
|
entry[0].value = http2conf.upstream.max_concurrent_streams;
|
||||||
|
|
||||||
|
@ -950,8 +952,15 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||||
entry[1].value = http2conf.upstream.window_size;
|
entry[1].value = http2conf.upstream.window_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (http2conf.upstream.decoder_dynamic_table_size !=
|
||||||
|
NGHTTP2_DEFAULT_HEADER_TABLE_SIZE) {
|
||||||
|
entry[nentry].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
|
||||||
|
entry[nentry].value = http2conf.upstream.decoder_dynamic_table_size;
|
||||||
|
++nentry;
|
||||||
|
}
|
||||||
|
|
||||||
rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
|
rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
|
||||||
entry.size());
|
nentry);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
ULOG(ERROR, this) << "nghttp2_submit_settings() returned error: "
|
ULOG(ERROR, this) << "nghttp2_submit_settings() returned error: "
|
||||||
<< nghttp2_strerror(rv);
|
<< nghttp2_strerror(rv);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue