]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] http: add a separate "http-keep-alive" timeout
authorWilly Tarreau <w@1wt.eu>
Sun, 10 Jan 2010 13:46:16 +0000 (14:46 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 10 Jan 2010 13:46:16 +0000 (14:46 +0100)
This one is used to wait for next request after a response was sent
to the client.

doc/configuration.txt
include/types/proxy.h
src/cfgparse.c
src/proto_http.c
src/proxy.c

index 528b991e03331ffc692ce5549e12466150030bfc..c5dd1054becc7abfe4ddf742c405ccb0a6b1fca3 100644 (file)
@@ -835,6 +835,7 @@ timeout client              X          X         X         -
 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 @@ no option http-server-close
   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 contimeout <timeout> (deprecated)
             "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 @@ timeout http-request <timeout>
 
   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 @@ timeout http-request <timeout>
   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>
index 78449e7ea6a8e766b399bbb53b4cc0114a6d8b23..2ba298b8eed5191907da60b3f85ca763a457e5f6 100644 (file)
@@ -201,6 +201,7 @@ struct proxy {
                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 */
index 58505ec27f95c6e0e0248a413a22e6ed009062ec..13e1cfdf8e6ef518258cfd0eb67c16fbccb63262 100644 (file)
@@ -1006,6 +1006,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                        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 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                        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;
                }
 
index 582b562846a0a0e290f65e95ac5881903d83b019..d62ac73fa17db08bc871d3995e8f7041248b8251 100644 (file)
@@ -2309,11 +2309,18 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
                         * 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 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
         * 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.
         */
index 38eb2be899db764c5f1fa5a66874dd8e9b785d8a..5c5251f0b360949f7f2375bccb89731aaaeb2142 100644 (file)
@@ -153,6 +153,10 @@ static int proxy_parse_timeout(char **args, int section, struct proxy *proxy,
                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 @@ static int proxy_parse_timeout(char **args, int section, struct proxy *proxy,
        } 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;
        }