[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