nghttpx: Add --frontend-http2-window-size option, and its family
We added --frontend-http2-window-size, --frontend-http2-connection-window-size, --backend-http2-window-size, and --backend-http2-connection-window-size option to replace existing *-bits options. The old options are not flexible because they only specify number of bits. Now we can specify integer value, with possible g, m, and k unit. The old options are still available for backend compatibility, but are deprecated.
This commit is contained in:
parent
27b250ac8e
commit
f5a2f1da25
|
@ -138,6 +138,10 @@ OPTIONS = [
|
|||
"no-server-rewrite",
|
||||
"frontend-http2-optimize-write-buffer-size",
|
||||
"frontend-http2-optimize-window-size",
|
||||
"frontend-http2-window-size",
|
||||
"frontend-http2-connection-window-size",
|
||||
"backend-http2-window-size",
|
||||
"backend-http2-connection-window-size",
|
||||
]
|
||||
|
||||
LOGVARS = [
|
||||
|
|
80
src/shrpx.cc
80
src/shrpx.cc
|
@ -1335,13 +1335,14 @@ void fill_default_config(Config *config) {
|
|||
timeoutconf.settings = 10_s;
|
||||
}
|
||||
|
||||
// window bits for HTTP/2 and SPDY upstream connection per
|
||||
// stream. 2**16-1 = 64KiB-1, which is HTTP/2 default. Please note
|
||||
// that SPDY/3 default is 64KiB.
|
||||
upstreamconf.window_bits = 16;
|
||||
// HTTP/2 SPDY/3.1 has connection-level flow control. The default
|
||||
// window size for HTTP/2 is 64KiB - 1. SPDY/3's default is 64KiB
|
||||
upstreamconf.connection_window_bits = 16;
|
||||
// window size for HTTP/2 and SPDY upstream connection per stream.
|
||||
// 2**16-1 = 64KiB-1, which is HTTP/2 default. Please note that
|
||||
// SPDY/3 default is 64KiB.
|
||||
upstreamconf.window_size = 64_k - 1;
|
||||
// HTTP/2 and SPDY/3.1 has connection-level flow control. The
|
||||
// default window size for HTTP/2 is 64KiB - 1. SPDY/3's default
|
||||
// is 64KiB
|
||||
upstreamconf.connection_window_size = 64_k - 1;
|
||||
upstreamconf.max_concurrent_streams = 100;
|
||||
|
||||
nghttp2_option_new(&upstreamconf.option);
|
||||
|
@ -1362,8 +1363,8 @@ void fill_default_config(Config *config) {
|
|||
timeoutconf.settings = 10_s;
|
||||
}
|
||||
|
||||
downstreamconf.window_bits = 16;
|
||||
downstreamconf.connection_window_bits = 30;
|
||||
downstreamconf.window_size = 64_k - 1;
|
||||
downstreamconf.connection_window_size = (1u << 31) - 1;
|
||||
downstreamconf.max_concurrent_streams = 100;
|
||||
|
||||
nghttp2_option_new(&downstreamconf.option);
|
||||
|
@ -1997,26 +1998,25 @@ HTTP/2 and SPDY:
|
|||
concurrent requests are set by a remote server.
|
||||
Default: )"
|
||||
<< get_config()->http2.downstream.max_concurrent_streams << R"(
|
||||
--frontend-http2-window-bits=<N>
|
||||
Sets the per-stream initial window size of HTTP/2 SPDY
|
||||
frontend connection. For HTTP/2, the size is 2**<N>-1.
|
||||
For SPDY, the size is 2**<N>.
|
||||
Default: )" << get_config()->http2.upstream.window_bits << R"(
|
||||
--frontend-http2-connection-window-bits=<N>
|
||||
--frontend-http2-window-size=<SIZE>
|
||||
Sets the per-stream initial window size of HTTP/2 and
|
||||
SPDY frontend connection.
|
||||
Default: )" << get_config()->http2.upstream.window_size << R"(
|
||||
--frontend-http2-connection-window-size=<SIZE>
|
||||
Sets the per-connection window size of HTTP/2 and SPDY
|
||||
frontend connection. For HTTP/2, the size is
|
||||
2**<N>-1. For SPDY, the size is 2**<N>.
|
||||
Default: )" << get_config()->http2.upstream.connection_window_bits
|
||||
frontend connection. For SPDY connection, the value
|
||||
less than 64KiB is rounded up to 64KiB.
|
||||
Default: )" << get_config()->http2.upstream.connection_window_size
|
||||
<< R"(
|
||||
--backend-http2-window-bits=<N>
|
||||
--backend-http2-window-size=<SIZE>
|
||||
Sets the initial window size of HTTP/2 backend
|
||||
connection to 2**<N>-1.
|
||||
Default: )" << get_config()->http2.downstream.window_bits << R"(
|
||||
--backend-http2-connection-window-bits=<N>
|
||||
connection.
|
||||
Default: )" << get_config()->http2.downstream.window_size << R"(
|
||||
--backend-http2-connection-window-size=<SIZE>
|
||||
Sets the per-connection window size of HTTP/2 backend
|
||||
connection to 2**<N>-1.
|
||||
connection.
|
||||
Default: )"
|
||||
<< get_config()->http2.downstream.connection_window_bits << R"(
|
||||
<< get_config()->http2.downstream.connection_window_size << R"(
|
||||
--http2-no-cookie-crumbling
|
||||
Don't crumble cookie header field.
|
||||
--padding=<N>
|
||||
|
@ -2048,9 +2048,9 @@ HTTP/2 and SPDY:
|
|||
automatically adjusts connection window size based on
|
||||
TCP receiving window size. The maximum window size is
|
||||
capped by the value specified by
|
||||
--frontend-http2-connection-window-bits. Since the
|
||||
--frontend-http2-connection-window-size. Since the
|
||||
stream is subject to stream level window size, it should
|
||||
be adjusted using --frontend-http2-window-bits option as
|
||||
be adjusted using --frontend-http2-window-size option as
|
||||
well. This option is only effective on recent Linux
|
||||
platform.
|
||||
|
||||
|
@ -2867,6 +2867,14 @@ int main(int argc, char **argv) {
|
|||
no_argument, &flag, 130},
|
||||
{SHRPX_OPT_FRONTEND_HTTP2_OPTIMIZE_WINDOW_SIZE.c_str(), no_argument,
|
||||
&flag, 131},
|
||||
{SHRPX_OPT_FRONTEND_HTTP2_WINDOW_SIZE.c_str(), required_argument, &flag,
|
||||
132},
|
||||
{SHRPX_OPT_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE.c_str(),
|
||||
required_argument, &flag, 133},
|
||||
{SHRPX_OPT_BACKEND_HTTP2_WINDOW_SIZE.c_str(), required_argument, &flag,
|
||||
134},
|
||||
{SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE.c_str(),
|
||||
required_argument, &flag, 135},
|
||||
{nullptr, 0, nullptr, 0}};
|
||||
|
||||
int option_index = 0;
|
||||
|
@ -3484,6 +3492,26 @@ int main(int argc, char **argv) {
|
|||
cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_HTTP2_OPTIMIZE_WINDOW_SIZE,
|
||||
StringRef::from_lit("yes"));
|
||||
break;
|
||||
case 132:
|
||||
// --frontend-http2-window-size
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_HTTP2_WINDOW_SIZE,
|
||||
StringRef{optarg});
|
||||
break;
|
||||
case 133:
|
||||
// --frontend-http2-connection-window-size
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
||||
StringRef{optarg});
|
||||
break;
|
||||
case 134:
|
||||
// --backend-http2-window-size
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_HTTP2_WINDOW_SIZE,
|
||||
StringRef{optarg});
|
||||
break;
|
||||
case 135:
|
||||
// --backend-http2-connection-window-size
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
||||
StringRef{optarg});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -320,6 +320,13 @@ int parse_uint_with_unit(T *dest, const StringRef &opt,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (std::numeric_limits<T>::max() < n) {
|
||||
LOG(ERROR) << opt
|
||||
<< ": too large. The value should be less than or equal to "
|
||||
<< std::numeric_limits<T>::max();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*dest = n;
|
||||
|
||||
return 0;
|
||||
|
@ -1482,6 +1489,11 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
break;
|
||||
case 25:
|
||||
switch (name[24]) {
|
||||
case 'e':
|
||||
if (util::strieq_l("backend-http2-window-siz", name, 24)) {
|
||||
return SHRPX_OPTID_BACKEND_HTTP2_WINDOW_SIZE;
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
if (util::strieq_l("http2-no-cookie-crumblin", name, 24)) {
|
||||
return SHRPX_OPTID_HTTP2_NO_COOKIE_CRUMBLING;
|
||||
|
@ -1499,6 +1511,11 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
break;
|
||||
case 26:
|
||||
switch (name[25]) {
|
||||
case 'e':
|
||||
if (util::strieq_l("frontend-http2-window-siz", name, 25)) {
|
||||
return SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_SIZE;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if (util::strieq_l("frontend-http2-window-bit", name, 25)) {
|
||||
return SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS;
|
||||
|
@ -1657,6 +1674,11 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
break;
|
||||
case 36:
|
||||
switch (name[35]) {
|
||||
case 'e':
|
||||
if (util::strieq_l("backend-http2-connection-window-siz", name, 35)) {
|
||||
return SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
if (util::strieq_l("backend-http2-connections-per-worke", name, 35)) {
|
||||
return SHRPX_OPTID_BACKEND_HTTP2_CONNECTIONS_PER_WORKER;
|
||||
|
@ -1675,6 +1697,9 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
case 37:
|
||||
switch (name[36]) {
|
||||
case 'e':
|
||||
if (util::strieq_l("frontend-http2-connection-window-siz", name, 36)) {
|
||||
return SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE;
|
||||
}
|
||||
if (util::strieq_l("tls-session-cache-memcached-cert-fil", name, 36)) {
|
||||
return SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_CERT_FILE;
|
||||
}
|
||||
|
@ -1964,12 +1989,16 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
optarg);
|
||||
case SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS:
|
||||
case SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS: {
|
||||
size_t *resp;
|
||||
LOG(WARN) << opt << ": deprecated. Use "
|
||||
<< (optid == SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS
|
||||
? SHRPX_OPT_FRONTEND_HTTP2_WINDOW_SIZE
|
||||
: SHRPX_OPT_BACKEND_HTTP2_WINDOW_SIZE);
|
||||
int32_t *resp;
|
||||
|
||||
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS) {
|
||||
resp = &config->http2.upstream.window_bits;
|
||||
resp = &config->http2.upstream.window_size;
|
||||
} else {
|
||||
resp = &config->http2.downstream.window_bits;
|
||||
resp = &config->http2.downstream.window_size;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
@ -1986,18 +2015,25 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
return -1;
|
||||
}
|
||||
|
||||
*resp = n;
|
||||
// Make 16 bits to the HTTP/2 default 64KiB - 1. This is the same
|
||||
// behaviour of previous code. For SPDY, we adjust this value in
|
||||
// SpdyUpstream to look like the SPDY default.
|
||||
*resp = (1 << n) - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS:
|
||||
case SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_BITS: {
|
||||
size_t *resp;
|
||||
LOG(WARN) << opt << ": deprecated. Use "
|
||||
<< (optid == SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS
|
||||
? SHRPX_OPT_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE
|
||||
: SHRPX_OPT_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE);
|
||||
int32_t *resp;
|
||||
|
||||
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS) {
|
||||
resp = &config->http2.upstream.connection_window_bits;
|
||||
resp = &config->http2.upstream.connection_window_size;
|
||||
} else {
|
||||
resp = &config->http2.downstream.connection_window_bits;
|
||||
resp = &config->http2.downstream.connection_window_size;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
@ -2014,7 +2050,7 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
return -1;
|
||||
}
|
||||
|
||||
*resp = n;
|
||||
*resp = (1 << n) - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2707,6 +2743,34 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
case SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WINDOW_SIZE:
|
||||
config->http2.upstream.optimize_window_size = util::strieq_l("yes", optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_SIZE:
|
||||
if (parse_uint_with_unit(&config->http2.upstream.window_size, opt,
|
||||
optarg) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE:
|
||||
if (parse_uint_with_unit(&config->http2.upstream.connection_window_size,
|
||||
opt, optarg) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_BACKEND_HTTP2_WINDOW_SIZE:
|
||||
if (parse_uint_with_unit(&config->http2.downstream.window_size, opt,
|
||||
optarg) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE:
|
||||
if (parse_uint_with_unit(&config->http2.downstream.connection_window_size,
|
||||
opt, optarg) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_CONF:
|
||||
LOG(WARN) << "conf: ignored";
|
||||
|
|
|
@ -291,6 +291,14 @@ constexpr auto SHRPX_OPT_FRONTEND_HTTP2_OPTIMIZE_WRITE_BUFFER_SIZE =
|
|||
StringRef::from_lit("frontend-http2-optimize-write-buffer-size");
|
||||
constexpr auto SHRPX_OPT_FRONTEND_HTTP2_OPTIMIZE_WINDOW_SIZE =
|
||||
StringRef::from_lit("frontend-http2-optimize-window-size");
|
||||
constexpr auto SHRPX_OPT_FRONTEND_HTTP2_WINDOW_SIZE =
|
||||
StringRef::from_lit("frontend-http2-window-size");
|
||||
constexpr auto SHRPX_OPT_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE =
|
||||
StringRef::from_lit("frontend-http2-connection-window-size");
|
||||
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 size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
||||
|
||||
|
@ -587,8 +595,8 @@ struct Http2Config {
|
|||
nghttp2_option *option;
|
||||
nghttp2_option *alt_mode_option;
|
||||
nghttp2_session_callbacks *callbacks;
|
||||
size_t window_bits;
|
||||
size_t connection_window_bits;
|
||||
int32_t window_size;
|
||||
int32_t connection_window_size;
|
||||
size_t max_concurrent_streams;
|
||||
bool optimize_write_buffer_size;
|
||||
bool optimize_window_size;
|
||||
|
@ -599,8 +607,8 @@ struct Http2Config {
|
|||
} timeout;
|
||||
nghttp2_option *option;
|
||||
nghttp2_session_callbacks *callbacks;
|
||||
size_t window_bits;
|
||||
size_t connection_window_bits;
|
||||
int32_t window_size;
|
||||
int32_t connection_window_size;
|
||||
size_t max_concurrent_streams;
|
||||
} downstream;
|
||||
struct {
|
||||
|
@ -785,10 +793,12 @@ enum {
|
|||
SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_HOST,
|
||||
SHRPX_OPTID_BACKEND_HTTP1_TLS,
|
||||
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_MAX_CONCURRENT_STREAMS,
|
||||
SHRPX_OPTID_BACKEND_HTTP2_SETTINGS_TIMEOUT,
|
||||
SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS,
|
||||
SHRPX_OPTID_BACKEND_HTTP2_WINDOW_SIZE,
|
||||
SHRPX_OPTID_BACKEND_IPV4,
|
||||
SHRPX_OPTID_BACKEND_IPV6,
|
||||
SHRPX_OPTID_BACKEND_KEEP_ALIVE_TIMEOUT,
|
||||
|
@ -821,6 +831,7 @@ enum {
|
|||
SHRPX_OPTID_FRONTEND,
|
||||
SHRPX_OPTID_FRONTEND_FRAME_DEBUG,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_MAX_CONCURRENT_STREAMS,
|
||||
|
@ -829,6 +840,7 @@ enum {
|
|||
SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_SETTINGS_TIMEOUT,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_SIZE,
|
||||
SHRPX_OPTID_FRONTEND_NO_TLS,
|
||||
SHRPX_OPTID_FRONTEND_READ_TIMEOUT,
|
||||
SHRPX_OPTID_FRONTEND_WRITE_TIMEOUT,
|
||||
|
|
|
@ -1590,7 +1590,7 @@ int Http2Session::connection_made() {
|
|||
entry[0].value = http2conf.downstream.max_concurrent_streams;
|
||||
|
||||
entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||
entry[1].value = (1 << http2conf.downstream.window_bits) - 1;
|
||||
entry[1].value = http2conf.downstream.window_size;
|
||||
|
||||
if (http2conf.no_server_push || get_config()->http2_proxy) {
|
||||
entry[nentry].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
|
||||
|
@ -1604,14 +1604,11 @@ int Http2Session::connection_made() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (http2conf.downstream.connection_window_bits != 16) {
|
||||
int32_t window_size =
|
||||
(1 << http2conf.downstream.connection_window_bits) - 1;
|
||||
rv = nghttp2_session_set_local_window_size(session_, NGHTTP2_FLAG_NONE, 0,
|
||||
window_size);
|
||||
if (rv != 0) {
|
||||
return -1;
|
||||
}
|
||||
rv = nghttp2_session_set_local_window_size(
|
||||
session_, NGHTTP2_FLAG_NONE, 0,
|
||||
http2conf.downstream.connection_window_size);
|
||||
if (rv != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto must_terminate =
|
||||
|
|
|
@ -947,7 +947,7 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
|||
if (faddr->alt_mode) {
|
||||
entry[1].value = (1u << 31) - 1;
|
||||
} else {
|
||||
entry[1].value = (1 << http2conf.upstream.window_bits) - 1;
|
||||
entry[1].value = http2conf.upstream.window_size;
|
||||
}
|
||||
|
||||
rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
|
||||
|
@ -957,20 +957,17 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
|||
<< nghttp2_strerror(rv);
|
||||
}
|
||||
|
||||
int32_t window_bits =
|
||||
faddr->alt_mode ? 31 : http2conf.upstream.optimize_window_size
|
||||
? 16
|
||||
: http2conf.upstream.connection_window_bits;
|
||||
auto window_size = faddr->alt_mode
|
||||
? std::numeric_limits<int32_t>::max()
|
||||
: http2conf.upstream.connection_window_size;
|
||||
|
||||
if (window_bits != 16) {
|
||||
int32_t window_size = (1u << window_bits) - 1;
|
||||
rv = nghttp2_session_set_local_window_size(session_, NGHTTP2_FLAG_NONE, 0,
|
||||
window_size);
|
||||
rv = nghttp2_session_set_local_window_size(session_, NGHTTP2_FLAG_NONE, 0,
|
||||
window_size);
|
||||
|
||||
if (rv != 0) {
|
||||
ULOG(ERROR, this) << "nghttp2_submit_window_update() returned error: "
|
||||
<< nghttp2_strerror(rv);
|
||||
}
|
||||
if (rv != 0) {
|
||||
ULOG(ERROR, this)
|
||||
<< "nghttp2_session_set_local_window_size() returned error: "
|
||||
<< nghttp2_strerror(rv);
|
||||
}
|
||||
|
||||
// We wait for SETTINGS ACK at least 10 seconds.
|
||||
|
@ -1073,10 +1070,8 @@ int Http2Upstream::on_write() {
|
|||
if (http2conf.upstream.optimize_window_size) {
|
||||
auto faddr = handler_->get_upstream_addr();
|
||||
if (!faddr->alt_mode) {
|
||||
int32_t window_size =
|
||||
(1u << http2conf.upstream.connection_window_bits) - 1;
|
||||
window_size =
|
||||
std::min(static_cast<uint32_t>(window_size), hint.rwin * 2);
|
||||
auto window_size = std::min(http2conf.upstream.connection_window_size,
|
||||
static_cast<int32_t>(hint.rwin * 2));
|
||||
|
||||
rv = nghttp2_session_set_local_window_size(
|
||||
session_, NGHTTP2_FLAG_NONE, 0, window_size);
|
||||
|
|
|
@ -53,6 +53,28 @@ namespace {
|
|||
constexpr size_t MAX_BUFFER_SIZE = 32_k;
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
int32_t get_connection_window_size() {
|
||||
return std::max(get_config()->http2.upstream.connection_window_size,
|
||||
static_cast<int32_t>(64_k));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
int32_t get_window_size() {
|
||||
auto n = get_config()->http2.upstream.window_size;
|
||||
|
||||
// 65535 is the default window size of HTTP/2. OTOH, the default
|
||||
// window size of SPDY is 65536. The configuration defaults to
|
||||
// HTTP/2, so if we have 65535, we use 65536 for SPDY.
|
||||
if (n == 65535) {
|
||||
return 64_k;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
ssize_t send_callback(spdylay_session *session, const uint8_t *data, size_t len,
|
||||
int flags, void *user_data) {
|
||||
|
@ -402,33 +424,27 @@ void on_data_chunk_recv_callback(spdylay_session *session, uint8_t flags,
|
|||
return;
|
||||
}
|
||||
|
||||
auto &http2conf = get_config()->http2;
|
||||
|
||||
// If connection-level window control is not enabled (e.g,
|
||||
// spdy/3), spdylay_session_get_recv_data_length() is always
|
||||
// returns 0.
|
||||
if (spdylay_session_get_recv_data_length(session) >
|
||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
||||
1 << http2conf.upstream.connection_window_bits)) {
|
||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE, get_connection_window_size())) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream) << "Flow control error on connection: "
|
||||
<< "recv_window_size="
|
||||
<< spdylay_session_get_recv_data_length(session)
|
||||
<< ", window_size="
|
||||
<< (1 << http2conf.upstream.connection_window_bits);
|
||||
<< ", window_size=" << get_connection_window_size();
|
||||
}
|
||||
spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
return;
|
||||
}
|
||||
if (spdylay_session_get_stream_recv_data_length(session, stream_id) >
|
||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
||||
1 << http2conf.upstream.window_bits)) {
|
||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE, get_window_size())) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream) << "Flow control error: recv_window_size="
|
||||
<< spdylay_session_get_stream_recv_data_length(
|
||||
session, stream_id)
|
||||
<< ", initial_window_size="
|
||||
<< (1 << http2conf.upstream.window_bits);
|
||||
<< ", initial_window_size=" << get_window_size();
|
||||
}
|
||||
upstream->rst_stream(downstream, SPDYLAY_FLOW_CONTROL_ERROR);
|
||||
return;
|
||||
|
@ -574,16 +590,17 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
|||
// going to be deprecated in the future, and the default stream
|
||||
// window is large enough for API request body (64KiB), we don't
|
||||
// expand window size depending on the options.
|
||||
int32_t initial_window_size;
|
||||
if (version >= SPDYLAY_PROTO_SPDY3 && !faddr->alt_mode) {
|
||||
int val = 1;
|
||||
flow_control_ = true;
|
||||
initial_window_size_ = 1 << http2conf.upstream.window_bits;
|
||||
initial_window_size = get_window_size();
|
||||
rv = spdylay_session_set_option(
|
||||
session_, SPDYLAY_OPT_NO_AUTO_WINDOW_UPDATE2, &val, sizeof(val));
|
||||
assert(rv == 0);
|
||||
} else {
|
||||
flow_control_ = false;
|
||||
initial_window_size_ = 0;
|
||||
initial_window_size = 0;
|
||||
}
|
||||
// TODO Maybe call from outside?
|
||||
std::array<spdylay_settings_entry, 2> entry;
|
||||
|
@ -595,7 +612,7 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
|||
if (flow_control_) {
|
||||
++num_entry;
|
||||
entry[1].settings_id = SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||
entry[1].value = initial_window_size_;
|
||||
entry[1].value = initial_window_size;
|
||||
entry[1].flags = SPDYLAY_ID_FLAG_SETTINGS_NONE;
|
||||
}
|
||||
|
||||
|
@ -603,10 +620,11 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
|||
entry.data(), num_entry);
|
||||
assert(rv == 0);
|
||||
|
||||
auto connection_window_size = get_connection_window_size();
|
||||
|
||||
if (flow_control_ && version >= SPDYLAY_PROTO_SPDY3_1 &&
|
||||
http2conf.upstream.connection_window_bits > 16) {
|
||||
int32_t delta = (1 << http2conf.upstream.connection_window_bits) -
|
||||
SPDYLAY_INITIAL_WINDOW_SIZE;
|
||||
connection_window_size > 64_k) {
|
||||
int32_t delta = connection_window_size - SPDYLAY_INITIAL_WINDOW_SIZE;
|
||||
rv = spdylay_submit_window_update(session_, 0, delta);
|
||||
assert(rv == 0);
|
||||
}
|
||||
|
|
|
@ -103,7 +103,6 @@ private:
|
|||
DownstreamQueue downstream_queue_;
|
||||
ClientHandler *handler_;
|
||||
spdylay_session *session_;
|
||||
int32_t initial_window_size_;
|
||||
bool flow_control_;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue