Skip to content

Commit

Permalink
req_fsm: Ensure failed sub-requests reach transmit
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dridi committed Nov 21, 2023
1 parent 23d62d2 commit 16f2552
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
6 changes: 5 additions & 1 deletion bin/varnishd/cache/cache_req_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
28 changes: 28 additions & 0 deletions bin/varnishtest/tests/e00037.vtc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
varnishtest "Double fail ESI sub request"

server s1 {
rxreq
txresp -body {<esi:include src="/inc"/>}
} -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

0 comments on commit 16f2552

Please sign in to comment.