]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: checks: Support log-format string to set the body for HTTP send rules
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 6 May 2020 13:38:58 +0000 (15:38 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 6 May 2020 16:04:05 +0000 (18:04 +0200)
For http-check send rules, it is now possible to use a log-format string to set
the request's body. the keyword "body-lf" should be used instead of "body". If the
string eval fails, no body is added.

doc/configuration.txt
reg-tests/checks/http-check.vtc
src/checks.c

index da5d05e78132c809616f7fbed67935b73a165047..8ddd43f7eed7432ceecc5f91daa5e7e51c2adedc 100644 (file)
@@ -4682,7 +4682,8 @@ http-check expect [min-recv <int>] [comment <msg>]
 
 
 http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
-                [hdr <name> <fmt>]* [body <string>] [comment <msg>]
+                [hdr <name> <fmt>]* [{ body <string> | body-lf <fmt> }]
+                [comment <msg>]
   Add a possible list of headers and/or a body to the request sent during HTTP
   health checks.
   May be used in sections :   defaults | frontend | listen | backend
@@ -4720,6 +4721,11 @@ http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
                    HTTP health checks. If defined, the "Content-Length" header
                    is thus automatically added to the request.
 
+    body-lf <fmt>  add the body defined by the log-format string <fmt> to the
+                   request sent during HTTP health checks. If defined, the
+                   "Content-Length" header is thus automatically added to the
+                   request.
+
   In addition to the request line defined by the "option httpchk" directive,
   this one is the valid way to add some headers and optionally a body to the
   request sent during HTTP health checks. If a body is defined, the associate
index 3de3e3f8fe98430e5a13b5ac4d4672e0238ebdb5..27ad474eadaff2bc6d8f3fd57b9ef4e7b1ae864d 100644 (file)
@@ -67,7 +67,8 @@ server s4 {
     expect req.proto == HTTP/1.0
     expect req.http.x-test == <undef>
     expect req.http.x-haproxy-server-state ~ "UP.+name=be4/srv"
-    expect req.bodylen == 0
+    expect req.bodylen == 23
+    expect req.body == "health-check on be4-srv"
     txresp
 
 } -start
@@ -137,7 +138,7 @@ haproxy h1 -conf {
         http-check expect rstatus "^2[0-9]{2}"
         http-check connect addr ${s4_addr} port ${s4_port}
         http-check unset-var(check.path)
-        http-check send meth GET uri-lf "%[var(check.path)]" # default to "/"
+        http-check send meth GET uri-lf "%[var(check.path)]" body-lf "health-check on %[be_name]-%[srv_name]"
         ## implicit expect rule
         server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1
 
index 0723488a6a8e71322aac62c1d02442fac0ed7065..b59c6b7e979d1d48ff77a82d21109a57e6107036 100644 (file)
@@ -1987,13 +1987,6 @@ static enum tcpcheck_eval_ret tcpcheck_eval_send(struct check *check, struct tcp
                if (!http_update_host(htx, sl, uri))
                        goto error_htx;
 
-               body = send->http.body; // TODO: handle body_fmt
-               clen = ist((!istlen(body) ? "0" : ultoa(istlen(body))));
-
-               if (!htx_add_header(htx, ist("Connection"), ist("close")) ||
-                   !htx_add_header(htx, ist("Content-length"), clen))
-                       goto error_htx;
-
                if (!LIST_ISEMPTY(&send->http.hdrs)) {
                        struct tcpcheck_http_hdr *hdr;
                        struct ist hdr_value;
@@ -2020,8 +2013,23 @@ static enum tcpcheck_eval_ret tcpcheck_eval_send(struct check *check, struct tcp
                                goto error_htx;
                }
 
+
+               if (send->http.flags & TCPCHK_SND_HTTP_FL_BODY_FMT) {
+                       chunk_reset(tmp);
+                       tmp->data = sess_build_logline(check->sess, NULL, b_orig(tmp), b_size(tmp), &send->http.body_fmt);
+                       body = ist2(b_orig(tmp), b_data(tmp));
+               }
+               else
+                       body = send->http.body;
+               clen = ist((!istlen(body) ? "0" : ultoa(istlen(body))));
+
+               if (!htx_add_header(htx, ist("Connection"), ist("close")) ||
+                   !htx_add_header(htx, ist("Content-length"), clen))
+                       goto error_htx;
+
+
                if (!htx_add_endof(htx, HTX_BLK_EOH) ||
-                   (istlen(body) && !htx_add_data_atonce(htx, send->http.body)) ||
+                   (istlen(body) && !htx_add_data_atonce(htx, body)) ||
                    !htx_add_endof(htx, HTX_BLK_EOM))
                        goto error_htx;
 
@@ -4054,14 +4062,16 @@ static struct tcpcheck_rule *parse_tcpcheck_send_http(char **args, int cur_arg,
                  skip_hdr:
                        cur_arg += 2;
                }
-               else if (strcmp(args[cur_arg], "body") == 0) {
+               else if (strcmp(args[cur_arg], "body") == 0 || strcmp(args[cur_arg], "body-lf") == 0) {
                        if (!*(args[cur_arg+1])) {
                                memprintf(errmsg, "'%s' expects a string as argument.", args[cur_arg]);
                                goto error;
                        }
+                       flags &= ~TCPCHK_SND_HTTP_FL_BODY_FMT;
+                       if (strcmp(args[cur_arg], "body-lf") == 0)
+                               flags |= TCPCHK_SND_HTTP_FL_BODY_FMT;
                        cur_arg++;
                        body = args[cur_arg];
-                       // TODO: log-format body
                }
                else if (strcmp(args[cur_arg], "comment") == 0) {
                        if (!*(args[cur_arg+1])) {
@@ -4077,7 +4087,7 @@ static struct tcpcheck_rule *parse_tcpcheck_send_http(char **args, int cur_arg,
                        }
                }
                else {
-                       memprintf(errmsg, "expects 'comment', 'meth', 'uri', 'uri-lf', 'ver', 'hdr' and 'body'"
+                       memprintf(errmsg, "expects 'comment', 'meth', 'uri', 'uri-lf', 'ver', 'hdr', 'body' or 'body-lf'"
                                  " but got '%s' as argument.", args[cur_arg]);
                        goto error;
                }
@@ -4151,10 +4161,20 @@ static struct tcpcheck_rule *parse_tcpcheck_send_http(char **args, int cur_arg,
        }
 
        if (body) {
-               chk->send.http.body = ist2(strdup(body), strlen(body));
-               if (!isttest(chk->send.http.body)) {
-                       memprintf(errmsg, "out of memory");
-                       goto error;
+               if (chk->send.http.flags & TCPCHK_SND_HTTP_FL_BODY_FMT) {
+                       LIST_INIT(&chk->send.http.body_fmt);
+                       px->conf.args.ctx = ARGC_SRV;
+                       if (!parse_logformat_string(body, px, &chk->send.http.body_fmt, 0, SMP_VAL_BE_CHK_RUL, errmsg)) {
+                               memprintf(errmsg, "'%s' invalid log-format string (%s).\n", body, *errmsg);
+                               goto error;
+                       }
+               }
+               else {
+                       chk->send.http.body = ist2(strdup(body), strlen(body));
+                       if (!isttest(chk->send.http.body)) {
+                               memprintf(errmsg, "out of memory");
+                               goto error;
+                       }
                }
        }