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:
Tatsuhiro Tsujikawa 2016-09-09 21:05:37 +09:00
parent 27b250ac8e
commit f5a2f1da25
8 changed files with 198 additions and 81 deletions

View File

@ -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 = [

View File

@ -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;
}

View File

@ -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";

View File

@ -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,

View File

@ -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,15 +1604,12 @@ 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);
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 =
addr_->tls && !nghttp2::ssl::check_http2_requirement(conn_.tls.ssl);

View File

@ -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,21 +957,18 @@ 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);
if (rv != 0) {
ULOG(ERROR, this) << "nghttp2_submit_window_update() returned error: "
ULOG(ERROR, this)
<< "nghttp2_session_set_local_window_size() returned error: "
<< nghttp2_strerror(rv);
}
}
// We wait for SETTINGS ACK at least 10 seconds.
ev_timer_init(&settings_timer_, settings_timeout_cb,
@ -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);

View File

@ -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);
}

View File

@ -103,7 +103,6 @@ private:
DownstreamQueue downstream_queue_;
ClientHandler *handler_;
spdylay_session *session_;
int32_t initial_window_size_;
bool flow_control_;
};