diff --git a/gennghttpxfun.py b/gennghttpxfun.py index d85eb139..93ad43f8 100755 --- a/gennghttpxfun.py +++ b/gennghttpxfun.py @@ -152,6 +152,7 @@ OPTIONS = [ "dns-cache-timeout", "dns-lookup-timeout", "dns-max-try", + "frontend-keep-alive-timeout", ] LOGVARS = [ diff --git a/src/shrpx.cc b/src/shrpx.cc index 20ffbb2f..cddbeb51 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -1461,6 +1461,9 @@ void fill_default_config(Config *config) { // Write timeout for HTTP2/non-HTTP2 upstream connection timeoutconf.write = 30_s; + + // Keep alive timeout for HTTP/1 upstream connection + timeoutconf.idle_read = 1_min; } } @@ -1828,6 +1831,11 @@ Timeout: Specify write timeout for all frontend connections. Default: )" << util::duration_str(config->conn.upstream.timeout.write) << R"( + --frontend-keep-alive-timeout= + Specify keep-alive timeout for frontend HTTP/1 + connection. + Default: )" + << util::duration_str(config->conn.upstream.timeout.idle_read) << R"( --stream-read-timeout= Specify read timeout for HTTP/2 and SPDY streams. 0 means no timeout. @@ -3066,6 +3074,8 @@ int main(int argc, char **argv) { {SHRPX_OPT_DNS_CACHE_TIMEOUT.c_str(), required_argument, &flag, 143}, {SHRPX_OPT_DNS_LOOKUP_TIMEOUT.c_str(), required_argument, &flag, 144}, {SHRPX_OPT_DNS_MAX_TRY.c_str(), required_argument, &flag, 145}, + {SHRPX_OPT_FRONTEND_KEEP_ALIVE_TIMEOUT.c_str(), required_argument, + &flag, 146}, {nullptr, 0, nullptr, 0}}; int option_index = 0; @@ -3751,6 +3761,11 @@ int main(int argc, char **argv) { // --dns-max-try cmdcfgs.emplace_back(SHRPX_OPT_DNS_MAX_TRY, StringRef{optarg}); break; + case 146: + // --frontend-keep-alive-timeout + cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_KEEP_ALIVE_TIMEOUT, + StringRef{optarg}); + break; default: break; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index a963d3b6..56aeaf5f 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -1789,6 +1789,9 @@ int option_lookup_token(const char *name, size_t namelen) { if (util::strieq_l("frontend-http2-read-timeou", name, 26)) { return SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT; } + if (util::strieq_l("frontend-keep-alive-timeou", name, 26)) { + return SHRPX_OPTID_FRONTEND_KEEP_ALIVE_TIMEOUT; + } break; } break; @@ -3126,6 +3129,9 @@ int parse_config(Config *config, int optid, const StringRef &opt, config->dns.max_try = n; return 0; } + case SHRPX_OPTID_FRONTEND_KEEP_ALIVE_TIMEOUT: + return parse_duration(&config->conn.upstream.timeout.idle_read, opt, + optarg); case SHRPX_OPTID_CONF: LOG(WARN) << "conf: ignored"; diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 95c39f9c..272e7e40 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -317,6 +317,8 @@ constexpr auto SHRPX_OPT_DNS_CACHE_TIMEOUT = constexpr auto SHRPX_OPT_DNS_LOOKUP_TIMEOUT = StringRef::from_lit("dns-lookup-timeout"); constexpr auto SHRPX_OPT_DNS_MAX_TRY = StringRef::from_lit("dns-max-try"); +constexpr auto SHRPX_OPT_FRONTEND_KEEP_ALIVE_TIMEOUT = + StringRef::from_lit("frontend-keep-alive-timeout"); constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8; @@ -766,6 +768,7 @@ struct ConnectionConfig { ev_tstamp http2_read; ev_tstamp read; ev_tstamp write; + ev_tstamp idle_read; } timeout; struct { RateLimitConfig read; @@ -937,6 +940,7 @@ enum { SHRPX_OPTID_FRONTEND_HTTP2_SETTINGS_TIMEOUT, SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS, SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_SIZE, + SHRPX_OPTID_FRONTEND_KEEP_ALIVE_TIMEOUT, SHRPX_OPTID_FRONTEND_NO_TLS, SHRPX_OPTID_FRONTEND_READ_TIMEOUT, SHRPX_OPTID_FRONTEND_WRITE_TIMEOUT, diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc index a12d1a40..a7ec4778 100644 --- a/src/shrpx_https_upstream.cc +++ b/src/shrpx_https_upstream.cc @@ -76,6 +76,11 @@ int htp_msg_begin(http_parser *htp) { upstream->attach_downstream(std::move(downstream)); + auto conn = handler->get_connection(); + auto &upstreamconf = get_config()->conn.upstream; + + conn->rt.repeat = upstreamconf.timeout.read; + handler->repeat_read_timer(); return 0; @@ -672,6 +677,11 @@ int HttpsUpstream::on_write() { return 0; } + auto conn = handler_->get_connection(); + auto &upstreamconf = get_config()->conn.upstream; + + conn->rt.repeat = upstreamconf.timeout.idle_read; + handler_->repeat_read_timer(); return resume_read(SHRPX_NO_BUFFER, nullptr, 0);