[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