haproxy/reg-tests/sample_fetches/vars.vtc
Willy Tarreau 54496a6a5b MINOR: vars: make the vars() sample fetch function support a default value
It is quite common to see in configurations constructions like the
following one:

    http-request set-var(txn.bodylen) 0
    http-request set-var(txn.bodylen) req.hdr(content-length)
    ...
    http-request set-header orig-len %[var(txn.bodylen)]

The set-var() rules are almost always duplicated when manipulating
integers or any other value that is mandatory along operations. This is
a problem because it makes the configurations complicated to maintain
and slower than needed. And it becomes even more complicated when several
conditions may set the same variable because the risk of forgetting to
initialize it or to accidentally reset it is high.

This patch extends the var() sample fetch function to take an optional
argument which contains a default value to be returned if the variable
was not set. This way it becomes much simpler to use the variable, just
set it where needed, and read it with a fall back to the default value:

    http-request set-var(txn.bodylen) req.hdr(content-length)
    ...
    http-request set-header orig-len %[var(txn.bodylen,0)]

The default value is always passed as a string, thus it will experience
a cast to the output type. It doesn't seem userful to complicate the
configuration to pass an explicit type at this point.

The vars.vtc regtest was updated accordingly.
2021-09-03 12:08:54 +02:00

85 lines
3.2 KiB
Plaintext

varnishtest "Test a few set-var() in global, tcp and http rule sets, at different scopes"
feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev5)'"
feature ignore_unknown_macro
haproxy h1 -conf {
global
# note below, str60 is purposely not defined so that the default is used
set-var proc.int12 int(12)
set-var proc.int5 var(proc.str60,60),div(proc.int12)
set-var proc.str1 str("this is")
set-var proc.str2 str("a string")
set-var proc.str var(proc.str1)
set-var-fmt proc.str "%[var(proc.str)] a string"
set-var proc.uuid uuid()
defaults
mode http
timeout connect 1s
timeout client 1s
timeout server 1s
frontend fe1
bind "fd@${fe1}"
tcp-request session set-var-fmt(sess.str3) "%[var(proc.str1)] %[var(proc.str2)]"
tcp-request session set-var(sess.int5) var(proc.int5)
tcp-request session set-var(proc.int5) var(proc.int5),add(sess.int5) ## proc. becomes 10
tcp-request content set-var-fmt(req.str4) "%[var(sess.str3),regsub(is a,is also a)]"
http-request set-var-fmt(txn.str5) "%[var(req.str4)]"
http-request set-var(req.int5) var(sess.int5)
http-request set-var(sess.int5) var(sess.int5),add(req.int5) ## sess. becomes 10 first time, then 15...
http-request return status 200 hdr x-var "proc=%[var(proc.int5)] sess=%[var(sess.int5)] req=%[var(req.int5)] str=%[var(proc.str)] str5=%[var(txn.str5)] uuid=%[var(proc.uuid)]"
} -start
haproxy h1 -cli {
send "get var proc.int5"
expect ~ "^proc.int5: type=sint value=<5>$"
}
client c1 -connect ${h1_fe1_sock} {
txreq -req GET -url /req1_1
rxresp
expect resp.status == 200
expect resp.http.x-var ~ "proc=10 sess=10 req=5 str=this is a string str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*"
txreq -req GET -url /req1_2
rxresp
expect resp.status == 200
expect resp.http.x-var ~ "proc=10 sess=20 req=10 str=this is a string str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*"
} -run
haproxy h1 -cli {
send "get var proc.int5"
expect ~ "^proc.int5: type=sint value=<10>$"
}
client c2 -connect ${h1_fe1_sock} {
txreq -req GET -url /req2_1
rxresp
expect resp.status == 200
expect resp.http.x-var ~ "proc=20 sess=20 req=10 str=this is a string str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*"
txreq -req GET -url /req2_2
rxresp
expect resp.status == 200
expect resp.http.x-var ~ "proc=20 sess=40 req=20 str=this is a string str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*"
} -run
haproxy h1 -cli {
send "get var proc.int5"
expect ~ "^proc.int5: type=sint value=<20>$"
}
haproxy h1 -cli {
send "experimental-mode on; set var proc.str str(updating); set var proc.str fmt %[var(proc.str),regsub(ing,ed)]"
expect ~ .*
}
client c3 -connect ${h1_fe1_sock} {
txreq -req GET -url /req3_1
rxresp
expect resp.status == 200
expect resp.http.x-var ~ "proc=40 sess=40 req=20 str=updated str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*"
} -run