From: Christopher Faulet Date: Wed, 6 May 2020 13:38:58 +0000 (+0200) Subject: MINOR: checks: Support log-format string to set the body for HTTP send rules X-Git-Tag: v2.2-dev8~113 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=574e7bd7f3e882ba1fa86d8a1f8f2fc07186ef5e;p=thirdparty%2Fhaproxy.git MINOR: checks: Support log-format string to set the body for HTTP send rules 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. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index da5d05e781..8ddd43f7ee 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -4682,7 +4682,8 @@ http-check expect [min-recv ] [comment ] http-check send [meth ] [{ uri | uri-lf }>] [ver ] - [hdr ]* [body ] [comment ] + [hdr ]* [{ body | body-lf }] + [comment ] 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 ] [{ uri | uri-lf }>] [ver ] HTTP health checks. If defined, the "Content-Length" header is thus automatically added to the request. + body-lf add the body defined by the log-format string 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 diff --git a/reg-tests/checks/http-check.vtc b/reg-tests/checks/http-check.vtc index 3de3e3f8fe..27ad474ead 100644 --- a/reg-tests/checks/http-check.vtc +++ b/reg-tests/checks/http-check.vtc @@ -67,7 +67,8 @@ server s4 { expect req.proto == HTTP/1.0 expect req.http.x-test == 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 diff --git a/src/checks.c b/src/checks.c index 0723488a6a..b59c6b7e97 100644 --- a/src/checks.c +++ b/src/checks.c @@ -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; + } } }