[master] f1392d0fa Error handling for out-of-workspace VDP_Push during ESI processing

Nils Goroll nils.goroll at uplex.de
Wed Apr 1 08:25:07 UTC 2020


commit f1392d0faded9a10a61b948e3cdff8063fb3b59d
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Tue Mar 3 15:52:34 2020 +0100

    Error handling for out-of-workspace VDP_Push during ESI processing
    
    As with any other out-of-workspace condition during ESI processing, we
    do not have any better way than to deliver an incomplete response
    (missing ESI include).
    
    Or do we?
    
    Fixes #3241

diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c
index e8d51637f..b4b30fa3f 100644
--- a/bin/varnishd/cache/cache_esi_deliver.c
+++ b/bin/varnishd/cache/cache_esi_deliver.c
@@ -835,16 +835,28 @@ ved_deliver(struct req *req, struct boc *boc, int wantbody)
 
 		INIT_OBJ(foo, VED_FOO_MAGIC);
 		foo->ecx = ecx;
-		XXXAZ(VDP_Push(req, &ved_gzgz, foo));
+		i = VDP_Push(req, &ved_gzgz, foo);
 
 	} else if (ecx->isgzip && !i) {
 		/* Non-Gzip'ed include in gzip'ed parent */
-		XXXAZ(VDP_Push(req, &ved_pretend_gz, ecx));
+		i = VDP_Push(req, &ved_pretend_gz, ecx);
 	} else {
 		/* Anything else goes straight through */
-		XXXAZ(VDP_Push(req, &ved_ved, ecx));
+		i = VDP_Push(req, &ved_ved, ecx);
 	}
-	(void)VDP_DeliverObj(req);
-	(void)VDP_bytes(req, VDP_FLUSH, NULL, 0);
+
+	if (i == 0) {
+		i = VDP_DeliverObj(req);
+	} else {
+		VSLb(req->vsl, SLT_Error, "Failure to push ESI processors");
+		req->doclose = SC_OVERLOAD;
+	}
+
+	if (i == 0)
+		i = VDP_bytes(req, VDP_FLUSH, NULL, 0);
+
+	if (i && req->doclose == SC_NULL)
+		req->doclose = SC_REM_CLOSE;
+
 	VDP_close(req);
 }
diff --git a/bin/varnishtest/tests/r03241.vtc b/bin/varnishtest/tests/r03241.vtc
new file mode 100644
index 000000000..ac7fab446
--- /dev/null
+++ b/bin/varnishtest/tests/r03241.vtc
@@ -0,0 +1,56 @@
+varnishtest "ESI include out of workspace"
+
+
+server s1 {
+	rxreq
+	expect req.http.esi0 == "foo"
+	txresp -body {
+		<html>
+		Before include
+		<esi:include src="/body" sr="foo"/>
+		After include
+		</html>
+	}
+	rxreq
+	expect req.url == "/body1"
+	expect req.http.esi0 != "foo"
+	txresp -body {
+		Included file
+	}
+} -start
+
+varnish v1 -vcl+backend {
+	import vtc;
+
+	sub vcl_recv {
+		if (req.esi_level > 0) {
+			set req.url = req.url + req.esi_level;
+		} else {
+			set req.http.esi0 = "foo";
+		}
+	}
+	sub vcl_backend_response {
+		if (bereq.url == "/") {
+			set beresp.do_esi = true;
+		}
+	}
+	sub vcl_deliver {
+		if (req.esi_level > 0) {
+			vtc.workspace_alloc(client, -16);
+		}
+	}
+} -start
+
+logexpect l1 -v v1 -g raw {
+	expect * * Error           "^Failure to push ESI processors"
+} -start
+
+client c1 {
+	txreq -hdr "Host: foo"
+	rxresp
+	# XXX this is actually wrong (missed include)
+	expect resp.bodylen == 57
+	expect resp.status == 200
+}  -run
+
+logexpect l1 -wait


More information about the varnish-commit mailing list