[master] a80d03629 some beresp.do_* flags are undefined after setting beresp.filters

Nils Goroll nils.goroll at uplex.de
Sun Apr 5 14:16:08 UTC 2020


commit a80d03629c96338ed6e51ca9071820b9f5e55a3d
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Sun Apr 5 16:02:09 2020 +0200

    some beresp.do_* flags are undefined after setting beresp.filters
    
    See previous commit: Analogous to resp.do_esi, any access to the
    beresp.do_* flags which influence beresp.filters is now a VCL error.
    
    Ref #3002

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 9cb57970c..c8ad67d1c 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -411,7 +411,7 @@ struct busyobj {
 
 	struct pool_task	fetch_task[1];
 
-#define BO_FLAG(l, r, w, d) unsigned	l:1;
+#define BO_FLAG(l, r, w, f, d) unsigned	l:1;
 #include "tbl/bo_flags.h"
 
 	/* Timeouts */
diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index 48d6c7618..45a162bcb 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -441,7 +441,7 @@ pan_busyobj(struct vsb *vsb, const struct busyobj *bo)
 	VSB_cat(vsb, "flags = {");
 	p = "";
 /*lint -save -esym(438,p) -e539 */
-#define BO_FLAG(l, r, w, d) \
+#define BO_FLAG(l, r, w, f, d)					\
 	if (bo->l) { VSB_printf(vsb, "%s" #l, p); p = ", "; }
 #include "tbl/bo_flags.h"
 /*lint -restore */
diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index 8782df08d..1f3138e1c 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -186,31 +186,63 @@ VRT_r_obj_reason(VRT_CTX)
  * bool-fields (.do_*)
  */
 
-#define VBERESPW0(field)
-#define VBERESPW1(field)						\
+static inline int
+beresp_filter_fixed(VRT_CTX, const char *s)
+{
+	if (ctx->bo->filter_list == NULL)
+		return (0);
+	VRT_fail(ctx, "beresp.filters are already fixed, beresp.%s is undefined", s);
+	return (1);
+}
+
+#define VBERESPWF0(ctx, str) (void) 0
+#define VBERESPWF1(ctx, str) do {		\
+	if (beresp_filter_fixed((ctx), str))	\
+		return;			\
+	} while(0)
+
+#define VBERESPW0(field, str, fltchk)
+#define VBERESPW1(field, str, fltchk)					\
 void									\
 VRT_l_beresp_##field(VRT_CTX, VCL_BOOL a)				\
 {									\
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);				\
 	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);			\
+	VBERESPWF##fltchk(ctx, str);					\
 	ctx->bo->field = a ? 1 : 0;					\
 }
 
-#define VBERESPR0(field)
-#define VBERESPR1(field)						\
+#define VBERESPRF0(ctx, str) (void) 0
+#define VBERESPRF1(ctx, str) do {		\
+	if (beresp_filter_fixed((ctx), str))	\
+		return (0);			\
+	} while(0)
+
+#define VBERESPR0(field, str, fltchk)
+#define VBERESPR1(field, str, fltchk)					\
 VCL_BOOL								\
 VRT_r_beresp_##field(VRT_CTX)						\
 {									\
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);				\
 	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);			\
+	VBERESPRF##fltchk(ctx, str);					\
 	return (ctx->bo->field);					\
 }
 
-#define BO_FLAG(l, r, w, d) \
-	VBERESPR##r(l) \
-	VBERESPW##w(l)
+#define BO_FLAG(l, r, w, f, d)			\
+	VBERESPR##r(l, #l, f)			\
+	VBERESPW##w(l, #l, f)
 #include "tbl/bo_flags.h"
 
+#undef VBERESPWF0
+#undef VBERESPWF1
+#undef VBERESPW0
+#undef VBERESPW1
+
+#undef VBERESPRF0
+#undef VBERESPRF1
+#undef VBERESPR0
+#undef VBERESPR1
 /*--------------------------------------------------------------------*/
 
 VCL_BOOL
diff --git a/bin/varnishtest/tests/c00101.vtc b/bin/varnishtest/tests/c00101.vtc
new file mode 100644
index 000000000..c75f73749
--- /dev/null
+++ b/bin/varnishtest/tests/c00101.vtc
@@ -0,0 +1,48 @@
+varnishtest "bo_* with effect on filters"
+
+
+server s1 -repeat 2 -keepalive {
+	rxreq
+	txresp -body {
+		-This is a test: Hello world
+	}
+} -start
+
+varnish v1 -vcl+backend {
+	sub backend_response_filter {
+		set beresp.http.filter0 = beresp.filters;
+		set beresp.do_esi = true;
+		set beresp.http.filter1 = beresp.filters;
+		set beresp.do_gzip = true;
+		set beresp.http.filter2 = beresp.filters;
+		set beresp.do_esi = false;
+		set beresp.do_gzip = false;
+		set beresp.http.Content-Encoding = "gzip";
+		set beresp.do_gunzip = true;
+		set beresp.http.filter3 = beresp.filters;
+		set beresp.filters = "";
+
+		# does not affect filters
+		set beresp.do_stream = true;
+
+	}
+	sub vcl_backend_response {
+		call backend_response_filter;
+		if (bereq.http.fiddle) {
+			call backend_response_filter;
+		}
+	}
+	sub vcl_recv {
+		return (pass);
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 200
+
+	txreq -hdr "fiddle: yes"
+	rxresp
+	expect resp.status == 503
+} -run
diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst
index 93d0414b8..306f82eee 100644
--- a/doc/sphinx/reference/vcl_var.rst
+++ b/doc/sphinx/reference/vcl_var.rst
@@ -745,6 +745,7 @@ beresp.do_esi
 	Set it to true to parse the object for ESI directives.
 	Will only be honored if req.esi is true.
 
+	It is a VCL error to use beresp.do_esi after setting beresp.filters.
 
 beresp.do_stream
 
@@ -781,6 +782,8 @@ beresp.do_gzip
 	If ``http_gzip_support`` is disabled, setting this variable
 	has no effect.
 
+	It is a VCL error to use beresp.do_gzip after setting beresp.filters.
+
 beresp.do_gunzip
 
 	Type: BOOL
@@ -797,6 +800,8 @@ beresp.do_gunzip
 	If ``http_gzip_support`` is disabled, setting this variable
 	has no effect.
 
+	It is a VCL error to use beresp.do_gunzip after setting beresp.filters.
+
 beresp.was_304
 
 	Type: BOOL
@@ -997,6 +1002,9 @@ beresp.filters
 	* ``testgunzip`` gets added for compressed content if
 	  ``beresp.do_gunzip`` is false.
 
+	After beresp.filters is set, using any of the beforementioned
+	``beresp.do_*`` switches is a VCL error.
+
 obj
 ~~~
 
diff --git a/include/tbl/bo_flags.h b/include/tbl/bo_flags.h
index 91293f5d6..9d26d6a97 100644
--- a/include/tbl/bo_flags.h
+++ b/include/tbl/bo_flags.h
@@ -31,15 +31,18 @@
 
 /*lint -save -e525 -e539 */
 
-/* lower, vcl_r, vcl_w, doc */
-BO_FLAG(do_esi,		1, 1, "")
-BO_FLAG(do_gzip,	1, 1, "")
-BO_FLAG(do_gunzip,	1, 1, "")
-BO_FLAG(do_stream,	1, 1, "")
-BO_FLAG(do_pass,	0, 0, "")
-BO_FLAG(uncacheable,	0, 0, "")
-BO_FLAG(was_304,	1, 0, "")
-BO_FLAG(is_bgfetch,	0, 0, "")
+/*
+ * filters: whether this flag determines beresp.filters default
+ *
+ * lower, vcl_r, vcl_w, filters, doc */
+BO_FLAG(do_esi,		1, 1, 1, "")
+BO_FLAG(do_gzip,	1, 1, 1, "")
+BO_FLAG(do_gunzip,	1, 1, 1, "")
+BO_FLAG(do_stream,	1, 1, 0, "")
+BO_FLAG(do_pass,	0, 0, 0, "")
+BO_FLAG(uncacheable,	0, 0, 0, "")
+BO_FLAG(was_304,	1, 0, 0, "")
+BO_FLAG(is_bgfetch,	0, 0, 0, "")
 #undef BO_FLAG
 
 /*lint -restore */


More information about the varnish-commit mailing list