[master] f53c783 Don't treat 'unset' as a special case of 'set', having bereq.body hardcoded in the compiler is not nice.

Poul-Henning Kamp phk at FreeBSD.org
Wed Jan 24 12:24:08 UTC 2018


commit f53c7838defcf2799be1501eba3a79cf4f3df2ad
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Jan 24 12:21:18 2018 +0000

    Don't treat 'unset' as a special case of 'set',
    having bereq.body hardcoded in the compiler is not nice.

diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index b16c614..bb82fd6 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -434,11 +434,10 @@ VRT_r_beresp_backend(VRT_CTX)
 /*--------------------------------------------------------------------*/
 
 void
-VRT_l_bereq_body(VRT_CTX, const char *p, ...)
+VRT_u_bereq_body(VRT_CTX)
 {
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
-	assert(p == vrt_magic_string_unset);
 	if (ctx->bo->req != NULL) {
 		CHECK_OBJ_NOTNULL(ctx->bo->req, REQ_MAGIC);
 		ctx->bo->req = NULL;
diff --git a/bin/varnishtest/tests/v00018.vtc b/bin/varnishtest/tests/v00018.vtc
index 186f7cb..7c14f02 100644
--- a/bin/varnishtest/tests/v00018.vtc
+++ b/bin/varnishtest/tests/v00018.vtc
@@ -68,12 +68,12 @@ varnish v1 -errvcl {Symbol not found: 'mu' (expected type BOOL):} {
 	sub vcl_backend_response { set beresp.do_gzip = mu; }
 }
 
-varnish v1 -errvcl {Only bereq.body and HTTP header variables can be unset.} {
+varnish v1 -errvcl {Variable 'beresp.do_gzip' cannot be unset} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_backend_response { unset beresp.do_gzip; }
 }
 
-varnish v1 -errvcl {bereq.body cannot be set.} {
+varnish v1 -errvcl {Variable 'bereq.body' cannot be set.} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_backend_fetch { set bereq.body = "foo"; }
 }
diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py
index 5e5c04f..3b6dda7 100755
--- a/lib/libvcc/generate.py
+++ b/lib/libvcc/generate.py
@@ -169,13 +169,14 @@ returns = (
 sp_variables = collections.OrderedDict()
 
 class vardef(object):
-	def __init__(self, nam, typ, rd, wr, doc):
+	def __init__(self, nam, typ, rd, wr, doc, uns = None):
 		sp_variables[nam] = self
 		self.nam = nam
 		self.typ = typ
 		self.rd = rd
 		self.wr = wr
 		self.doc = doc
+		self.uns = uns
 
 vardef('remote.ip',
 	'IP',
@@ -273,7 +274,8 @@ vardef('req.http.',
 	('client',),
 	('client',), """
 	The corresponding HTTP header.
-	"""
+	""",
+	uns = ('client',)
 )
 vardef('req.restarts',
 	'INT',
@@ -435,9 +437,10 @@ vardef('bereq.backend',
 vardef('bereq.body',
 	'BODY',
 	(),
-	('backend_fetch',), """
+	(), """
 	The request body.
-	"""
+	""",
+	uns = ('backend_fetch',)
 )
 vardef('bereq.hash',
 	'BLOB',
@@ -472,7 +475,8 @@ vardef('bereq.http.',
 	('pipe', 'backend', ),
 	('pipe', 'backend', ), """
 	The corresponding HTTP header.
-	"""
+	""",
+	uns = ('pipe', 'backend', )
 )
 vardef('bereq.uncacheable',
 	'BOOL',
@@ -556,7 +560,8 @@ vardef('beresp.http.',
 	('backend_response', 'backend_error'),
 	('backend_response', 'backend_error'), """
 	The corresponding HTTP header.
-	"""
+	""",
+	uns = ('backend_response', 'backend_error')
 )
 vardef('beresp.do_esi',
 	'BOOL',
@@ -810,7 +815,8 @@ vardef('resp.http.',
 	('deliver', 'synth'),
 	('deliver', 'synth'), """
 	The corresponding HTTP header.
-	"""
+	""",
+	uns = ('deliver', 'synth')
 )
 vardef('resp.is_streaming',
 	'BOOL',
@@ -1306,6 +1312,15 @@ def one_var(nm, spec):
 		restrict(fo, spec.wr)
 		fo.write(";\n")
 
+	if spec.uns is None or len(spec.uns) == 0:
+		fo.write('\t/* No unsets allowed */\n')
+	else:
+		fh.write("void VRT_u_%s(VRT_CTX);\n" % cnam)
+		fo.write('\tsym->uname = "VRT_u_%s(ctx)";\n' % cnam)
+		fo.write('\tsym->u_methods =\n')
+		restrict(fo, spec.uns)
+		fo.write(";\n")
+
 aliases.sort()
 for i in sp_variables:
 	one_var(i, sp_variables[i])
diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index 1d582e2..ee6fe85 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -81,6 +81,9 @@ static const struct arith {
 	{ VOID,		'=',		VOID }
 };
 
+
+/*--------------------------------------------------------------------*/
+
 static void
 parse_set(struct vcc *tl)
 {
@@ -90,14 +93,27 @@ parse_set(struct vcc *tl)
 
 	vcc_NextToken(tl);
 	ExpectErr(tl, ID);
-	sym = vcc_FindVar(tl, "cannot be set");
+	sym = VCC_SymbolTok(tl, NULL, SYM_VAR, 0);
 	ERRCHK(tl);
-	assert(sym != NULL);
-	if (vcc_IdIs(tl->t, "bereq.body")) {
-		VSB_printf(tl->sb, "bereq.body cannot be set.\n");
+	if (sym == NULL) {
+		VSB_printf(tl->sb, "Unknown variable ");
+		vcc_ErrToken(tl, tl->t);
+		VSB_cat(tl->sb, "\nAt: ");
+		vcc_ErrWhere(tl, tl->t);
+		return;
+	}
+	if (sym->w_methods == 0) {
+		VSB_printf(tl->sb, "Variable ");
+		vcc_ErrToken(tl, tl->t);
+		if (sym->r_methods != 0)
+			VSB_printf(tl->sb, " is read only.");
+		else
+			VSB_printf(tl->sb, " cannot be set.");
+		VSB_cat(tl->sb, "\nAt: ");
 		vcc_ErrWhere(tl, tl->t);
 		return;
 	}
+	vcc_AddUses(tl, tl->t, sym->w_methods, "cannot be set");
 	Fb(tl, 1, "%s\n", sym->lname);
 	tl->indent += INDENT;
 	vcc_NextToken(tl);
@@ -138,18 +154,25 @@ parse_unset(struct vcc *tl)
 	/* XXX: Wrong, should use VCC_Expr(HEADER) */
 	vcc_NextToken(tl);
 	ExpectErr(tl, ID);
-	sym = vcc_FindVar(tl, "cannot be unset");
+	sym = VCC_SymbolTok(tl, NULL, SYM_VAR, 0);
 	ERRCHK(tl);
-	assert(sym != NULL);
-	if (sym->fmt != HEADER && !vcc_IdIs(tl->t, "bereq.body")) {
-		VSB_printf(tl->sb,
-		    "Only bereq.body and HTTP header variables can"
-		    " be unset.\n");
+	if (sym == NULL) {
+		VSB_printf(tl->sb, "Unknown variable ");
+		vcc_ErrToken(tl, tl->t);
+		VSB_cat(tl->sb, "\nAt: ");
 		vcc_ErrWhere(tl, tl->t);
 		return;
 	}
-	ERRCHK(tl);
-	Fb(tl, 1, "%svrt_magic_string_unset);\n", sym->lname);
+	if (sym->u_methods == 0) {
+		VSB_printf(tl->sb, "Variable ");
+		vcc_ErrToken(tl, tl->t);
+		VSB_printf(tl->sb, " cannot be unset.");
+		VSB_cat(tl->sb, "\nAt: ");
+		vcc_ErrWhere(tl, tl->t);
+		return;
+	}
+	vcc_AddUses(tl, tl->t, sym->u_methods, "cannot be unset.");
+	Fb(tl, 1, "%s;\n", sym->uname);
 	vcc_NextToken(tl);
 }
 
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index e0b0da9..8694c38 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -141,6 +141,8 @@ struct symbol {
 	unsigned			r_methods;
 	const char			*lname;
 	unsigned			w_methods;
+	const char			*uname;
+	unsigned			u_methods;
 };
 
 VTAILQ_HEAD(tokenhead, token);
@@ -335,7 +337,6 @@ vcc_type_t VCC_Type(const char *p);
 
 /* vcc_var.c */
 sym_wildcard_t vcc_Var_Wildcard;
-const struct symbol *vcc_FindVar(struct vcc *, const char *);
 
 /* vcc_vmod.c */
 void vcc_ParseImport(struct vcc *tl);
diff --git a/lib/libvcc/vcc_var.c b/lib/libvcc/vcc_var.c
index 133455f..0c9af8c 100644
--- a/lib/libvcc/vcc_var.c
+++ b/lib/libvcc/vcc_var.c
@@ -59,6 +59,7 @@ vcc_Var_Wildcard(struct vcc *tl, struct symbol *parent,
 	sym->eval = vcc_Eval_Var;
 	sym->r_methods = parent->r_methods;
 	sym->w_methods = parent->w_methods;
+	sym->u_methods = parent->u_methods;
 
 	/* Create a C-name version of the header name */
 	vsb = VSB_new_auto();
@@ -79,34 +80,10 @@ vcc_Var_Wildcard(struct vcc *tl, struct symbol *parent,
 	VSB_printf(vsb, "VRT_SetHdr(ctx, %s,", sym->rname);
 	AZ(VSB_finish(vsb));
 	sym->lname = TlDup(tl, VSB_data(vsb));
+	VSB_clear(vsb);
+	VSB_printf(vsb, "VRT_SetHdr(ctx, %s, vrt_magic_string_unset)",
+	    sym->rname);
+	AZ(VSB_finish(vsb));
+	sym->uname = TlDup(tl, VSB_data(vsb));
 	VSB_destroy(&vsb);
 }
-
-/*--------------------------------------------------------------------*/
-
-const struct symbol *
-vcc_FindVar(struct vcc *tl, const char *use)
-{
-	const struct symbol *sym;
-
-	sym = VCC_SymbolTok(tl, NULL, SYM_VAR, 0);
-	if (tl->err)
-		return (NULL);
-	if (sym != NULL) {
-		if (sym->w_methods == 0) {
-			VSB_printf(tl->sb, "Variable ");
-			vcc_ErrToken(tl, tl->t);
-			VSB_printf(tl->sb, " is read only.");
-			VSB_cat(tl->sb, "\nAt: ");
-			vcc_ErrWhere(tl, tl->t);
-			return (NULL);
-		}
-		vcc_AddUses(tl, tl->t, sym->w_methods, use);
-		return (sym);
-	}
-	VSB_printf(tl->sb, "Unknown variable ");
-	vcc_ErrToken(tl, tl->t);
-	VSB_cat(tl->sb, "\nAt: ");
-	vcc_ErrWhere(tl, tl->t);
-	return (NULL);
-}


More information about the varnish-commit mailing list