]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: httpclient: allow to configure the timeout.connect
authorWilliam Lallemand <wlallemand@haproxy.org>
Tue, 5 Sep 2023 14:42:27 +0000 (16:42 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Tue, 5 Sep 2023 14:42:27 +0000 (16:42 +0200)
When using the httpclient, one could be bothered with it returning
after a very long time when failing. By default the httpclient has a
retries of 3 and a timeout connect of 5s, which can results in pause of
20s upon failure.

This patch allows the user to configure the "timeout connect" of the
httpclient so it could reduce the time to return an error.

This patch helps fixing part of the issue #2269.

Could be backported in 2.7 if needed.

doc/configuration.txt
src/http_client.c

index 982bc6ae52dd12943c2787d4bd503291d371b990..bbec0aa8929191b21dd1f1839e6e43844cb22f69 100644 (file)
@@ -1091,6 +1091,7 @@ The following keywords are supported in the "global" section :
    - httpclient.retries
    - httpclient.ssl.ca-file
    - httpclient.ssl.verify
+   - httpclient.timeout.connect
    - insecure-fork-wanted
    - insecure-setuid-wanted
    - issuers-chain-path
@@ -1759,6 +1760,18 @@ httpclient.ssl.verify [none|required]
   However, when this option is explicitly enabled it will trigger a
   configuration error if it fails.
 
+httpclient.timeout.connect <timeout>
+  Set the maximum time to wait for a connection attempt by default for the
+  httpclient.
+
+  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.
+
+  The default value is 5000ms.
+
+
 insecure-fork-wanted
   By default HAProxy tries hard to prevent any thread and process creation
   after it starts. Doing so is particularly important when using Lua files of
index cc9a1b0126415b30df2291712e8eda88f73df764..21fdb80b2da77e402e502f1bd940d0b0c47a236f 100644 (file)
@@ -56,6 +56,7 @@ static char *resolvers_prefer = NULL;
 static int resolvers_disabled = 0;
 
 static int httpclient_retries = CONN_RETRIES;
+static int httpclient_timeout_connect = MS_TO_TICKS(5000);
 
 /* --- This part of the file implement an HTTP client over the CLI ---
  * The functions will be  starting by "hc_cli" for "httpclient cli"
@@ -1221,6 +1222,7 @@ struct proxy *httpclient_create_proxy(const char *id)
        px->maxconn = 0;
        px->accept = NULL;
        px->conn_retries = httpclient_retries;
+       px->timeout.connect = httpclient_timeout_connect;
        px->timeout.client = TICK_ETERNITY;
        /* The HTTP Client use the "option httplog" with the global log server */
        px->conf.logformat_string = httpclient_log_format;
@@ -1548,12 +1550,55 @@ static int httpclient_parse_global_retries(char **args, int section_type, struct
        return 0;
 }
 
+static int httpclient_parse_global_timeout_connect(char **args, int section_type, struct proxy *curpx,
+                                        const struct proxy *defpx, const char *file, int line,
+                                        char **err)
+{
+       const char *res;
+       unsigned timeout;
+
+       if (too_many_args(1, args, err, NULL))
+               return -1;
+
+       if (*(args[1]) == 0) {
+               ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n",
+                        file, line, args[0]);
+               return -1;
+       }
+
+       res = parse_time_err(args[1], &timeout, TIME_UNIT_MS);
+       if (res == PARSE_TIME_OVER) {
+               memprintf(err, "timer overflow in argument '%s' to '%s' (maximum value is 2147483647 ms or ~24.8 days)",
+                         args[1], args[0]);
+               return -1;
+       }
+       else if (res == PARSE_TIME_UNDER) {
+               memprintf(err, "timer underflow in argument '%s' to '%s' (minimum non-null value is 1 ms)",
+                         args[1], args[0]);
+               return -1;
+       }
+       else if (res) {
+               memprintf(err, "unexpected character '%c' in '%s'", *res, args[0]);
+               return -1;
+       }
+
+       if (*args[2] != 0) {
+               memprintf(err, "'%s' : unexpected extra argument '%s' after value '%s'.", args[0], args[2], args[1]);
+               return -1;
+       }
+
+       httpclient_timeout_connect = MS_TO_TICKS(timeout);
+
+       return 0;
+}
+
 
 static struct cfg_kw_list cfg_kws = {ILH, {
        { CFG_GLOBAL, "httpclient.resolvers.disabled", httpclient_parse_global_resolvers_disabled },
        { CFG_GLOBAL, "httpclient.resolvers.id", httpclient_parse_global_resolvers },
        { CFG_GLOBAL, "httpclient.resolvers.prefer", httpclient_parse_global_prefer },
        { CFG_GLOBAL, "httpclient.retries", httpclient_parse_global_retries },
+       { CFG_GLOBAL, "httpclient.timeout.connect", httpclient_parse_global_timeout_connect },
 #ifdef USE_OPENSSL
        { CFG_GLOBAL, "httpclient.ssl.verify", httpclient_parse_global_verify },
        { CFG_GLOBAL, "httpclient.ssl.ca-file", httpclient_parse_global_ca_file },