From: Willy Tarreau Date: Mon, 21 Sep 2026 20:34:20 +0000 (+0000) Subject: REGTESTS: http-rules: test the binary header manipulation actions X-Git-Tag: v3.5-dev8~60 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=4c3e22e485c3ab147d4a6ff8fa30942f51ef8ebd;p=haproxy.git REGTESTS: http-rules: test the binary header manipulation actions The add-headers-bin, set-headers-bin and del-headers-bin actions had no coverage at all. The test saves the incoming header block with req.hdrs_bin, drops a few headers and restores them from the saved block, with and without the "prefix" filter, and checks on the server side which headers made it through. The lists passed to del-headers-bin are built by hand with the bin() fetch so that the varint encoding of the header names is exercised too, with the default exact matching and with the "beg" one. --- diff --git a/reg-tests/http-rules/headers_bin.vtc b/reg-tests/http-rules/headers_bin.vtc new file mode 100644 index 000000000..01a851307 --- /dev/null +++ b/reg-tests/http-rules/headers_bin.vtc @@ -0,0 +1,104 @@ +varnishtest "Test the binary header manipulation actions" + +# The add-headers-bin, set-headers-bin and del-headers-bin actions had no +# coverage at all. They take a varint encoded list of header names and +# values, which is exactly what the req.hdrs_bin fetch produces, so the +# test saves the incoming header block, drops some headers and restores +# them from the saved block, with and without the "prefix" filter. +# +# The lists passed to del-headers-bin are built by hand with the bin() +# fetch: a varint length followed by the bytes, one pair per entry, the +# list being terminated by two empty strings. For instance +# 03 "x-a" 00 00 00 designates the single header name "x-a". + +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.url == "/prefix" + expect req.http.x-a == "" + expect req.http.x-b == "2" + expect req.http.x-c == "" + txresp + + rxreq + expect req.url == "/all" + expect req.http.x-a == "1" + expect req.http.x-b == "2" + expect req.http.x-c == "3" + txresp + + rxreq + expect req.url == "/del" + expect req.http.x-a == "" + expect req.http.x-b == "2" + expect req.http.x-c == "3" + txresp + + rxreq + expect req.url == "/delbeg" + expect req.http.x-a == "" + expect req.http.x-b == "" + expect req.http.x-c == "" + txresp +} -start + +haproxy h1 -conf { + global + .if feature(THREAD) + thread-groups 1 + .endif + chroot / + + 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-request set-var(txn.hdrs) req.hdrs_bin + + http-request del-header x-a if { path /prefix } || { path /all } + http-request del-header x-b if { path /prefix } || { path /all } + http-request del-header x-c if { path /prefix } || { path /all } + + # only the headers whose name starts with the prefix are restored + http-request add-headers-bin var(txn.hdrs) prefix x-b if { path /prefix } + http-request set-headers-bin var(txn.hdrs) if { path /all } + + # 03 "x-a" 00 00 00 : one entry named "x-a" with an empty value + http-request del-headers-bin bin(03782d61000000) if { path /del } + # 02 "x-" 00 00 00 with a prefix match removes all the x-* headers + http-request del-headers-bin bin(02782d000000) -m beg if { path /delbeg } + + # the response side accepts the same actions + http-after-response set-headers-bin var(txn.hdrs) prefix x-c + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/prefix" -hdr "x-a: 1" -hdr "x-b: 2" -hdr "x-c: 3" + rxresp + expect resp.status == 200 + # the response got the x-c header back from the saved request block + expect resp.http.x-c == "3" + + txreq -url "/all" -hdr "x-a: 1" -hdr "x-b: 2" -hdr "x-c: 3" + rxresp + expect resp.status == 200 + + txreq -url "/del" -hdr "x-a: 1" -hdr "x-b: 2" -hdr "x-c: 3" + rxresp + expect resp.status == 200 + + txreq -url "/delbeg" -hdr "x-a: 1" -hdr "x-b: 2" -hdr "x-c: 3" + rxresp + expect resp.status == 200 +} -run