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 827c6b0..ee6f81c 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 86fd5e7..dababea 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 41012b4..95b81c9 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 e3d59dc..18f016c 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]);