]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: streams: Add a new keyword for retry-on, "junk-response"
authorOlivier Houchard <cognet@ci0.org>
Fri, 3 May 2019 21:01:47 +0000 (23:01 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 4 May 2019 08:20:24 +0000 (10:20 +0200)
Add a way to retry requests if we got a junk response from the server, ie
an incomplete response, or something that is not valid HTTP.
To do so, one can use the new "junk-response" keyword for retry-on.

doc/configuration.txt
include/types/proxy.h
src/proto_htx.c
src/proxy.c

index 827c6b0b2157b7667ea1d6e3d81edd3f6255efb6..ee6f81c1d7cdb8f6af25ea027f4f66598f419b70 100644 (file)
@@ -8027,6 +8027,14 @@ retry-on [list of keywords]
                         condition, or a server crash or restart while
                         processing the request.
 
+      junk-response     retry when the server returned something not looking
+                        like a complete HTTP response. This includes partial
+                        responses headers as well as non-HTTP contents. It
+                        usually is a bad idea to retry on such events, which
+                        may be caused a configuration issue (wrong server port)
+                        or by the request being harmful to the server (buffer
+                        overflow attack for example).
+
       response-timeout  the server timeout stroke while waiting for the server
                         to respond to the request. This may be caused by poor
                         network condition, the reuse of an idle connection
index 86fd5e7fb2007c2cb22175e9dd59d617448ae7ce..dababea344e21f9ee6de2969b0a9751c0d213777 100644 (file)
@@ -222,6 +222,7 @@ enum PR_SRV_STATE_FILE {
  * reserved for eventual future status codes
  */
 #define PR_RE_EARLY_ERROR         0x00010000 /* Retry if we failed at sending early data */
+#define PR_RE_JUNK_REQUEST        0x00020000 /* We received an incomplete or garbage response */
 struct stream;
 
 struct http_snapshot {
index 41012b4720ce6b34b5b63d665c118dcef8b0d791..95b81c9e51ea8bb3b996aaf58e328c75626e1d43 100644 (file)
@@ -1812,6 +1812,9 @@ int htx_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                _HA_ATOMIC_ADD(&__objt_server(s->target)->counters.failed_resp, 1);
                health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_HDRRSP);
        }
+       if ((s->be->retry_type & PR_RE_JUNK_REQUEST) &&
+           do_l7_retry(s, si_b) == 0)
+               return 0;
        txn->status = 502;
        s->si[1].flags |= SI_FL_NOLINGER;
        htx_reply_and_close(s, txn->status, htx_error_message(s));
index e3d59dc2ceba9284695d5cd52caceb4bdb5c8202..18f016c83a997b0404f4a3cd977416618b1dedc1 100644 (file)
@@ -543,6 +543,8 @@ proxy_parse_retry_on(char **args, int section, struct proxy *curpx,
                        curpx->retry_type |= PR_RE_504;
                else if (!strcmp(args[i], "0rtt-rejected"))
                        curpx->retry_type |= PR_RE_EARLY_ERROR;
+               else if (!strcmp(args[i], "junk-response"))
+                       curpx->retry_type |= PR_RE_JUNK_REQUEST;
                else if (!strcmp(args[i], "none")) {
                        if (i != 1 || *args[i + 1]) {
                                memprintf(err, "'%s' 'none' keyworld only usable alone", args[0]);