]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http_fetch: Add support for checks to `unique-id` fetch
authorTim Duesterhus <tim@bastelstu.be>
Mon, 13 Apr 2026 17:37:31 +0000 (19:37 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 13 Apr 2026 18:02:21 +0000 (20:02 +0200)
This allows to use the `unique-id` fetch within `tcp-check` or `http-check`
ruleset. The format is taken from the checked server's backend (which is
naturally inherited from the corresponding `defaults` section).

This is particularly useful with

    http-check send ... hdr request-id %[unique-id]

to ensure all requests sent by HAProxy have a unique ID header attached.

This resolves GitHub Issue #3307.

Reviewed-by: Volker Dusch <github@wallbash.com>
doc/configuration.txt
reg-tests/checks/unique_id.vtc [new file with mode: 0644]
src/http_fetch.c

index 7843060a635b1895b780db183887a178d7b271d9..4288e8881637c05954f725f1f8ae82113331103a 100644 (file)
@@ -6186,7 +6186,7 @@ timeout server-fin                        X          -         X         X
 timeout tarpit                            X          X         X         X
 timeout tunnel                            X          -         X         X
 transparent                 (deprecated)  X          -         X         X
-unique-id-format                          X          X         X         -
+unique-id-format                          X          X         X         X
 unique-id-header                          X          X         X         -
 use_backend                               -          X         X         -
 use-fcgi-app                              -          -         X         X
@@ -15020,7 +15020,7 @@ unique-id-format <fmt>
   May be used in the following contexts: tcp, http
 
   May be used in sections :   defaults | frontend | listen | backend
-                                  yes  |    yes   |   yes  |   no
+                                  yes  |    yes   |   yes  |   yes
 
   Arguments :
     <fmt>   is a Custom log format string (see section 8.2.6).
@@ -15042,6 +15042,11 @@ unique-id-format <fmt>
   It is recommended to use hexadecimal notation for many fields since it
   makes them more compact and saves space in logs.
 
+  For regular connections the format configured in the frontend is used to
+  generate the unique ID. For health checks the format of the backend is
+  used when using the "unique-id" fetch within a tcp-check or an http-check
+  ruleset.
+
   Example:
 
         unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid
diff --git a/reg-tests/checks/unique_id.vtc b/reg-tests/checks/unique_id.vtc
new file mode 100644 (file)
index 0000000..f6d8754
--- /dev/null
@@ -0,0 +1,49 @@
+varnishtest "Health-checks: unique_id fetch"
+feature ignore_unknown_macro
+#REGTEST_TYPE=slow
+
+server s1 {
+    rxreq
+    expect req.method == GET
+    expect req.url == /
+    expect req.proto == HTTP/1.1
+    expect req.http.host == "localhost"
+    expect req.http.request-id == "TEST-be=up"
+
+    txresp
+} -start
+
+syslog S1 -level notice {
+    recv
+    expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be/srv succeeded.*code: 200"
+} -start
+
+haproxy h1 -conf {
+    global
+    .if feature(THREAD)
+        thread-groups 1
+    .endif
+
+    defaults
+        mode http
+        timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+        option httpchk
+        option log-health-checks
+
+    backend be
+        log ${S1_addr}:${S1_port} len 2048 local0
+
+        unique-id-format TEST-%[be_name]=%[srv_is_up(srv),iif(up,down)]
+
+        http-check connect
+        http-check send meth GET uri / ver HTTP/1.1 hdr host localhost hdr request-id %[unique-id]
+        http-check expect status 200
+
+        ## implicit expect rule
+        server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1
+
+} -start
+
+syslog S1 -wait
index e49c8bb71436593d621907ae2ed9eae04433516d..3169214facc13026efca05a56299761b012ff9f0 100644 (file)
@@ -22,6 +22,7 @@
 #include <haproxy/base64.h>
 #include <haproxy/channel.h>
 #include <haproxy/chunk.h>
+#include <haproxy/check.h>
 #include <haproxy/connection.h>
 #include <haproxy/global.h>
 #include <haproxy/h1.h>
@@ -504,14 +505,22 @@ static int smp_fetch_srv_status(const struct arg *args, struct sample *smp, cons
 static int smp_fetch_uniqueid(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
        struct ist unique_id;
+       struct check *check;
 
-       if (lf_expr_isempty(&smp->sess->fe->format_unique_id))
-               return 0;
+       if (smp->strm) {
+               if (lf_expr_isempty(&smp->sess->fe->format_unique_id))
+                       return 0;
 
-       if (!smp->strm)
+               unique_id = stream_generate_unique_id(smp->strm, &smp->sess->fe->format_unique_id);
+       } else if ((check = objt_check(smp->sess->origin)) != NULL) {
+               if (lf_expr_isempty(&check->proxy->format_unique_id))
+                       return 0;
+
+               unique_id = check_generate_unique_id(check, &check->proxy->format_unique_id);
+       } else {
                return 0;
+       }
 
-       unique_id = stream_generate_unique_id(smp->strm, &smp->sess->fe->format_unique_id);
        if (!isttest(unique_id))
                return 0;