diff --git a/doc/configuration.txt b/doc/configuration.txt index 9972ce107..0e2836ee0 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -9858,6 +9858,7 @@ option httpchk option httpchk option httpchk option httpchk +option httpchk Enables HTTP protocol to check on the servers health May be used in the following contexts: tcp, http @@ -9879,7 +9880,10 @@ option httpchk is the optional HTTP version string. It defaults to "HTTP/1.0" but some servers might behave incorrectly in HTTP 1.0, so turning it to HTTP/1.1 may sometimes help. Note that the Host field is - mandatory in HTTP/1.1, use "http-check send" directive to add it. + mandatory in HTTP/1.1. + + is the optional HTTP Host header value. It is not set by default. + It is a log-format string. By default, server health checks only consist in trying to establish a TCP connection. When "option httpchk" is specified, a complete HTTP request is diff --git a/reg-tests/checks/http-check.vtc b/reg-tests/checks/http-check.vtc index 0cb6a167c..31ef87abb 100644 --- a/reg-tests/checks/http-check.vtc +++ b/reg-tests/checks/http-check.vtc @@ -8,6 +8,7 @@ server s1 { expect req.method == OPTIONS expect req.url == / expect req.proto == HTTP/1.0 + expect req.http.host == txresp } -start @@ -16,6 +17,7 @@ server s2 { expect req.method == GET expect req.url == /status expect req.proto == HTTP/1.1 + expect req.http.host == "www.haproxy.org" txresp } -start @@ -102,7 +104,7 @@ haproxy h1 -conf { backend be2 log ${S1_addr}:${S1_port} len 2048 local0 - option httpchk GET /status HTTP/1.1 + option httpchk GET /status HTTP/1.1 www.haproxy.org server srv ${s2_addr}:${s2_port} check inter 100ms rise 1 fall 1 backend be3 diff --git a/src/tcpcheck.c b/src/tcpcheck.c index d5bd796f3..10aad1af8 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -5081,7 +5081,7 @@ static struct tcpcheck_rule *proxy_parse_httpchk_req(char **args, int cur_arg, s { struct tcpcheck_rule *chk = NULL; struct tcpcheck_http_hdr *hdr = NULL; - char *meth = NULL, *uri = NULL, *vsn = NULL; + char *meth = NULL, *uri = NULL, *vsn = NULL, *host = NULL; char *hdrs, *body; hdrs = (*args[cur_arg+2] ? strstr(args[cur_arg+2], "\r\n") : NULL); @@ -5114,6 +5114,8 @@ static struct tcpcheck_rule *proxy_parse_httpchk_req(char **args, int cur_arg, s uri = args[cur_arg+1]; if (*args[cur_arg+2]) vsn = args[cur_arg+2]; + if (*args[cur_arg+3]) + host = args[cur_arg+3]; if (meth) { chk->send.http.meth.meth = find_http_meth(meth, strlen(meth)); @@ -5138,6 +5140,24 @@ static struct tcpcheck_rule *proxy_parse_httpchk_req(char **args, int cur_arg, s goto error; } } + if (host) { + hdr = calloc(1, sizeof(*hdr)); + if (!hdr) { + memprintf(errmsg, "out of memory"); + goto error; + } + lf_expr_init(&hdr->value); + hdr->name = istdup(ist("host")); + if (!isttest(hdr->name)) { + memprintf(errmsg, "out of memory"); + goto error; + } + + if (!parse_logformat_string(host, px, &hdr->value, 0, SMP_VAL_BE_CHK_RUL, errmsg)) + goto error; + LIST_APPEND(&chk->send.http.hdrs, &hdr->list); + hdr = NULL; + } return chk; @@ -5160,7 +5180,7 @@ int proxy_parse_httpchk_opt(char **args, int cur_arg, struct proxy *curpx, const if (warnifnotcap(curpx, PR_CAP_BE, file, line, args[cur_arg+1], NULL)) err_code |= ERR_WARN; - if (alertif_too_many_args_idx(3, 1, file, line, args, &err_code)) + if (alertif_too_many_args_idx(4, 1, file, line, args, &err_code)) goto out; chk = proxy_parse_httpchk_req(args, cur_arg+2, curpx, &errmsg);