nghttpx: Add option to specify HPACK encoder/decoder dynamic table size
This commit is contained in:
parent
743fc4a3c3
commit
f4016644a9
|
@ -142,6 +142,10 @@ OPTIONS = [
|
|||
"frontend-http2-connection-window-size",
|
||||
"backend-http2-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 = [
|
||||
|
|
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.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_set_no_auto_window_update(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
|
||||
// because we are a sink.
|
||||
nghttp2_option_new(&upstreamconf.alt_mode_option);
|
||||
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.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_set_no_auto_window_update(downstreamconf.option, 1);
|
||||
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;
|
||||
|
@ -2053,6 +2065,36 @@ HTTP/2 and SPDY:
|
|||
be adjusted using --frontend-http2-window-size option as
|
||||
well. This option is only effective on recent Linux
|
||||
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 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 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:
|
||||
(default mode)
|
||||
|
@ -2875,6 +2917,14 @@ int main(int argc, char **argv) {
|
|||
134},
|
||||
{SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE.c_str(),
|
||||
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}};
|
||||
|
||||
int option_index = 0;
|
||||
|
@ -3512,6 +3562,28 @@ int main(int argc, char **argv) {
|
|||
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
||||
StringRef{optarg});
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1733,9 +1733,29 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
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:
|
||||
switch (name[40]) {
|
||||
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,
|
||||
40)) {
|
||||
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;
|
||||
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:
|
||||
LOG(WARN) << "conf: ignored";
|
||||
|
||||
|
|
|
@ -299,6 +299,14 @@ constexpr auto SHRPX_OPT_BACKEND_HTTP2_WINDOW_SIZE =
|
|||
StringRef::from_lit("backend-http2-window-size");
|
||||
constexpr auto SHRPX_OPT_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;
|
||||
|
||||
|
@ -595,9 +603,11 @@ struct Http2Config {
|
|||
nghttp2_option *option;
|
||||
nghttp2_option *alt_mode_option;
|
||||
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 connection_window_size;
|
||||
size_t max_concurrent_streams;
|
||||
bool optimize_write_buffer_size;
|
||||
bool optimize_window_size;
|
||||
} upstream;
|
||||
|
@ -607,6 +617,8 @@ struct Http2Config {
|
|||
} timeout;
|
||||
nghttp2_option *option;
|
||||
nghttp2_session_callbacks *callbacks;
|
||||
size_t encoder_dynamic_table_size;
|
||||
size_t decoder_dynamic_table_size;
|
||||
int32_t window_size;
|
||||
int32_t connection_window_size;
|
||||
size_t max_concurrent_streams;
|
||||
|
@ -795,6 +807,8 @@ enum {
|
|||
SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_BITS,
|
||||
SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
||||
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_SETTINGS_TIMEOUT,
|
||||
SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS,
|
||||
|
@ -832,8 +846,10 @@ enum {
|
|||
SHRPX_OPTID_FRONTEND_FRAME_DEBUG,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS,
|
||||
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_RESPONSE_HEADER,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_ENCODER_DYNAMIC_TABLE_SIZE,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_MAX_CONCURRENT_STREAMS,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WINDOW_SIZE,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WRITE_BUFFER_SIZE,
|
||||
|
|
|
@ -1584,7 +1584,7 @@ int Http2Session::connection_made() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
std::array<nghttp2_settings_entry, 3> entry;
|
||||
std::array<nghttp2_settings_entry, 4> entry;
|
||||
size_t nentry = 2;
|
||||
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||
entry[0].value = http2conf.downstream.max_concurrent_streams;
|
||||
|
@ -1598,6 +1598,13 @@ int Http2Session::connection_made() {
|
|||
++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(),
|
||||
nentry);
|
||||
if (rv != 0) {
|
||||
|
|
|
@ -939,7 +939,9 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
|||
flow_control_ = true;
|
||||
|
||||
// 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].value = http2conf.upstream.max_concurrent_streams;
|
||||
|
||||
|
@ -950,8 +952,15 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
|||
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(),
|
||||
entry.size());
|
||||
nentry);
|
||||
if (rv != 0) {
|
||||
ULOG(ERROR, this) << "nghttp2_submit_settings() returned error: "
|
||||
<< nghttp2_strerror(rv);
|
||||
|
|
Loading…
Reference in New Issue