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 <[email protected]>
---
doc/configuration.txt | 9 +++++--
reg-tests/checks/unique_id.vtc | 49 ++++++++++++++++++++++++++++++++++
src/http_fetch.c | 17 +++++++++---
3 files changed, 69 insertions(+), 6 deletions(-)
create mode 100644 reg-tests/checks/unique_id.vtc
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 34d0b6d30..218b56c77 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -6154,7 +6154,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
@@ -14988,7 +14988,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).
@@ -15010,6 +15010,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
index 000000000..83b3ac100
--- /dev/null
+++ b/reg-tests/checks/unique_id.vtc
@@ -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
diff --git a/src/http_fetch.c b/src/http_fetch.c
index e49c8bb71..3169214fa 100644
--- a/src/http_fetch.c
+++ b/src/http_fetch.c
@@ -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;
--
2.53.0