Added set-timeout for frontend side of session, so it can be used to set
dynamically per-client timeouts if needed.
---
 doc/configuration.txt      | 12 ++++++------
 include/haproxy/action-t.h |  1 +
 src/action.c               |  5 ++++-
 src/http_act.c             |  5 +++++
 src/stream.c               |  4 ++++
 5 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index d49d359a2..d46765b65 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -7010,7 +7010,7 @@ http-request <action> [options...] [ { if | unless } 
<condition> ]
     - set-query <fmt>
     - set-src <expr>
     - set-src-port <expr>
-    - set-timeout { server | tunnel } { <timeout> | <expr> }
+    - set-timeout { client | server | tunnel } { <timeout> | <expr> }
     - set-tos <tos>
     - set-uri <fmt>
     - set-var(<var-name>[,<cond>...]) <expr>
@@ -7925,10 +7925,10 @@ http-request set-src-port <expr> [ { if | unless } 
<condition> ]
   the address family supports a port, otherwise it forces the source address to
   IPv4 "0.0.0.0" before rewriting the port.
 
-http-request set-timeout { server | tunnel } { <timeout> | <expr> }
+http-request set-timeout { client | server | tunnel } { <timeout> | <expr> }
                                        [ { if | unless } <condition> ]
 
-  This action overrides the specified "server" or "tunnel" timeout for the
+  This action overrides the specified "client", "server" or "tunnel" timeout 
for the
   current stream only. The timeout can be specified in millisecond or with any
   other unit if the number is suffixed by the unit as explained at the top of
   this document. It is also possible to write an expression which must returns
@@ -7936,8 +7936,8 @@ http-request set-timeout { server | tunnel } { <timeout> 
| <expr> }
 
   Note that the server/tunnel timeouts are only relevant on the backend side
   and thus this rule is only available for the proxies with backend
-  capabilities. Also the timeout value must be non-null to obtain the expected
-  results.
+  capabilities. As well as client timeout is only relevant for frontend side.
+  Also the timeout value must be non-null to obtain the expected results.
 
   Example:
     http-request set-timeout tunnel 5s
@@ -20339,7 +20339,7 @@ fe_name : string
 
 fe_client_timeout : integer
   Returns the configuration value in millisecond for the client timeout of the
-  current frontend.
+  current frontend. This timeout can be overwritten by a "set-timeout" rule.
 
 res.timer.data : integer
   this is the total transfer time of the response payload till the last byte
diff --git a/include/haproxy/action-t.h b/include/haproxy/action-t.h
index 7fafd612a..f77bdce5f 100644
--- a/include/haproxy/action-t.h
+++ b/include/haproxy/action-t.h
@@ -99,6 +99,7 @@ enum act_name {
 enum act_timeout_name {
        ACT_TIMEOUT_SERVER,
        ACT_TIMEOUT_TUNNEL,
+       ACT_TIMEOUT_CLIENT,
 };
 
 enum act_normalize_uri {
diff --git a/src/action.c b/src/action.c
index 9d3bfe4b9..b8ee4a185 100644
--- a/src/action.c
+++ b/src/action.c
@@ -195,9 +195,12 @@ int cfg_parse_rule_set_timeout(const char **args, int idx, 
int *out_timeout,
        else if (strcmp(timeout_name, "tunnel") == 0) {
                *name = ACT_TIMEOUT_TUNNEL;
        }
+       else if (strcmp(timeout_name, "client") == 0) {
+               *name = ACT_TIMEOUT_CLIENT;
+       }
        else {
                memprintf(err,
-                         "'set-timeout' rule supports 'server'/'tunnel' (got 
'%s')",
+                         "'set-timeout' rule supports 
'server'/'tunnel'/'client' (got '%s')",
                          timeout_name);
                return -1;
        }
diff --git a/src/http_act.c b/src/http_act.c
index d168cf5e0..22cccaf2c 100644
--- a/src/http_act.c
+++ b/src/http_act.c
@@ -2192,6 +2192,11 @@ static enum act_parse_ret parse_http_set_timeout(const 
char **args,
                return ACT_RET_PRS_ERR;
        }
 
+       if (!(px->cap & PR_CAP_FE)) {
+               memprintf(err, "proxy '%s' has no frontend capability", px->id);
+               return ACT_RET_PRS_ERR;
+       }
+
        if (!(px->cap & PR_CAP_BE)) {
                memprintf(err, "proxy '%s' has no backend capability", px->id);
                return ACT_RET_PRS_ERR;
diff --git a/src/stream.c b/src/stream.c
index 45b0c56d9..2c1c7aae3 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -867,6 +867,10 @@ void stream_retnclose(struct stream *s, const struct 
buffer *msg)
 int stream_set_timeout(struct stream *s, enum act_timeout_name name, int 
timeout)
 {
        switch (name) {
+       case ACT_TIMEOUT_CLIENT:
+               s->scf->ioto = timeout;
+               return 1;
+
        case ACT_TIMEOUT_SERVER:
                s->scb->ioto = timeout;
                return 1;
-- 
2.42.0


Reply via email to