[PATCH] MINOR: support for http-response set-timeout

2023-10-16 Thread Vladimir Vdovin
Added set-timeout action for http-response. Adapted reg-tests and
documentation.
---
 doc/configuration.txt  | 19 +
 reg-tests/http-set-timeout/set_timeout.vtc | 90 +-
 src/http_act.c |  1 +
 3 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 0b74ae291..88a576795 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -8087,6 +8087,7 @@ http-response   [ { if | unless } 
 ]
 - set-mark 
 - set-nice 
 - set-status  [reason ]
+- set-timeout { client | server | tunnel } {  |  }
 - set-tos 
 - set-var([,...]) 
 - set-var-fmt([,...]) 
@@ -8332,6 +8333,24 @@ http-response set-status  [reason ]
 # return "503 Slow Down", custom reason
 http-response set-status 503 reason "Slow Down".
 
+http-response set-timeout { client | server | tunnel } {  |  }
+   [ { if | unless }  ]
+
+  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
+  a number interpreted as a timeout in millisecond.
+
+  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. 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-response set-timeout tunnel 5s
+http-response set-timeout server res.hdr(X-Refresh-Seconds),mul(1000)
+
 http-response set-tos  [ { if | unless }  ]
 
   This is used to set the TOS or DSCP field value of packets sent to the client
diff --git a/reg-tests/http-set-timeout/set_timeout.vtc 
b/reg-tests/http-set-timeout/set_timeout.vtc
index 6fa0a35f1..a112bc51e 100644
--- a/reg-tests/http-set-timeout/set_timeout.vtc
+++ b/reg-tests/http-set-timeout/set_timeout.vtc
@@ -4,7 +4,7 @@ feature ignore_unknown_macro
 
 #REQUIRE_VERSION=2.4
 
-server srv_h1 -repeat 5 {
+server srv_h1 -repeat 9 {
 rxreq
 txresp
 } -start
@@ -34,6 +34,26 @@ syslog Slog5 -level info {
 expect ~ "^.*timeout: 5000 3000.*$"
 } -start
 
+syslog Slog6 -level info {
+recv
+expect ~ "^.*timeout: 5000 5000.*$"
+} -start
+
+syslog Slog7 -level info {
+recv
+expect ~ "^.*timeout: 5000 5000.*$"
+} -start
+
+syslog Slog8 -level info {
+recv
+expect ~ "^.*timeout: 5000 3000.*$"
+} -start
+
+syslog Slog9 -level info {
+recv
+expect ~ "^.*timeout: 5000 3000.*$"
+} -start
+
 haproxy hap -conf {
 defaults
 timeout connect 5s
@@ -87,6 +107,46 @@ haproxy hap -conf {
 backend be2
mode http
server srv_h1 ${srv_h1_addr}:${srv_h1_port}
+
+listen li4
+mode http
+bind "fd@${li4}"
+log-format "timeout: %[be_server_timeout] %[cur_server_timeout]"
+log ${Slog6_addr}:${Slog6_port} len 2048 local0 debug err
+http-response set-timeout server 5s
+   server srv_h1 ${srv_h1_addr}:${srv_h1_port}
+
+listen li5
+mode http
+bind "fd@${li5}"
+log-format "timeout: %[fe_client_timeout] %[cur_client_timeout]"
+log ${Slog7_addr}:${Slog7_port} len 2048 local0 debug err
+http-response set-timeout client 5s
+   server srv_h1 ${srv_h1_addr}:${srv_h1_port}
+
+frontend fe3
+mode http
+bind "fd@${fe3}"
+log-format "timeout: %[be_server_timeout] %[cur_server_timeout]"
+log ${Slog8_addr}:${Slog8_port} len 2048 local0 debug err
+default_backend be1
+
+backend be3
+   mode http
+   http-response set-timeout server int(3),mul(1000)
+   server srv_h1 ${srv_h1_addr}:${srv_h1_port}
+
+frontend fe4
+mode http
+bind "fd@${fe4}"
+log-format "timeout: %[fe_client_timeout] %[cur_client_timeout]"
+log ${Slog9_addr}:${Slog9_port} len 2048 local0 debug err
+http-response set-timeout client int(3),mul(1000)
+default_backend be2
+
+backend be4
+   mode http
+   server srv_h1 ${srv_h1_addr}:${srv_h1_port}
 } -start
 
 client c1 -connect ${hap_li1_sock} {
@@ -119,8 +179,36 @@ client c5 -connect ${hap_fe2_sock} {
 expect resp.status == 200
 } -run
 
+client c6 -connect ${hap_li4_sock} {
+txreq
+rxresp
+expect resp.status == 200
+} -run
+
+client c7 -connect ${hap_fe3_sock} {
+txreq
+rxresp
+expect resp.status == 200
+} -run
+
+client c8 -connect ${hap_li5_sock} {
+txreq
+rxresp
+expect resp.status == 200
+} -run
+
+client c9 -connect ${hap_fe4_sock} {
+txreq
+rxresp
+expect resp.status == 200
+} -run
+
 syslog Slog1 -wait
 syslog Slog2 -wait
 syslog Slog3 -wait
 syslog Slog4 -wait
 syslog Sl

[PATCH] MINOR: support for http-response set-timeout

2023-10-14 Thread Vladimir Vdovin
Added set-timeout action for http-response. Adapted reg-tests and
documentation.
---
 doc/configuration.txt  | 19 +
 reg-tests/http-set-timeout/set_timeout.vtc | 90 +-
 src/http_act.c |  1 +
 3 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 0b74ae291..1de71fdec 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -8087,6 +8087,7 @@ http-response   [ { if | unless } 
 ]
 - set-mark 
 - set-nice 
 - set-status  [reason ]
+- set-timeout { client | server | tunnel } {  |  }
 - set-tos 
 - set-var([,...]) 
 - set-var-fmt([,...]) 
@@ -8332,6 +8333,24 @@ http-response set-status  [reason ]
 # return "503 Slow Down", custom reason
 http-response set-status 503 reason "Slow Down".
 
+http-response set-timeout { client | server | tunnel } {  |  }
+   [ { if | unless }  ]
+
+  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
+  a number interpreted as a timeout in millisecond.
+
+  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. 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-response set-timeout tunnel 5s
+http-response set-timeout server req.hdr(host),map_int(host.lst)
+
 http-response set-tos  [ { if | unless }  ]
 
   This is used to set the TOS or DSCP field value of packets sent to the client
diff --git a/reg-tests/http-set-timeout/set_timeout.vtc 
b/reg-tests/http-set-timeout/set_timeout.vtc
index 6fa0a35f1..2d8b63ee4 100644
--- a/reg-tests/http-set-timeout/set_timeout.vtc
+++ b/reg-tests/http-set-timeout/set_timeout.vtc
@@ -4,7 +4,7 @@ feature ignore_unknown_macro
 
 #REQUIRE_VERSION=2.4
 
-server srv_h1 -repeat 5 {
+server srv_h1 -repeat 9 {
 rxreq
 txresp
 } -start
@@ -34,6 +34,26 @@ syslog Slog5 -level info {
 expect ~ "^.*timeout: 5000 3000.*$"
 } -start
 
+syslog Slog6 -level info {
+recv
+expect ~ "^.*timeout: 5000 5000.*$"
+} -start
+
+syslog Slog7 -level info {
+recv
+expect ~ "^.*timeout: 5000 5000.*$"
+} -start
+
+syslog Slog8 -level info {
+recv
+expect ~ "^.*timeout: 5000 3000.*$"
+} -start
+
+syslog Slog9 -level info {
+recv
+expect ~ "^.*timeout: 5000 3000.*$"
+} -start
+
 haproxy hap -conf {
 defaults
 timeout connect 5s
@@ -87,6 +107,46 @@ haproxy hap -conf {
 backend be2
mode http
server srv_h1 ${srv_h1_addr}:${srv_h1_port}
+
+listen li4
+mode http
+bind "fd@${li4}"
+log-format "timeout: %[be_server_timeout] %[cur_server_timeout]"
+log ${Slog6_addr}:${Slog6_port} len 2048 local0 debug err
+http-response set-timeout server 5s
+   server srv_h1 ${srv_h1_addr}:${srv_h1_port}
+
+listen li5
+mode http
+bind "fd@${li5}"
+log-format "timeout: %[fe_client_timeout] %[cur_client_timeout]"
+log ${Slog7_addr}:${Slog7_port} len 2048 local0 debug err
+http-response set-timeout client 5s
+   server srv_h1 ${srv_h1_addr}:${srv_h1_port}
+
+frontend fe3
+mode http
+bind "fd@${fe3}"
+log-format "timeout: %[be_server_timeout] %[cur_server_timeout]"
+log ${Slog8_addr}:${Slog8_port} len 2048 local0 debug err
+default_backend be1
+
+backend be3
+   mode http
+   http-response set-timeout server int(3),mul(1000)
+   server srv_h1 ${srv_h1_addr}:${srv_h1_port}
+
+frontend fe4
+mode http
+bind "fd@${fe4}"
+log-format "timeout: %[fe_client_timeout] %[cur_client_timeout]"
+log ${Slog9_addr}:${Slog9_port} len 2048 local0 debug err
+http-response set-timeout client int(3),mul(1000)
+default_backend be2
+
+backend be4
+   mode http
+   server srv_h1 ${srv_h1_addr}:${srv_h1_port}
 } -start
 
 client c1 -connect ${hap_li1_sock} {
@@ -119,8 +179,36 @@ client c5 -connect ${hap_fe2_sock} {
 expect resp.status == 200
 } -run
 
+client c6 -connect ${hap_li4_sock} {
+txreq
+rxresp
+expect resp.status == 200
+} -run
+
+client c7 -connect ${hap_fe3_sock} {
+txreq
+rxresp
+expect resp.status == 200
+} -run
+
+client c8 -connect ${hap_li5_sock} {
+txreq
+rxresp
+expect resp.status == 200
+} -run
+
+client c9 -connect ${hap_fe4_sock} {
+txreq
+rxresp
+expect resp.status == 200
+} -run
+
 syslog Slog1 -wait
 syslog Slog2 -wait
 syslog Slog3 -wait
 syslog Slog4 -wait
 syslog Slog5 -

[PATCH] MINOR: support for http-request set-timeout client

2023-09-27 Thread Vladimir Vdovin
Added set-timeout for frontend side of session, so it can be used to set
custom per-client timeouts if needed. Added cur_client_timeout to fetch
client timeout samples.
---
 doc/configuration.txt  | 17 +---
 include/haproxy/action-t.h |  1 +
 include/haproxy/action.h   |  6 +--
 reg-tests/http-set-timeout/set_timeout.vtc | 46 +-
 src/action.c   | 43 +---
 src/http_act.c | 13 +-
 src/stream.c   | 16 
 7 files changed, 105 insertions(+), 37 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 37f62da33..e98f571f3 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -7010,7 +7010,7 @@ http-request  [options...] [ { if | unless } 
 ]
 - set-query 
 - set-src 
 - set-src-port 
-- set-timeout { server | tunnel } {  |  }
+- set-timeout { client | server | tunnel } {  |  }
 - set-tos 
 - set-uri 
 - set-var([,...]) 
@@ -7925,10 +7925,10 @@ http-request set-src-port  [ { if | unless } 
 ]
   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 } {  |  }
+http-request set-timeout { client | server | tunnel } {  |  }
[ { if | unless }  ]
 
-  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 } {  
|  }
 
   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
@@ -20098,6 +20098,11 @@ cur_tunnel_timeout : integer
   In the default case, this will be equal to be_tunnel_timeout unless a
   "set-timeout" rule has been applied. See also "be_tunnel_timeout".
 
+cur_client_timeout : integer
+  Returns the currently applied client timeout in millisecond for the stream.
+  In the default case, this will be equal to fe_client_timeout unless a
+  "set-timeout" rule has been applied. See also "fe_client_timeout".
+
 dst : ip
   This is the destination IP address of the connection on the client side,
   which is the address the client connected to. Any tcp/http rules may alter
@@ -20353,7 +20358,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/include/haproxy/action.h b/include/haproxy/action.h
index 8a35664f4..9511448e5 100644
--- a/include/haproxy/action.h
+++ b/include/haproxy/action.h
@@ -102,10 +102,8 @@ int check_trk_action(struct act_rule *rule, struct proxy 
*px, char **err);
  */
 int check_capture(struct act_rule *rule, struct proxy *px, char **err);
 
-int cfg_parse_rule_set_timeout(const char **args, int idx, int *out_timeout,
-   enum act_timeout_name *name,
-   struct sample_expr **expr, char **err,
-   const char *file, int line, struct arg_list 
*al);
+int cfg_parse_rule_set_timeout(const char **args, int idx, struct act_rule 
*rule,
+struct 
proxy *px, char **err);
 
 static inline void release_timeout_action(struct act_rule *rule)
 {
diff --git a/reg-tests/http-set-timeout/set_timeout.vtc 
b/reg-tests/http-set-timeout/set_timeout.vtc
index ebaa6a3b4..6fa0a35f1 100644
--- a/reg-tests/http-set-timeout/set_timeout.vtc
+++ b/reg-tests/http-set-timeout/set_timeout.vtc
@@ -4,7 +4,7 @@ feature ignore_unknown_macro
 
 #REQUIRE_VERSION=2.4
 
-server srv_h1 -repeat 3 {
+server srv_h1 -repeat 5 {
 rxreq
 txresp
 } -start
@@ -24,6 +2

[PATCH] MINOR: support for http-request set-timeout client

2023-09-25 Thread Vladimir Vdovin
Added set-timeout for frontend side of session, so it can be used to set
custom per-client timeouts if needed. Added cur_client_timeout to fetch
client timeout samples.
---
 doc/configuration.txt  | 17 +---
 include/haproxy/action-t.h |  1 +
 include/haproxy/action.h   |  3 +-
 reg-tests/http-set-timeout/set_timeout.vtc | 46 +-
 src/action.c   | 27 ++---
 src/http_act.c |  8 +---
 src/stream.c   | 16 
 7 files changed, 99 insertions(+), 19 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index d49d359a2..db6ed866a 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -7010,7 +7010,7 @@ http-request  [options...] [ { if | unless } 
 ]
 - set-query 
 - set-src 
 - set-src-port 
-- set-timeout { server | tunnel } {  |  }
+- set-timeout { client | server | tunnel } {  |  }
 - set-tos 
 - set-uri 
 - set-var([,...]) 
@@ -7925,10 +7925,10 @@ http-request set-src-port  [ { if | unless } 
 ]
   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 } {  |  }
+http-request set-timeout { client | server | tunnel } {  |  }
[ { if | unless }  ]
 
-  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 } {  
|  }
 
   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
@@ -20084,6 +20084,11 @@ cur_tunnel_timeout : integer
   In the default case, this will be equal to be_tunnel_timeout unless a
   "set-timeout" rule has been applied. See also "be_tunnel_timeout".
 
+cur_client_timeout : integer
+  Returns the currently applied client timeout in millisecond for the stream.
+  In the default case, this will be equal to fe_client_timeout unless a
+  "set-timeout" rule has been applied. See also "fe_client_timeout".
+
 dst : ip
   This is the destination IP address of the connection on the client side,
   which is the address the client connected to. Any tcp/http rules may alter
@@ -20339,7 +20344,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/include/haproxy/action.h b/include/haproxy/action.h
index 8a35664f4..73d0fdd2b 100644
--- a/include/haproxy/action.h
+++ b/include/haproxy/action.h
@@ -105,7 +105,8 @@ int check_capture(struct act_rule *rule, struct proxy *px, 
char **err);
 int cfg_parse_rule_set_timeout(const char **args, int idx, int *out_timeout,
enum act_timeout_name *name,
struct sample_expr **expr, char **err,
-   const char *file, int line, struct arg_list 
*al);
+   const char *file, int line, struct arg_list *al,
+  char *px_id, char 
*px_cap);
 
 static inline void release_timeout_action(struct act_rule *rule)
 {
diff --git a/reg-tests/http-set-timeout/set_timeout.vtc 
b/reg-tests/http-set-timeout/set_timeout.vtc
index ebaa6a3b4..6fa0a35f1 100644
--- a/reg-tests/http-set-timeout/set_timeout.vtc
+++ b/reg-tests/http-set-timeout/set_timeout.vtc
@@ -4,7 +4,7 @@ feature ignore_unknown_macro
 
 #REQUIRE_VERSION=2.4
 
-server srv_h1 -repeat 3 {
+server srv_h1 -repeat 5 {
 rxreq
 txresp
 } -start
@@ -24,6 +24,16 @@ syslog Slog3 -level info {
 expect ~ "^.*timeout: 5000 3000.*$"
 } -start
 
+syslog Slog4 -level info {

[PATCH] MINOR: support for http-request set-timeout client

2023-09-15 Thread Vladimir Vdovin
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  [options...] [ { if | unless } 
 ]
 - set-query 
 - set-src 
 - set-src-port 
-- set-timeout { server | tunnel } {  |  }
+- set-timeout { client | server | tunnel } {  |  }
 - set-tos 
 - set-uri 
 - set-var([,...]) 
@@ -7925,10 +7925,10 @@ http-request set-src-port  [ { if | unless } 
 ]
   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 } {  |  }
+http-request set-timeout { client | server | tunnel } {  |  }
[ { if | unless }  ]
 
-  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 } {  
|  }
 
   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