From: Christopher Faulet Date: Fri, 2 Oct 2026 19:18:00 +0000 (+0200) Subject: REGTESTS: filters: Exercise Lua filters across HTTP retries X-Git-Tag: v3.5-dev9~60 X-Git-Url: https://git.kaiwu.me/$%7BISSUES%7D/static/gitweb.js?a=commitdiff_plain;h=5b4ec1ab604cce5ce3d100766bcc7ffd81a5577c;p=haproxy.git REGTESTS: filters: Exercise Lua filters across HTTP retries Retry a 503 response and redispatch to a second server. Check that both servers receive the same request header order and instance identifiers, without another attachment or duplicate request processing. Verify that the failed response does not leak headers into the final response, and that its filter order and instances still follow the frontend/backend response sequences. Include a waiting frontend filter. --- diff --git a/reg-tests/filters/lua-retry.vtc b/reg-tests/filters/lua-retry.vtc new file mode 100644 index 000000000..afc5b6f83 --- /dev/null +++ b/reg-tests/filters/lua-retry.vtc @@ -0,0 +1,74 @@ +varnishtest "HTTP retries reuse Lua filter instances and do not duplicate callbacks" + +feature cmd "$HAPROXY_PROGRAM -cc 'feature(LUA)'" +feature ignore_unknown_macro + +barrier b_retry cond 2 +barrier b_drained cond 2 + +server s1 { + rxreq + expect req.http.x-probe-order == "F.a;F.b;B.c;B.a;" + expect req.http.x-probe-instances == "F.a:2;F.b:1;B.c:1;B.a:2;" + expect req.http.x-probe-errors == + txresp -status 503 -hdr "X-Probe-Order: failed-response;" -body "retry me" + # Hold the first connection open until redispatch has completed too. + barrier b_retry sync +} -start + +server s2 { + rxreq + expect req.http.x-probe-order == "F.a;F.b;B.c;B.a;" + expect req.http.x-probe-instances == "F.a:2;F.b:1;B.c:1;B.a:2;" + expect req.http.x-probe-errors == + barrier b_retry sync + txresp -body "successful retry" + # Do not mix retry assertions with the separate WAIT/backend-EOF race. + barrier b_drained sync +} -start + +haproxy h1 -conf { + global + nbthread 1 + tune.lua.bool-sample-conversion normal + lua-load "${testdir}/lua-probe.lua" + 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}" + filter-config lua id probe-a enabled F a + filter-config lua id probe-b enabled F b wait + filter-sequence global lua/probe-b:before(lua/probe-a) + filter-sequence response lua/probe-b:before(lua/probe-a) + http-after-response set-header x-retries "%[txn.conn_retries]" + http-after-response set-header x-redispatched "%[txn.redispatched]" + default_backend be + backend be + balance first + retries 1 + retry-on 503 + option redispatch + filter-config lua id probe-a enabled B a + filter-config lua id probe-c enabled B c + filter-sequence global lua/probe-c:before(lua/probe-a) + filter-sequence request lua/probe-c:before(lua/probe-a) + filter-sequence response lua/probe-a:before(lua/probe-c) + server bad ${s1_addr}:${s1_port} + server good ${s2_addr}:${s2_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-retries == "1" + expect resp.http.x-redispatched == "1" + expect resp.http.x-probe-order == "F.b;F.a;B.a;B.c;" + expect resp.http.x-probe-instances == "F.b:1;F.a:2;B.a:2;B.c:1;" + expect resp.http.x-probe-errors == + expect resp.body == "successful retry" + barrier b_drained sync +} -run