From 16f255257f7dc4db5ad5eee37fa4b69ed2d40a64 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Tue, 21 Nov 2023 07:12:11 +0100 Subject: [PATCH] req_fsm: Ensure failed sub-requests reach transmit A VCL failure on the client side transitions to vcl_synth, except failures from vcl_synth that lead to minimal errors. The ESI transport is not allowed to reply with minimal responses so this would lead to a panic. On top of that, the vcl_req_reset feature flag emulates `return (fail)` statements when an HTTP/2 client disconnected, resulting in the same panic scenario. For sub-requests, we masquerade the fail transition as a deliver and trade the illegal minimal response for the synthetic response. Fixes #4022 --- bin/varnishd/cache/cache_req_fsm.c | 6 +++++- bin/varnishtest/tests/e00037.vtc | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 bin/varnishtest/tests/e00037.vtc diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 789cea5408a..c0508cd4c9c 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -333,7 +333,11 @@ cnt_synth(struct worker *wrk, struct req *req) VSLb_ts_req(req, "Process", W_TIM_real(wrk)); - if (wrk->vpi->handling == VCL_RET_FAIL) { + while (wrk->vpi->handling == VCL_RET_FAIL) { + if (req->esi_level > 0) { + wrk->vpi->handling = VCL_RET_DELIVER; + break; + } VSB_destroy(&synth_body); (void)VRB_Ignore(req); (void)req->transport->minimal_response(req, 500); diff --git a/bin/varnishtest/tests/e00037.vtc b/bin/varnishtest/tests/e00037.vtc new file mode 100644 index 00000000000..bfb1354e538 --- /dev/null +++ b/bin/varnishtest/tests/e00037.vtc @@ -0,0 +1,28 @@ +varnishtest "Double fail ESI sub request" + +server s1 { + rxreq + txresp -body {} +} -start + +varnish v1 -vcl+backend { + sub vcl_backend_response { + set beresp.do_esi = true; + } + + sub vcl_recv { + if (req.esi_level > 0) { + return (fail); + } + } + + sub vcl_synth { + return (fail); + } +} -start + +client c1 { + non_fatal + txreq + rxresp +} -run