From f5a2f1da255631ef496039720df724253cc6004e Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Fri, 9 Sep 2016 21:05:37 +0900 Subject: [PATCH] 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. --- gennghttpxfun.py | 4 ++ src/shrpx.cc | 80 +++++++++++++++++++++++++------------ src/shrpx_config.cc | 80 +++++++++++++++++++++++++++++++++---- src/shrpx_config.h | 20 ++++++++-- src/shrpx_http2_session.cc | 15 +++---- src/shrpx_http2_upstream.cc | 29 ++++++-------- src/shrpx_spdy_upstream.cc | 50 +++++++++++++++-------- src/shrpx_spdy_upstream.h | 1 - 8 files changed, 198 insertions(+), 81 deletions(-) diff --git a/gennghttpxfun.py b/gennghttpxfun.py index 94cf417d..fc161ad3 100755 --- a/gennghttpxfun.py +++ b/gennghttpxfun.py @@ -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 = [ diff --git a/src/shrpx.cc b/src/shrpx.cc index 2af16878..8d70f630 100644 --- a/src/shrpx.cc +++ b/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= - Sets the per-stream initial window size of HTTP/2 SPDY - frontend connection. For HTTP/2, the size is 2**-1. - For SPDY, the size is 2**. - Default: )" << get_config()->http2.upstream.window_bits << R"( - --frontend-http2-connection-window-bits= + --frontend-http2-window-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= Sets the per-connection window size of HTTP/2 and SPDY - frontend connection. For HTTP/2, the size is - 2**-1. For SPDY, the size is 2**. - 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= + --backend-http2-window-size= Sets the initial window size of HTTP/2 backend - connection to 2**-1. - Default: )" << get_config()->http2.downstream.window_bits << R"( - --backend-http2-connection-window-bits= + connection. + Default: )" << get_config()->http2.downstream.window_size << R"( + --backend-http2-connection-window-size= Sets the per-connection window size of HTTP/2 backend - connection to 2**-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= @@ -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; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index a18ab94a..f6e69e6c 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -320,6 +320,13 @@ int parse_uint_with_unit(T *dest, const StringRef &opt, return -1; } + if (std::numeric_limits::max() < n) { + LOG(ERROR) << opt + << ": too large. The value should be less than or equal to " + << std::numeric_limits::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"; diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 8aab63d7..1eeb9a36 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -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, diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc index 20c6ff1f..99179aad 100644 --- a/src/shrpx_http2_session.cc +++ b/src/shrpx_http2_session.cc @@ -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 = diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc index dcf36157..0a8d0d34 100644 --- a/src/shrpx_http2_upstream.cc +++ b/src/shrpx_http2_upstream.cc @@ -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::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(window_size), hint.rwin * 2); + auto window_size = std::min(http2conf.upstream.connection_window_size, + static_cast(hint.rwin * 2)); rv = nghttp2_session_set_local_window_size( session_, NGHTTP2_FLAG_NONE, 0, window_size); diff --git a/src/shrpx_spdy_upstream.cc b/src/shrpx_spdy_upstream.cc index efb55df7..5a007b21 100644 --- a/src/shrpx_spdy_upstream.cc +++ b/src/shrpx_spdy_upstream.cc @@ -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(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 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); } diff --git a/src/shrpx_spdy_upstream.h b/src/shrpx_spdy_upstream.h index c84d3f7e..2d6bd244 100644 --- a/src/shrpx_spdy_upstream.h +++ b/src/shrpx_spdy_upstream.h @@ -103,7 +103,6 @@ private: DownstreamQueue downstream_queue_; ClientHandler *handler_; spdylay_session *session_; - int32_t initial_window_size_; bool flow_control_; };