[master] 7de4ae97e outlaw std.rollback(req) in vcl_pipe {}

Nils Goroll nils.goroll at uplex.de
Mon Jan 11 14:26:03 UTC 2021


commit 7de4ae97e18ba2f31f7d6a24c1194746e6834e5e
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Fri Nov 27 18:28:47 2020 +0100

    outlaw std.rollback(req) in vcl_pipe {}
    
    With the previous commits, as the bereq uses the req workspace, we
    cannot roll back the req without also rolling back the bereq.
    
    As the use case is rather exotic, we spare the additional complications
    and just outlaw rollbacks from vcl_pipe.
    
    std.rollback(bereq) is already forbidden by the compiler because the
    bereq symbol is not available in vcl_pipe {}.
    
    We could, alternative to the runtime failure for std.rollback(req),
    remove the req symbol from vcl_pipe {}, but that could break use of req
    to vmod functions also. So we chose the more compatible route of
    selectively failing rollback rather than making impossible other use
    cases.

diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index 327a651f1..67abc24b2 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -795,6 +795,10 @@ VRT_Rollback(VRT_CTX, VCL_HTTP hp)
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+	if (ctx->method & VCL_MET_PIPE) {
+		VRT_fail(ctx, "Cannot rollback in vcl_pipe {}");
+		return;
+	}
 	if (hp == ctx->http_req) {
 		CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
 		Req_Rollback(ctx->req);
diff --git a/bin/varnishtest/tests/m00017.vtc b/bin/varnishtest/tests/m00017.vtc
index 78e3bdcbc..012e92989 100644
--- a/bin/varnishtest/tests/m00017.vtc
+++ b/bin/varnishtest/tests/m00017.vtc
@@ -3,6 +3,8 @@ varnishtest "Test std.rollback"
 # bug regressions:
 # - #3009
 # - #3083
+# - #3329
+# - #3385
 
 server s1 {
 	rxreq
@@ -335,3 +337,40 @@ client c6 {
 } -run
 
 server s1 -wait
+
+# this could work, but would need additional coding to save
+# the right snapshot of the bereq on the req ws
+varnish v1 -errvcl {Not available in subroutine 'vcl_pipe'} {
+	import std;
+
+	backend proforma None;
+
+	sub vcl_pipe {
+		std.rollback(bereq);
+	}
+}
+
+# vcl_pipe { std.rollback(req); } cannot work unless it also implied
+# rolling back the bereq first.
+# We would want to remove req from vcl_pipe, but that could break
+# vmods, so we fail specifically at runtime
+
+varnish v1 -vcl {
+	import std;
+
+	backend proforma None;
+
+	sub vcl_recv {
+		return (pipe);
+	}
+	sub vcl_pipe {
+		std.rollback(req);
+	}
+}
+
+client c7 {
+	txreq -url /
+	rxresp
+	expect resp.status == 503
+	expect resp.reason == "VCL failed"
+} -run


More information about the varnish-commit mailing list