[master] a4c8ffa Enable VCL switching from VCL

Poul-Henning Kamp phk at FreeBSD.org
Tue Aug 16 11:20:16 CEST 2016


commit a4c8ffa4bc15d4d3fb12c9ef7475c1458115a259
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Aug 16 09:19:24 2016 +0000

    Enable VCL switching from VCL

diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index fa9d8f6..e7fec41 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -688,6 +688,8 @@ cnt_recv(struct worker *wrk, struct req *req)
 	}
 
 	VCL_recv_method(req->vcl, wrk, req, NULL, NULL);
+	if (wrk->handling == VCL_RET_VCL)
+		VCL_recv_method(req->vcl, wrk, req, NULL, NULL);
 
 	/* Attempts to cache req.body may fail */
 	if (req->req_body_status == REQ_BODY_FAIL) {
@@ -714,6 +716,12 @@ cnt_recv(struct worker *wrk, struct req *req)
 	SHA256_Final(req->digest, &sha256ctx);
 
 	switch(recv_handling) {
+	case VCL_RET_VCL:
+		VSLb(req->vsl, SLT_VCL_Error,
+		    "return(vcl) only allowed from active (top) VCL.");
+		req->err_code = 503;
+		req->req_step = R_STP_SYNTH;
+		return (REQ_FSM_MORE);
 	case VCL_RET_PURGE:
 		req->req_step = R_STP_PURGE;
 		return (REQ_FSM_MORE);
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index edba7b0..5afc65a 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -453,6 +453,8 @@ VRT_vcl_select(VRT_CTX, VCL_VCL vcl)
 	CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC);
 	VCL_Rel(&req->vcl);
 	vcl_get(&req->vcl, vcl);
+	/* XXX: better logging */
+	VSLb(ctx->req->vsl, SLT_Debug, "Now using %s VCL", vcl->loaded_name);
 }
 
 struct vclref *
diff --git a/bin/varnishtest/tests/c00077.vtc b/bin/varnishtest/tests/c00077.vtc
new file mode 100644
index 0000000..005a17d
--- /dev/null
+++ b/bin/varnishtest/tests/c00077.vtc
@@ -0,0 +1,71 @@
+varnishtest "Switching VCL from VCL"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_deliver {
+		set resp.http.vcl = "vclA";
+	}
+} -start
+
+varnish v1 -clierr 106 "vcl.label vcl.A vcl1"
+varnish v1 -cliok "vcl.label vclA vcl1"
+
+varnish v1 -vcl+backend {
+	sub vcl_recv {
+		if (req.http.vcl == "vcl1") {
+			return (vcl(vclA));
+		}
+	}
+	sub vcl_deliver {
+		set resp.http.vcl = "vcl2";
+	}
+}
+varnish v1 -cliok "vcl.label vclB vcl2"
+varnish v1 -cliok "vcl.list"
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.http.vcl == vcl2
+
+	txreq -hdr "vcl: vcl1"
+	rxresp
+	expect resp.http.vcl == vclA
+} -run
+
+varnish v1 -clierr 106 "vcl.discard vcl1"
+
+varnish v1 -vcl+backend { sub vcl_recv { return (vcl(vclB)); } }
+
+client c1 {
+	txreq -hdr "vcl: vcl1"
+	rxresp
+	expect resp.status == 503
+} -run
+
+delay .2
+
+varnish v1 -vcl+backend { sub vcl_recv { return (vcl(vclA)); } }
+varnish v1 -vcl+backend { sub vcl_recv { return (vcl(vclA)); } }
+varnish v1 -vcl+backend { sub vcl_recv { return (vcl(vclA)); } }
+varnish v1 -vcl+backend { sub vcl_recv { return (vcl(vclA)); } }
+
+varnish v1 -clierr 106 "vcl.discard vclA"
+
+varnish v1 -vcl+backend { }
+varnish v1 -cliok "vcl.discard vcl3"
+varnish v1 -cliok "vcl.discard vcl4"
+varnish v1 -cliok "vcl.discard vcl5"
+varnish v1 -cliok "vcl.discard vcl6"
+varnish v1 -cliok "vcl.discard vcl7"
+
+varnish v1 -cliok "vcl.discard vclB"
+varnish v1 -cliok "vcl.discard vcl2"
+varnish v1 -cliok "vcl.discard vclA"
+varnish v1 -cliok "vcl.discard vcl1"
+
+
diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py
index d5b5f00..a34d1e3 100755
--- a/lib/libvcc/generate.py
+++ b/lib/libvcc/generate.py
@@ -85,7 +85,7 @@ returns = (
 
 	('recv',
 		"C",
-		('synth', 'pass', 'pipe', 'hash', 'purge',)
+		('synth', 'pass', 'pipe', 'hash', 'purge', 'vcl')
 	),
 	('pipe',
 		"C",



More information about the varnish-commit mailing list