summaryrefslogtreecommitdiffstats
path: root/reg-tests/sample_fetches
diff options
context:
space:
mode:
Diffstat (limited to 'reg-tests/sample_fetches')
-rw-r--r--reg-tests/sample_fetches/cond_set_var.vtc362
-rw-r--r--reg-tests/sample_fetches/cook.vtc37
-rw-r--r--reg-tests/sample_fetches/hashes.vtc101
-rw-r--r--reg-tests/sample_fetches/so_name.vtc22
-rw-r--r--reg-tests/sample_fetches/srv_name.vtc46
-rw-r--r--reg-tests/sample_fetches/ubase64.vtc57
-rw-r--r--reg-tests/sample_fetches/vars.vtc84
7 files changed, 709 insertions, 0 deletions
diff --git a/reg-tests/sample_fetches/cond_set_var.vtc b/reg-tests/sample_fetches/cond_set_var.vtc
new file mode 100644
index 0000000..67786ae
--- /dev/null
+++ b/reg-tests/sample_fetches/cond_set_var.vtc
@@ -0,0 +1,362 @@
+#REGTEST_TYPE=devel
+
+# This regtest checks the multiple conditions that can be specified to a
+# set-var call (be it a converter or HTTP or TCP action). It mainly uses the
+# actions but since the "var_set" function is used for the converter and for
+# the actions, it should be enough to focus on one type of set-var.
+# Among the variables that can be defined and the multiple scopes they can
+# have, the proc scope is the only one having a specific behaviour. Proc scoped
+# variables are created during init when a variable of any other scope is
+# created during the first successful set-var.
+# Since this test uses variables of different scopes, the validation cannot be
+# based on the "show var" command of the CLI because it only displays process
+# variables. It then always follows the same logic, for every sub test case :
+# an HTTP header is added to the response in which we add a concatenation of
+# all the tested variables (which exist in the request/response scope). These
+# HTTP headers are then tested upon an expected result (which changes for every
+# test case).
+#
+
+varnishtest "Test the conditional set-var converter and action"
+feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'"
+feature cmd "command -v socat"
+feature ignore_unknown_macro
+
+server s1 -repeat 10 {
+ rxreq
+ txresp
+} -start
+
+haproxy h1 -conf {
+ global
+ set-var proc.int12 int(12)
+ set-var proc.int5 var(proc.str60,60),div(proc.int12)
+
+ defaults
+ mode http
+ timeout connect 100ms
+ timeout client 1s
+ timeout server 1s
+
+ listen main-fe
+ bind "fd@${mainfe}"
+
+ use_backend ifexists_be if { path_beg /ifexists }
+ use_backend ifnotexists_be if { path_beg /ifnotexists }
+ use_backend ifempty_be if { path_beg /ifempty }
+ use_backend ifnotempty_be if { path_beg /ifnotempty }
+ use_backend ifset_be if { path_beg /ifset }
+ use_backend ifnotset_be if { path_beg /ifnotset }
+ use_backend ifgt_be if { path_beg /ifgt }
+ use_backend iflt_be if { path_beg /iflt }
+ use_backend combined_be if { path_beg /combined }
+ use_backend converter_be if { path_beg /converter }
+
+
+ backend ifexists_be
+ server s1 ${s1_addr}:${s1_port}
+
+ # proc scope variables are created during configuration parsing so the
+ # ifexists condition will always be true for those variables
+ http-response set-var(proc.ifexists_proc,ifexists) var(proc.int12)
+ http-response set-var(sess.ifexists_sess,ifexists) var(proc.int5)
+ http-response set-var(res.ifexists_res,ifexists) str(toto)
+
+ http-response set-header x-var "proc.ifexists=%[var(proc.ifexists_proc)] sess.ifexists=%[var(sess.ifexists_sess)] res.ifexists=%[var(res.ifexists_res)]"
+
+
+ backend ifnotexists_be
+ server s1 ${s1_addr}:${s1_port}
+
+ http-response set-header x-var-init "proc.ifnotexists=%[var(proc.ifnotexists_proc)] sess.ifnotexists=%[var(sess.ifnotexists_sess)] res.ifnotexists=%[var(res.ifnotexists_res)]"
+
+ http-response set-var(proc.ifnotexists_proc,ifnotexists) var(proc.int12)
+ http-response set-var(sess.ifnotexists_sess,ifnotexists) var(proc.int5)
+ http-response set-var(res.ifnotexists_res,ifnotexists) str(toto)
+
+ http-response set-header x-var "proc.ifnotexists=%[var(proc.ifnotexists_proc)] sess.ifnotexists=%[var(sess.ifnotexists_sess)] res.ifnotexists=%[var(res.ifnotexists_res)]"
+
+
+ backend ifempty_be
+ server s1 ${s1_addr}:${s1_port}
+ # init
+ http-response set-var(proc.ifempty_proc) str(ifempty_proc)
+ http-response set-var(sess.ifempty_sess) bin(6966656d7074795f73657373) #ifempty_sess
+ http-response set-var(res.ifempty_res) str(ifempty_res)
+ http-response set-var(res.ifempty_res_int) int(5)
+
+ http-response set-header x-var-init "proc.ifempty=%[var(proc.ifempty_proc)] sess.ifempty=%[var(sess.ifempty_sess)] res.ifempty=%[var(res.ifempty_res)] res.ifempty_res_int=%[var(res.ifempty_res_int)]"
+
+ # None of those set-var calls should actually change their respective variables
+ # since none of the samples is empty
+ http-response set-var(proc.ifempty_proc,ifempty) int(12)
+ http-response set-var(sess.ifempty_sess,ifempty) bool(false)
+ http-response set-var(res.ifempty_res,ifempty) bin(746F746F) # "toto"
+ http-response set-var(res.ifempty_res_int,ifempty) str(toto)
+
+ http-response set-header x-var1 "proc.ifempty=%[var(proc.ifempty_proc)] sess.ifempty=%[var(sess.ifempty_sess)] res.ifempty=%[var(res.ifempty_res)] res.ifempty_res_int=%[var(res.ifempty_res_int)]"
+
+ http-response set-var(proc.ifempty_proc,ifempty) str()
+ http-response set-var(sess.ifempty_sess,ifempty) str()
+ http-response set-var(res.ifempty_res,ifempty) str()
+ http-response set-var(res.ifempty_res_int,ifempty) int(7) # should not work, scalar types are never empty
+
+ http-response set-header x-var2 "proc.ifempty=%[var(proc.ifempty_proc)] sess.ifempty=%[var(sess.ifempty_sess)] res.ifempty=%[var(res.ifempty_res)] res.ifempty_res_int=%[var(res.ifempty_res_int)]"
+
+
+ backend ifnotempty_be
+ server s1 ${s1_addr}:${s1_port}
+ # init
+ http-response set-var(proc.ifnotempty_proc) str(ifnotempty_proc)
+ http-response set-var(sess.ifnotempty_sess) bin(69666e6f74656d7074795f73657373) # "ifnotempty_sess"
+ http-response set-var(res.ifnotempty_res) str(ifnotempty_res)
+ http-response set-var(res.ifnotempty_res_int) int(5)
+
+ http-response set-header x-var-init "proc.ifnotempty=%[var(proc.ifnotempty_proc)] sess.ifnotempty=%[var(sess.ifnotempty_sess)] res.ifnotempty=%[var(res.ifnotempty_res)] res.ifnotempty_res_int=%[var(res.ifnotempty_res_int)]"
+
+ # None of those set-var calls should actually change their respective variables
+ # since none of the samples is not empty
+ http-response set-var(proc.ifnotempty_proc,ifnotempty) str(toto)
+ http-response set-var(sess.ifnotempty_sess,ifnotempty) bin(746F746F) # "toto"
+ http-response set-var(res.ifnotempty_res,ifnotempty) str(tata)
+ http-response set-var(res.ifnotempty_res_int,ifnotempty) int(6)
+
+ http-response set-header x-var1 "proc.ifnotempty=%[var(proc.ifnotempty_proc)] sess.ifnotempty=%[var(sess.ifnotempty_sess)] res.ifnotempty=%[var(res.ifnotempty_res)] res.ifnotempty_res_int=%[var(res.ifnotempty_res_int)]"
+
+ # The first three variables should remain unchanged.
+ http-response set-var(proc.ifnotempty_proc,ifnotempty) str()
+ http-response set-var(sess.ifnotempty_sess,ifnotempty) str()
+ http-response set-var(res.ifnotempty_res,ifnotempty) str()
+ http-response set-var(res.ifnotempty_res_int,ifnotempty) int(7) # should not work
+
+ http-response set-header x-var2 "proc.ifnotempty=%[var(proc.ifnotempty_proc)] sess.ifnotempty=%[var(sess.ifnotempty_sess)] res.ifnotempty=%[var(res.ifnotempty_res)] res.ifnotempty_res_int=%[var(res.ifnotempty_res_int)]"
+
+
+ backend ifset_be
+ server s1 ${s1_addr}:${s1_port}
+ # init
+ http-response set-var(proc.ifset_proc) str(ifset_proc)
+ http-response set-var(sess.ifset_sess) bin(69667365745f73657373) # "ifset_sess"
+ http-response set-var(res.ifset_res) str(ifset_res)
+ http-response set-var(res.ifset_res_int) int(5)
+
+ http-response set-header x-var-init "proc.ifset=%[var(proc.ifset_proc)] sess.ifset=%[var(sess.ifset_sess)] res.ifset=%[var(res.ifset_res)] res.ifset_res_int=%[var(res.ifset_res_int)]"
+
+ # All those set-var calls should succeed
+ http-response set-var(proc.ifset_proc,ifset) str(toto)
+ http-response set-var(sess.ifset_sess,ifset) bin(746F746F) # "toto"
+ http-response set-var(res.ifset_res,ifset) int(123)
+ http-response set-var(res.ifset_res_int,ifset) str(azerty)
+
+ http-response set-header x-var1 "proc.ifset=%[var(proc.ifset_proc)] sess.ifset=%[var(sess.ifset_sess)] res.ifset=%[var(res.ifset_res)] res.ifset_res_int=%[var(res.ifset_res_int)]"
+
+ http-response unset-var(proc.ifset_proc)
+ http-response unset-var(sess.ifset_sess)
+ http-response unset-var(res.ifset_res)
+ http-response unset-var(res.ifset_res_int)
+
+ http-response set-header x-var2 "proc.ifset=%[var(proc.ifset_proc)] sess.ifset=%[var(sess.ifset_sess)] res.ifset=%[var(res.ifset_res)] res.ifset_res_int=%[var(res.ifset_res_int)]"
+
+ # None of those set-var calls should succeed
+ http-response set-var(proc.ifset_proc,ifset) str(toto)
+ http-response set-var(sess.ifset_sess,ifset) bin(746F746F) # "toto"
+ http-response set-var(res.ifset_res,ifset) int(123)
+ http-response set-var(res.ifset_res_int,ifset) str(azerty)
+
+ http-response set-header x-var3 "proc.ifset=%[var(proc.ifset_proc)] sess.ifset=%[var(sess.ifset_sess)] res.ifset=%[var(res.ifset_res)] res.ifset_res_int=%[var(res.ifset_res_int)]"
+
+
+ backend ifnotset_be
+ server s1 ${s1_addr}:${s1_port}
+ # init
+ http-response set-var(proc.ifnotset_proc) str(ifnotset_proc)
+ http-response set-var(sess.ifnotset_sess) bin(69666e6f747365745f73657373) # "ifnotset_sess"
+ http-response set-var(res.ifnotset_res) str(ifnotset_res)
+ http-response set-var(res.ifnotset_res_int) int(5)
+
+ http-response set-header x-var-init "proc.ifnotset=%[var(proc.ifnotset_proc)] sess.ifnotset=%[var(sess.ifnotset_sess)] res.ifnotset=%[var(res.ifnotset_res)] res.ifnotset_res_int=%[var(res.ifnotset_res_int)]"
+
+ # None of those set-var calls should succeed
+ http-response set-var(proc.ifnotset_proc,ifnotset) str(toto)
+ http-response set-var(sess.ifnotset_sess,ifnotset) bin(746F746F) # "toto"
+ http-response set-var(res.ifnotset_res,ifnotset) int(123)
+ http-response set-var(res.ifnotset_res_int,ifnotset) str(azerty)
+
+ http-response set-header x-var1 "proc.ifnotset=%[var(proc.ifnotset_proc)] sess.ifnotset=%[var(sess.ifnotset_sess)] res.ifnotset=%[var(res.ifnotset_res)] res.ifnotset_res_int=%[var(res.ifnotset_res_int)]"
+
+ http-response unset-var(proc.ifnotset_proc)
+ http-response unset-var(sess.ifnotset_sess)
+ http-response unset-var(res.ifnotset_res)
+ http-response unset-var(res.ifnotset_res_int)
+
+ http-response set-header x-var2 "proc.ifnotset=%[var(proc.ifnotset_proc)] sess.ifnotset=%[var(sess.ifnotset_sess)] res.ifnotset=%[var(res.ifnotset_res)] res.ifnotset_res_int=%[var(res.ifnotset_res_int)]"
+
+ # All of those set-var calls should succeed
+ http-response set-var(proc.ifnotset_proc,ifnotset) str(toto)
+ http-response set-var(sess.ifnotset_sess,ifnotset) bin(746F746F) # "toto"
+ http-response set-var(res.ifnotset_res,ifnotset) int(123)
+ http-response set-var(res.ifnotset_res_int,ifnotset) str(azerty)
+
+ http-response set-header x-var3 "proc.ifnotset=%[var(proc.ifnotset_proc)] sess.ifnotset=%[var(sess.ifnotset_sess)] res.ifnotset=%[var(res.ifnotset_res)] res.ifnotset_res_int=%[var(res.ifnotset_res_int)]"
+
+ backend ifgt_be
+ server s1 ${s1_addr}:${s1_port}
+ # init
+ http-response set-var(proc.ifgt_proc) str(ifgt_proc)
+ http-response set-var(sess.ifgt_sess) bin(696667745f73657373) # "ifgt_sess"
+ http-response set-var(res.ifgt_res1) str(ifgt_res)
+ http-response set-var(res.ifgt_res2) int(5)
+ http-response set-var(res.ifgt_res_int1) int(5)
+ http-response set-var(res.ifgt_res_int2) int(5)
+
+ http-response set-header x-var-init "proc.ifgt=%[var(proc.ifgt_proc)] sess.ifgt=%[var(sess.ifgt_sess)] res.ifgt1=%[var(res.ifgt_res1)] res.ifgt2=%[var(res.ifgt_res2)] res.ifgt_res_int1=%[var(res.ifgt_res_int1)] res.ifgt_res_int2=%[var(res.ifgt_res_int2)]"
+
+ # ifgt does not apply on non scalar type so the two following set-var will ignore the condition
+ http-response set-var(proc.ifgt_proc,ifgt) str(toto)
+ http-response set-var(sess.ifgt_sess,ifgt) bin(746F746F) # "toto"
+ # ifgt can only apply when the variable and the sample are both scalar. In this case, the variable was a string so the condition is ignored
+ http-response set-var(res.ifgt_res1,ifgt) int(55)
+ # ifgt can only apply when the variable and the sample are both scalar. In this case, the sample is a string so the condition is ignored
+ http-response set-var(res.ifgt_res2,ifgt) str(text)
+ http-response set-var(res.ifgt_res_int1,ifgt) int(55) # should not work
+ http-response set-var(res.ifgt_res_int2,ifgt) int(2) # should work
+
+ http-response set-header x-var1 "proc.ifgt=%[var(proc.ifgt_proc)] sess.ifgt=%[var(sess.ifgt_sess)] res.ifgt1=%[var(res.ifgt_res1)] res.ifgt2=%[var(res.ifgt_res2)] res.ifgt_res_int1=%[var(res.ifgt_res_int1)] res.ifgt_res_int2=%[var(res.ifgt_res_int2)]"
+
+
+ backend iflt_be
+ server s1 ${s1_addr}:${s1_port}
+ # init
+ http-response set-var(proc.iflt_proc) str(iflt_proc)
+ http-response set-var(sess.iflt_sess) bin(69666c745f73657373) # "iflt_sess"
+ http-response set-var(res.iflt_res1) str(iflt_res)
+ http-response set-var(res.iflt_res2) int(5)
+ http-response set-var(res.iflt_res_int1) int(5)
+ http-response set-var(res.iflt_res_int2) int(5)
+
+ http-response set-header x-var-init "proc.iflt=%[var(proc.iflt_proc)] sess.iflt=%[var(sess.iflt_sess)] res.iflt1=%[var(res.iflt_res1)] res.iflt2=%[var(res.iflt_res2)] res.iflt_res_int1=%[var(res.iflt_res_int1)] res.iflt_res_int2=%[var(res.iflt_res_int2)]"
+
+ # iflt does not apply on non scalar type so the two following set-var will ignore the condition
+ http-response set-var(proc.iflt_proc,iflt) str(toto)
+ http-response set-var(sess.iflt_sess,iflt) bin(746F746F) # "toto"
+ # iflt can only apply when the variable and the sample are both scalar. In this case, the variable was a string so the condition is ignored
+ http-response set-var(res.iflt_res1,iflt) int(55)
+ # iflt can only apply when the variable and the sample are both scalar. In this case, the sample is a string so the condition is ignored
+ http-response set-var(res.iflt_res2,iflt) str(text)
+ http-response set-var(res.iflt_res_int1,iflt) int(55) # should work
+ http-response set-var(res.iflt_res_int2,iflt) int(2) # should not work
+
+ http-response set-header x-var1 "proc.iflt=%[var(proc.iflt_proc)] sess.iflt=%[var(sess.iflt_sess)] res.iflt1=%[var(res.iflt_res1)] res.iflt2=%[var(res.iflt_res2)] res.iflt_res_int1=%[var(res.iflt_res_int1)] res.iflt_res_int2=%[var(res.iflt_res_int2)]"
+
+
+ # Test multiple conditions at once
+ backend combined_be
+ server s1 ${s1_addr}:${s1_port}
+ # init
+ http-response set-var(proc.combined_proc) str(combined_proc)
+ http-response set-var(res.combined_res) int(5)
+ http-response unset-var(proc.combined_proc)
+
+ http-response set-header x-var-init "proc.combined=%[var(proc.combined_proc)] res.combined=%[var(res.combined_res)]"
+
+ http-response set-var(proc.combined_proc,ifnotset,ifnotempty) str(toto)
+ http-response set-var(res.combined_res,ifset,iflt) int(55)
+
+ http-response set-header x-var1 "proc.combined=%[var(proc.combined_proc)] res.combined=%[var(res.combined_res)]"
+
+
+ # Test the set-var converter
+ backend converter_be
+ server s1 ${s1_addr}:${s1_port}
+
+ http-request deny if { req.len,set-var(proc.req_len,ifexists) -m int 0 }
+ http-request deny if { req.hdr("X-Cust"),set-var(sess.x_cust,ifnotempty,ifnotset),length -m int 0 }
+
+ http-response set-header x-var "proc.req_len=%[var(proc.req_len)] sess.x_cust=%[var(sess.x_cust)]"
+
+} -start
+
+
+client c1 -connect ${h1_mainfe_sock} {
+ txreq -url "/ifexists"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var == "proc.ifexists=12 sess.ifexists= res.ifexists="
+} -run
+
+client c2 -connect ${h1_mainfe_sock} {
+ txreq -url "/ifnotexists"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var-init == "proc.ifnotexists= sess.ifnotexists= res.ifnotexists="
+ expect resp.http.x-var == "proc.ifnotexists= sess.ifnotexists=5 res.ifnotexists=toto"
+} -run
+
+client c3 -connect ${h1_mainfe_sock} {
+ txreq -url "/ifempty"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var-init == "proc.ifempty=ifempty_proc sess.ifempty=ifempty_sess res.ifempty=ifempty_res res.ifempty_res_int=5"
+ expect resp.http.x-var1 == "proc.ifempty=ifempty_proc sess.ifempty=ifempty_sess res.ifempty=ifempty_res res.ifempty_res_int=5"
+ expect resp.http.x-var2 == "proc.ifempty= sess.ifempty= res.ifempty= res.ifempty_res_int=5"
+} -run
+
+client c4 -connect ${h1_mainfe_sock} {
+ txreq -url "/ifnotempty"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var-init == "proc.ifnotempty=ifnotempty_proc sess.ifnotempty=ifnotempty_sess res.ifnotempty=ifnotempty_res res.ifnotempty_res_int=5"
+ expect resp.http.x-var1 == "proc.ifnotempty=toto sess.ifnotempty=toto res.ifnotempty=tata res.ifnotempty_res_int=6"
+ expect resp.http.x-var2 == "proc.ifnotempty=toto sess.ifnotempty=toto res.ifnotempty=tata res.ifnotempty_res_int=7"
+} -run
+
+client c5 -connect ${h1_mainfe_sock} {
+ txreq -url "/ifset"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var-init == "proc.ifset=ifset_proc sess.ifset=ifset_sess res.ifset=ifset_res res.ifset_res_int=5"
+ expect resp.http.x-var1 == "proc.ifset=toto sess.ifset=toto res.ifset=123 res.ifset_res_int=azerty"
+ expect resp.http.x-var2 == "proc.ifset= sess.ifset= res.ifset= res.ifset_res_int="
+ expect resp.http.x-var3 == "proc.ifset= sess.ifset= res.ifset= res.ifset_res_int="
+} -run
+
+client c6 -connect ${h1_mainfe_sock} {
+ txreq -url "/ifnotset"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var-init == "proc.ifnotset=ifnotset_proc sess.ifnotset=ifnotset_sess res.ifnotset=ifnotset_res res.ifnotset_res_int=5"
+ expect resp.http.x-var1 == "proc.ifnotset=ifnotset_proc sess.ifnotset=ifnotset_sess res.ifnotset=ifnotset_res res.ifnotset_res_int=5"
+ expect resp.http.x-var2 == "proc.ifnotset= sess.ifnotset= res.ifnotset= res.ifnotset_res_int="
+ expect resp.http.x-var3 == "proc.ifnotset=toto sess.ifnotset=toto res.ifnotset=123 res.ifnotset_res_int=azerty"
+} -run
+
+client c7 -connect ${h1_mainfe_sock} {
+ txreq -url "/ifgt"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var-init == "proc.ifgt=ifgt_proc sess.ifgt=ifgt_sess res.ifgt1=ifgt_res res.ifgt2=5 res.ifgt_res_int1=5 res.ifgt_res_int2=5"
+ expect resp.http.x-var1 == "proc.ifgt=toto sess.ifgt=toto res.ifgt1=55 res.ifgt2=text res.ifgt_res_int1=5 res.ifgt_res_int2=2"
+} -run
+
+client c8 -connect ${h1_mainfe_sock} {
+ txreq -url "/iflt"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var-init == "proc.iflt=iflt_proc sess.iflt=iflt_sess res.iflt1=iflt_res res.iflt2=5 res.iflt_res_int1=5 res.iflt_res_int2=5"
+ expect resp.http.x-var1 == "proc.iflt=toto sess.iflt=toto res.iflt1=55 res.iflt2=text res.iflt_res_int1=55 res.iflt_res_int2=5"
+} -run
+
+client c9 -connect ${h1_mainfe_sock} {
+ txreq -url "/combined"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var-init == "proc.combined= res.combined=5"
+ expect resp.http.x-var1 == "proc.combined=toto res.combined=55"
+} -run
+
+client c10 -connect ${h1_mainfe_sock} {
+ txreq -url "/converter" -hdr "X-Cust: foobar"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-var == "proc.req_len=67 sess.x_cust=foobar"
+} -run
diff --git a/reg-tests/sample_fetches/cook.vtc b/reg-tests/sample_fetches/cook.vtc
new file mode 100644
index 0000000..e2c1284
--- /dev/null
+++ b/reg-tests/sample_fetches/cook.vtc
@@ -0,0 +1,37 @@
+varnishtest "cook sample fetch Test"
+
+feature ignore_unknown_macro
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+haproxy h1 -conf {
+ defaults
+ mode http
+
+ frontend fe
+ bind "fd@${fe}"
+ http-request set-var(txn.count) req.cook_cnt()
+ http-request set-var(txn.val) req.cook_val()
+ http-request set-var(txn.val_cook2) req.cook_val(cook2)
+ http-response set-header count %[var(txn.count)]
+ http-response set-header val %[var(txn.val)]
+ http-response set-header val_cook2 %[var(txn.val_cook2)]
+
+ default_backend be
+
+ backend be
+ server srv1 ${s1_addr}:${s1_port}
+} -start
+
+client c1 -connect ${h1_fe_sock} {
+ txreq -url "/" \
+ -hdr "cookie: cook1=0; cook2=123; cook3=22"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.count == "3"
+ expect resp.http.val == "0"
+ expect resp.http.val_cook2 == "123"
+} -run
diff --git a/reg-tests/sample_fetches/hashes.vtc b/reg-tests/sample_fetches/hashes.vtc
new file mode 100644
index 0000000..2c2f60d
--- /dev/null
+++ b/reg-tests/sample_fetches/hashes.vtc
@@ -0,0 +1,101 @@
+varnishtest "Hash validity test"
+
+#REQUIRE_VERSION=2.4
+
+feature ignore_unknown_macro
+
+server s1 {
+ rxreq
+ 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}"
+
+ frontend fe
+ bind "fd@${fe}"
+
+ # base64 encoding of \x00\x01\x02...\xFF
+ http-response set-var(res.key) "str(AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==),b64dec"
+
+ # length (start:0, next:255)
+ http-response set-header x-len0 "%[var(res.key),length]"
+ http-response set-header x-len1 "%[var(res.key),bytes(1),length]"
+
+ # text-based encoding
+ http-response set-header x-hex "%[var(res.key),hex]"
+ http-response set-header x-b64 "%[var(res.key),base64]"
+
+ # SHA family
+ http-response set-header x-sha1 "%[var(res.key),sha1,hex]"
+ #http-response set-header x-sha2 "%[var(res.key),sha2,hex]"
+ #http-response set-header x-sha2-224 "%[var(res.key),sha2(224),hex]"
+ #http-response set-header x-sha2-256 "%[var(res.key),sha2(256),hex]"
+ #http-response set-header x-sha2-384 "%[var(res.key),sha2(384),hex]"
+ #http-response set-header x-sha2-512 "%[var(res.key),sha2(512),hex]"
+
+ # 32-bit hashes, and their avalanche variants
+ http-response set-header x-crc32 "%[var(res.key),crc32]"
+ http-response set-header x-crc32-1 "%[var(res.key),crc32(1)]"
+
+ http-response set-header x-crc32c "%[var(res.key),crc32c]"
+ http-response set-header x-crc32c-1 "%[var(res.key),crc32c(1)]"
+
+ http-response set-header x-djb2 "%[var(res.key),djb2]"
+ http-response set-header x-djb2-1 "%[var(res.key),djb2(1)]"
+
+ http-response set-header x-sdbm "%[var(res.key),sdbm]"
+ http-response set-header x-sdbm-1 "%[var(res.key),sdbm(1)]"
+
+ http-response set-header x-wt6 "%[var(res.key),wt6]"
+ http-response set-header x-wt6-1 "%[var(res.key),wt6(1)]"
+
+ # 32/64-bit hashes, with seed variant
+ http-response set-header x-xxh3 "%[var(res.key),xxh3]"
+ http-response set-header x-xxh3-1 "%[var(res.key),xxh3(1)]"
+ http-response set-header x-xxh32 "%[var(res.key),xxh32]"
+ http-response set-header x-xxh32-1 "%[var(res.key),xxh32(1)]"
+ http-response set-header x-xxh64 "%[var(res.key),xxh64]"
+ http-response set-header x-xxh64-1 "%[var(res.key),xxh64(1)]"
+ default_backend be
+
+ backend be
+ server srv1 ${s1_addr}:${s1_port}
+} -start
+
+client c1 -connect ${h1_fe_sock} {
+ txreq -url "/"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-len0 == "0"
+ expect resp.http.x-len1 == "255"
+ expect resp.http.x-hex == "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"
+ expect resp.http.x-b64 == "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="
+
+ expect resp.http.x-sha1 == "4916D6BDB7F78E6803698CAB32D1586EA457DFC8"
+ #expect resp.http.x-sha2 == "40AFF2E9D2D8922E47AFD4648E6967497158785FBD1DA870E7110266BF944880"
+ #expect resp.http.x-sha2-224 == "88702E63237824C4EB0D0FCFE41469A462493E8BEB2A75BBE5981734"
+ #expect resp.http.x-sha2-256 == "40AFF2E9D2D8922E47AFD4648E6967497158785FBD1DA870E7110266BF944880"
+ #expect resp.http.x-sha2-384 == "FFDAEBFF65ED05CF400F0221C4CCFB4B2104FB6A51F87E40BE6C4309386BFDEC2892E9179B34632331A59592737DB5C5"
+ #expect resp.http.x-sha2-512 == "1E7B80BC8EDC552C8FEEB2780E111477E5BC70465FAC1A77B29B35980C3F0CE4A036A6C9462036824BD56801E62AF7E9FEBA5C22ED8A5AF877BF7DE117DCAC6D"
+ expect resp.http.x-crc32 == "688229491"
+ expect resp.http.x-crc32-1 == "4230317029"
+ expect resp.http.x-crc32c == "2621708363"
+ expect resp.http.x-crc32c-1 == "2242979626"
+ expect resp.http.x-djb2 == "2589693061"
+ expect resp.http.x-djb2-1 == "600622701"
+ expect resp.http.x-sdbm == "905707648"
+ expect resp.http.x-sdbm-1 == "3103804144"
+ expect resp.http.x-wt6 == "4090277559"
+ expect resp.http.x-wt6-1 == "1192658767"
+ expect resp.http.x-xxh3 == "-7779787747613135503"
+ expect resp.http.x-xxh3-1 == "5930632130106562027"
+ expect resp.http.x-xxh32 == "1497633363"
+ expect resp.http.x-xxh32-1 == "1070421674"
+ expect resp.http.x-xxh64 == "2282408585429094475"
+ expect resp.http.x-xxh64-1 == "-4689339368900765961"
+} -run
diff --git a/reg-tests/sample_fetches/so_name.vtc b/reg-tests/sample_fetches/so_name.vtc
new file mode 100644
index 0000000..c6211fa
--- /dev/null
+++ b/reg-tests/sample_fetches/so_name.vtc
@@ -0,0 +1,22 @@
+varnishtest "so_name sample fetche Test"
+
+#REQUIRE_VERSION=2.2
+
+feature ignore_unknown_macro
+
+haproxy h1 -conf {
+ defaults
+ mode http
+
+ frontend fe
+ bind "fd@${fe}" name foo
+ http-request return status 200 hdr so-name %[so_name]
+
+} -start
+
+client c1 -connect ${h1_fe_sock} {
+ txreq -url "/"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.so-name == "foo"
+} -run
diff --git a/reg-tests/sample_fetches/srv_name.vtc b/reg-tests/sample_fetches/srv_name.vtc
new file mode 100644
index 0000000..900957e
--- /dev/null
+++ b/reg-tests/sample_fetches/srv_name.vtc
@@ -0,0 +1,46 @@
+varnishtest "srv_name sample fetche Test"
+
+#REQUIRE_VERSION=2.1
+
+feature ignore_unknown_macro
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+server s2 {
+ rxreq
+ 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}"
+
+ frontend fe
+ bind "fd@${fe}"
+ http-response set-header srv-id "%[srv_id]"
+ http-response set-header srv-name "%[srv_name]"
+ default_backend be
+
+ backend be
+ server srv1 ${s1_addr}:${s1_port}
+ server srv2 ${s2_addr}:${s2_port}
+} -start
+
+client c1 -connect ${h1_fe_sock} {
+ txreq -url "/"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.srv-id == "1"
+ expect resp.http.srv-name == "srv1"
+ txreq -url "/"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.srv-id == "2"
+ expect resp.http.srv-name == "srv2"
+} -run
diff --git a/reg-tests/sample_fetches/ubase64.vtc b/reg-tests/sample_fetches/ubase64.vtc
new file mode 100644
index 0000000..8e47d86
--- /dev/null
+++ b/reg-tests/sample_fetches/ubase64.vtc
@@ -0,0 +1,57 @@
+varnishtest "ub64dec sample fetche Test"
+
+#REQUIRE_VERSION=2.4
+
+feature ignore_unknown_macro
+
+haproxy h1 -conf {
+ global
+ # WT: limit false-positives causing "HTTP header incomplete" due to
+ # idle server connections being randomly used and randomly expiring
+ # under us.
+ tune.idle-pool.shared off
+
+ defaults
+ mode http
+ timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
+
+ frontend fe
+ bind "fd@${fe}"
+ acl input hdr(encode) -m found
+ http-request return content-type text/plain hdr encode %[hdr(encode),ub64enc] hdr decode %[hdr(decode),ub64dec] if input
+ http-request return content-type text/plain hdr encode %[bin(14fb9c03d97f12d97e),ub64enc] hdr decode %[str(FPucA9l_Etl-),ub64dec,hex,lower] if !input
+
+} -start
+
+client c1 -connect ${h1_fe_sock} {
+ txreq -hdr "encode: f" -hdr "decode: Zg"
+ rxresp
+ expect resp.http.encode == "Zg"
+ expect resp.http.decode == "f"
+ txreq -hdr "encode: fo" -hdr "decode: Zm8"
+ rxresp
+ expect resp.http.encode == "Zm8"
+ expect resp.http.decode == "fo"
+ txreq -hdr "encode: foo" -hdr "decode: Zm9v"
+ rxresp
+ expect resp.http.encode == "Zm9v"
+ expect resp.http.decode == "foo"
+ txreq -hdr "encode: foob" -hdr "decode: Zm9vYg"
+ rxresp
+ expect resp.http.encode == "Zm9vYg"
+ expect resp.http.decode == "foob"
+ txreq -hdr "encode: fooba" -hdr "decode: Zm9vYmE"
+ rxresp
+ expect resp.http.encode == "Zm9vYmE"
+ expect resp.http.decode == "fooba"
+ txreq -hdr "encode: foobar" -hdr "decode: Zm9vYmFy"
+ rxresp
+ expect resp.http.encode == "Zm9vYmFy"
+ expect resp.http.decode == "foobar"
+ txreq
+ rxresp
+ expect resp.http.encode == "FPucA9l_Etl-"
+ expect resp.http.decode == "14fb9c03d97f12d97e"
+} -run
diff --git a/reg-tests/sample_fetches/vars.vtc b/reg-tests/sample_fetches/vars.vtc
new file mode 100644
index 0000000..5144e9f
--- /dev/null
+++ b/reg-tests/sample_fetches/vars.vtc
@@ -0,0 +1,84 @@
+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 "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
+
+ 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