[MINOR] http: add a separate "http-keep-alive" timeout
This one is used to wait for next request after a response was sent
to the client.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 528b991..c5dd105 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -835,6 +835,7 @@
timeout clitimeout X X X - (deprecated)
timeout connect X - X X
timeout contimeout X - X X (deprecated)
+timeout http-keep-alive X X X X
timeout http-request X X X X
timeout queue X - X X
timeout server X - X X
@@ -2548,7 +2549,8 @@
session or not. The accept date reported in the logs corresponds to the end
of the previous request, and the request time corresponds to the time spent
waiting for a new request. The keep-alive request time is still bound to the
- timeout defined by "timeout http-request".
+ timeout defined by "timeout http-keep-alive" or "timeout http-request" if
+ not set.
This option may be set both in a frontend and in a backend. It is enabled if
at least one of the frontend or backend holding a connection has it enabled.
@@ -4537,6 +4539,47 @@
"timeout tarpit".
+timeout http-keep-alive <timeout>
+ Set the maximum allowed time to wait for a new HTTP request to appear
+ May be used in sections : defaults | frontend | listen | backend
+ yes | yes | yes | yes
+ Arguments :
+ <timeout> is the timeout value specified in milliseconds by default, but
+ can be in any other unit if the number is suffixed by the unit,
+ as explained at the top of this document.
+
+ By default, the time to wait for a new request in case of keep-alive is set
+ by "timeout http-request". However this is not always convenient because some
+ people want very short keep-alive timeouts in order to release connections
+ faster, and others prefer to have larger ones but still have short timeouts
+ once the request has started to present itself.
+
+ The "http-keep-alive" timeout covers these needs. It will define how long to
+ wait for a new HTTP request to start coming after a response was sent. Once
+ the first byte of request has been seen, the "http-request" timeout is used
+ to wait for the complete request to come. Note that empty lines prior to a
+ new request do not refresh the timeout and are not counted as a new request.
+
+ There is also another difference between the two timeouts : when a connection
+ expires during timeout http-keep-alive, no error is returned, the connection
+ just closes. If the connection expires in "http-request" while waiting for a
+ connection to complete, a HTTP 408 error is returned.
+
+ In general it is optimal to set this value to a few tens to hundreds of
+ milliseconds, to allow users to fetch all objects of a page at once but
+ without waiting for further clicks. Also, if set to a very small value (eg:
+ 1 millisecond) it will probably only accept pipelined requests but not the
+ non-pipelined ones. It may be a nice trade-off for very large sites running
+ with tends to hundreds of thousands of clients.
+
+ If this parameter is not set, the "http-request" timeout applies, and if both
+ are not set, "timeout client" still applies at the lower level. It should be
+ set in the frontend to take effect, unless the frontend is in TCP mode, in
+ which case the HTTP backend's timeout will be used.
+
+ See also : "timeout http-request", "timeout client".
+
+
timeout http-request <timeout>
Set the maximum allowed time to wait for a complete HTTP request
May be used in sections : defaults | frontend | listen | backend
@@ -4557,7 +4600,8 @@
Note that this timeout only applies to the header part of the request, and
not to any data. As soon as the empty line is received, this timeout is not
- used anymore.
+ used anymore. It is used again on keep-alive connections to wait for a second
+ request if "timeout http-keep-alive" is not set.
Generally it is enough to set it to a few seconds, as most clients send the
full request immediately upon connection. Add 3 or more seconds to cover TCP
@@ -4570,7 +4614,7 @@
effect, unless the frontend is in TCP mode, in which case the HTTP backend's
timeout will be used.
- See also : "timeout client".
+ See also : "timeout http-keep-alive", "timeout client".
timeout queue <timeout>
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 78449e7..2ba298b 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -201,6 +201,7 @@
int server; /* server I/O timeout (in ticks) */
int appsession; /* appsession cookie expiration */
int httpreq; /* maximum time for complete HTTP request */
+ int httpka; /* maximum time for a new HTTP request when using keep-alive */
int check; /* maximum time for complete check */
} timeout;
char *id, *desc; /* proxy id (name) and description */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 58505ec..13e1cfd 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1006,6 +1006,7 @@
curproxy->timeout.client = defproxy.timeout.client;
curproxy->timeout.tarpit = defproxy.timeout.tarpit;
curproxy->timeout.httpreq = defproxy.timeout.httpreq;
+ curproxy->timeout.httpka = defproxy.timeout.httpka;
curproxy->uri_auth = defproxy.uri_auth;
curproxy->mon_net = defproxy.mon_net;
curproxy->mon_mask = defproxy.mon_mask;
@@ -1023,6 +1024,7 @@
curproxy->timeout.queue = defproxy.timeout.queue;
curproxy->timeout.tarpit = defproxy.timeout.tarpit;
curproxy->timeout.httpreq = defproxy.timeout.httpreq;
+ curproxy->timeout.httpka = defproxy.timeout.httpka;
curproxy->source_addr = defproxy.source_addr;
}
diff --git a/src/proto_http.c b/src/proto_http.c
index 582b562..d62ac73 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -2309,11 +2309,18 @@
* request timeout processing.
*/
txn->flags &= ~TX_WAIT_NEXT_RQ;
+ req->analyse_exp = TICK_ETERNITY;
}
/* just set the request timeout once at the beginning of the request */
- if (!tick_isset(req->analyse_exp))
- req->analyse_exp = tick_add_ifset(now_ms, s->be->timeout.httpreq);
+ if (!tick_isset(req->analyse_exp)) {
+ if ((msg->msg_state == HTTP_MSG_RQBEFORE) &&
+ (txn->flags & TX_WAIT_NEXT_RQ) &&
+ tick_isset(s->be->timeout.httpka))
+ req->analyse_exp = tick_add(now_ms, s->be->timeout.httpka);
+ else
+ req->analyse_exp = tick_add_ifset(now_ms, s->be->timeout.httpreq);
+ }
/* we're not ready yet */
return 0;
@@ -2342,6 +2349,13 @@
* left uninitialized (for instance in the absence of headers).
*/
+ if (txn->flags & TX_WAIT_NEXT_RQ) {
+ /* kill the pending keep-alive timeout */
+ txn->flags &= ~TX_WAIT_NEXT_RQ;
+ req->analyse_exp = TICK_ETERNITY;
+ }
+
+
/* Maybe we found in invalid header name while we were configured not
* to block on that, so we have to capture it now.
*/
diff --git a/src/proxy.c b/src/proxy.c
index 38eb2be..5c5251f 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -153,6 +153,10 @@
tv = &proxy->timeout.tarpit;
td = &defpx->timeout.tarpit;
cap = PR_CAP_FE | PR_CAP_BE;
+ } else if (!strcmp(args[0], "http-keep-alive")) {
+ tv = &proxy->timeout.httpka;
+ td = &defpx->timeout.httpka;
+ cap = PR_CAP_FE | PR_CAP_BE;
} else if (!strcmp(args[0], "http-request")) {
tv = &proxy->timeout.httpreq;
td = &defpx->timeout.httpreq;
@@ -182,7 +186,7 @@
} else {
snprintf(err, errlen,
"timeout '%s': must be 'client', 'server', 'connect', 'check', "
- "'appsession', 'queue', 'http-request' or 'tarpit'",
+ "'appsession', 'queue', 'http-keep-alive', 'http-request' or 'tarpit'",
args[0]);
return -1;
}