]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: tcpcheck: refresh the start-line after updating the authority
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 23 Sep 2026 04:40:03 +0000 (04:40 +0000)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 23 Sep 2026 12:05:26 +0000 (14:05 +0200)
When an HTTP health-check request was built with an absolute URI, each
"host" header set by "http-check send" updated the authority of the URI with
http_update_authority(). This rewrote the start-line, which could move it
elsewhere in the HTX message. So, in tcpcheck_eval_send(), the start-line
pointer <sl> must be renewed in that case.

Let's retrieve the start-line again after each authority update. A reg-test
was added.

This must be backported to all supported versions.

reg-tests/checks/http-check-send-authority.vtc [new file with mode: 0644]
src/tcpcheck.c

diff --git a/reg-tests/checks/http-check-send-authority.vtc b/reg-tests/checks/http-check-send-authority.vtc
new file mode 100644 (file)
index 0000000..a4d2f88
--- /dev/null
@@ -0,0 +1,35 @@
+varnishtest "Health-checks: http-check send with an absolute URI and a host header"
+feature ignore_unknown_macro
+
+# When an HTTP health-check request is sent with an absolute URI, a host
+# header updates the authority of the URI. This may move the start-line in
+# the HTX message, so the flags set on the start-line afterwards, such as
+# the one announcing the content-length of the body, must be set on the new
+# one. Otherwise the request is sent with a body but without its
+# content-length.
+
+server s1 {
+    rxreq
+    expect req.method == POST
+    expect req.url == "http://a-much-longer-host-name.example.org/chk"
+    expect req.http.host == "a-much-longer-host-name.example.org"
+    expect req.http.content-length == 5
+    expect req.bodylen == 5
+    expect req.body == "hello"
+    txresp
+} -start
+
+haproxy h1 -conf {
+    defaults
+        mode http
+        timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout client  "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout server  "${HAPROXY_TEST_TIMEOUT-5s}"
+
+    backend be
+        option httpchk
+        http-check send meth POST uri http://a/chk ver HTTP/1.1 hdr host a-much-longer-host-name.example.org body "hello"
+        server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1
+} -start
+
+server s1 -wait
index d0e9770d81eff6b87d247af60a3521aec8bb7c59..e924155d9c48294bfafbff04c627f3e01da9a1c1 100644 (file)
@@ -1791,6 +1791,8 @@ enum tcpcheck_eval_ret tcpcheck_eval_send(struct check *check, struct tcpcheck_r
                                if ((sl->flags & HTX_SL_F_HAS_AUTHORITY) && isteqi(hdr->name, ist("host"))) {
                                        if (!http_update_authority(htx, sl, hdr_value))
                                                goto error_htx;
+                                       /* the start-line may have been moved */
+                                       sl = http_get_stline(htx);
                                }
                                if (isteqi(hdr->name, ist("connection")))
                                        connection_hdr = 1;