Dear,

Please find a patch to add 401 and 403 l7 retries, see
https://github.com/haproxy/haproxy/issues/948

-- 
 (o-    Julien Pivotto
 //\    Open-Source Consultant
 V_/_   Inuits - https://www.inuits.eu
From f71e0b2eb69303fa59645fefda3960fb2a9eb7fb Mon Sep 17 00:00:00 2001
From: Julien Pivotto <roidelapl...@inuits.eu>
Date: Thu, 12 Nov 2020 11:14:05 +0100
Subject: [PATCH] Add level 7 retries on http error 401, 403

Signed-off-by: Julien Pivotto <roidelapl...@inuits.eu>
---
 doc/configuration.txt     |  9 +++++----
 include/haproxy/proxy-t.h | 25 ++++++++++++++-----------
 include/haproxy/proxy.h   |  4 ++++
 src/proxy.c               |  4 ++++
 4 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 2a7a9a508..234002294 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -9307,10 +9307,11 @@ retry-on [list of keywords]
                         rejected by the server. These requests are generally
                         considered to be safe to retry.
 
-      <status>          any HTTP status code among "404" (Not Found), "408"
-                        (Request Timeout), "425" (Too Early), "500" (Server
-                        Error), "501" (Not Implemented), "502" (Bad Gateway),
-                        "503" (Service Unavailable), "504" (Gateway Timeout).
+      <status>          any HTTP status code among "401" (Unauthorized), "403"
+                        (Forbidden), "404" (Not Found), "408" (Request 
Timeout),
+                        "425" (Too Early), "500" (Server Error), "501" (Not
+                        Implemented), "502" (Bad Gateway), "503" (Service
+                        Unavailable), "504" (Gateway Timeout).
 
       all-retryable-errors
                         retry request for any error that are considered
diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h
index 41aca9d39..998e210f6 100644
--- a/include/haproxy/proxy-t.h
+++ b/include/haproxy/proxy-t.h
@@ -175,17 +175,20 @@ enum PR_SRV_STATE_FILE {
 #define PR_RE_CONN_FAILED         0x00000001 /* Retry if we failed to connect 
*/
 #define PR_RE_DISCONNECTED        0x00000002 /* Retry if we got disconnected 
with no answer */
 #define PR_RE_TIMEOUT             0x00000004 /* Retry if we got a server 
timeout before we got any data */
-#define PR_RE_404                 0x00000008 /* Retry if we got a 404 */
-#define PR_RE_408                 0x00000010 /* Retry if we got a 408 */
-#define PR_RE_425                 0x00000020 /* Retry if we got a 425 */
-#define PR_RE_500                 0x00000040 /* Retry if we got a 500 */
-#define PR_RE_501                 0x00000080 /* Retry if we got a 501 */
-#define PR_RE_502                 0x00000100 /* Retry if we got a 502 */
-#define PR_RE_503                 0x00000200 /* Retry if we got a 503 */
-#define PR_RE_504                 0x00000400 /* Retry if we got a 504 */
-#define PR_RE_STATUS_MASK         (PR_RE_404 | PR_RE_408 | PR_RE_425 | \
-                                   PR_RE_425 | PR_RE_500 | PR_RE_501 | \
-                                   PR_RE_502 | PR_RE_503 | PR_RE_504)
+#define PR_RE_401                 0x00000008 /* Retry if we got a 401 */
+#define PR_RE_403                 0x00000010 /* Retry if we got a 403 */
+#define PR_RE_404                 0x00000020 /* Retry if we got a 404 */
+#define PR_RE_408                 0x00000040 /* Retry if we got a 408 */
+#define PR_RE_425                 0x00000080 /* Retry if we got a 425 */
+#define PR_RE_500                 0x00000100 /* Retry if we got a 500 */
+#define PR_RE_501                 0x00000200 /* Retry if we got a 501 */
+#define PR_RE_502                 0x00000400 /* Retry if we got a 502 */
+#define PR_RE_503                 0x00000800 /* Retry if we got a 503 */
+#define PR_RE_504                 0x00001000 /* Retry if we got a 504 */
+#define PR_RE_STATUS_MASK         (PR_RE_401 | PR_RE_403 | PR_RE_404 | \
+                                   PR_RE_408 | PR_RE_425 | PR_RE_500 | \
+                                   PR_RE_501 | PR_RE_502 | PR_RE_503 | \
+                                   PR_RE_504)
 /* 0x00000800, 0x00001000, 0x00002000, 0x00004000 and 0x00008000 unused,
  * reserved for eventual future status codes
  */
diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h
index fe253bf7f..f63f4a2cd 100644
--- a/include/haproxy/proxy.h
+++ b/include/haproxy/proxy.h
@@ -154,6 +154,10 @@ static inline int l7_status_match(struct proxy *p, int 
status)
                return 0;
 
        switch (status) {
+       case 401:
+               return (p->retry_type & PR_RE_401);
+       case 403:
+               return (p->retry_type & PR_RE_403);
        case 404:
                return (p->retry_type & PR_RE_404);
        case 408:
diff --git a/src/proxy.c b/src/proxy.c
index e469c7671..ec8d3cf10 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -528,6 +528,10 @@ proxy_parse_retry_on(char **args, int section, struct 
proxy *curpx,
                        curpx->retry_type |= PR_RE_DISCONNECTED;
                else if (!strcmp(args[i], "response-timeout"))
                        curpx->retry_type |= PR_RE_TIMEOUT;
+               else if (!strcmp(args[i], "401"))
+                       curpx->retry_type |= PR_RE_401;
+               else if (!strcmp(args[i], "403"))
+                       curpx->retry_type |= PR_RE_403;
                else if (!strcmp(args[i], "404"))
                        curpx->retry_type |= PR_RE_404;
                else if (!strcmp(args[i], "408"))
-- 
2.28.0

Attachment: signature.asc
Description: PGP signature

Reply via email to