[master] d445e56 Turn "HEADER" into a full blown VCL data type, this is actually simpler and more orthogonal.
Poul-Henning Kamp
phk at varnish-cache.org
Tue Oct 23 23:06:31 CEST 2012
commit d445e56abf19792c6bdd1ab989d82eedb186f314
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Oct 23 21:02:44 2012 +0000
Turn "HEADER" into a full blown VCL data type, this is actually simpler
and more orthogonal.
This is a "it works!" snapshot, there are improvements to the generated
C-code in the pipeline.
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index c4573ff..ed7ae59 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -138,14 +138,14 @@ vrt_selecthttp(const struct req *req, enum gethdr_e where)
}
char *
-VRT_GetHdr(const struct req *req, enum gethdr_e where, const char *n)
+VRT_GetHdr(const struct req *req, const struct gethdr_s *hs)
{
char *p;
struct http *hp;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
- hp = vrt_selecthttp(req, where);
- if (!http_GetHdr(hp, n, &p))
+ hp = vrt_selecthttp(req, hs->where);
+ if (!http_GetHdr(hp, hs->what, &p))
return (NULL);
return (p);
}
@@ -230,24 +230,25 @@ VRT_ReqString(struct req *req, const char *p, ...)
/*--------------------------------------------------------------------*/
void
-VRT_SetHdr(struct req *req , enum gethdr_e where, const char *hdr,
- const char *p, ...)
+VRT_SetHdr(struct req *req , const struct gethdr_s *hs, const char *p, ...)
{
struct http *hp;
va_list ap;
char *b;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
- hp = vrt_selecthttp(req, where);
+ AN(hs);
+ AN(hs->what);
+ hp = vrt_selecthttp(req, hs->where);
va_start(ap, p);
if (p == vrt_magic_string_unset) {
- http_Unset(hp, hdr);
+ http_Unset(hp, hs->what);
} else {
- b = VRT_String(hp->ws, hdr + 1, p, ap);
+ b = VRT_String(hp->ws, hs->what + 1, p, ap);
if (b == NULL) {
- VSLb(req->vsl, SLT_LostHeader, "%s", hdr + 1);
+ VSLb(req->vsl, SLT_LostHeader, "%s", hs->what + 1);
} else {
- http_Unset(hp, hdr);
+ http_Unset(hp, hs->what);
http_SetHeader(hp, b);
}
}
diff --git a/include/vrt.h b/include/vrt.h
index 8ca31de..c98e085 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -187,9 +187,8 @@ void VRT_error(struct req *, unsigned, const char *);
int VRT_switch_config(const char *);
const struct gethdr_s *VRT_MkGethdr(struct req *,enum gethdr_e, const char *);
-char *VRT_GetHdr(const struct req *, enum gethdr_e where, const char *);
-void VRT_SetHdr(struct req *, enum gethdr_e where, const char *,
- const char *, ...);
+char *VRT_GetHdr(const struct req *, const struct gethdr_s *);
+void VRT_SetHdr(struct req *, const struct gethdr_s *, const char *, ...);
void VRT_handling(struct req *, unsigned hand);
void VRT_hashdata(struct req *, const char *str, ...);
diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py
index 7ddafeb..6efff05 100755
--- a/lib/libvcl/generate.py
+++ b/lib/libvcl/generate.py
@@ -158,7 +158,7 @@ sp_variables = (
'const struct req *'
),
('req.http.',
- 'HDR_REQ',
+ 'HEADER',
( 'proc',),
( 'proc',),
'const struct req *'
@@ -254,7 +254,7 @@ sp_variables = (
'const struct req *'
),
('bereq.http.',
- 'HDR_BEREQ',
+ 'HEADER',
( 'pipe', 'pass', 'miss', 'fetch',),
( 'pipe', 'pass', 'miss', 'fetch',),
'const struct req *'
@@ -302,7 +302,7 @@ sp_variables = (
'const struct req *'
),
('beresp.http.',
- 'HDR_BERESP',
+ 'HEADER',
( 'fetch',),
( 'fetch',),
'const struct req *'
@@ -404,7 +404,7 @@ sp_variables = (
'const struct req *'
),
('obj.http.',
- 'HDR_OBJ',
+ 'HEADER',
( 'hit', 'error',),
( 'error',), # XXX ?
'const struct req *'
@@ -452,7 +452,7 @@ sp_variables = (
'const struct req *'
),
('resp.http.',
- 'HDR_RESP',
+ 'HEADER',
( 'deliver',),
( 'deliver',),
'const struct req *'
@@ -787,7 +787,7 @@ fo.close()
def restrict(fo, spec):
if len(spec) == 0:
- fo.write("\t 0,\n")
+ fo.write("\t\t0,\n")
return
if spec[0] == 'all':
spec = vcls
@@ -803,7 +803,7 @@ def restrict(fo, spec):
fo.write("\n")
n = 0
if n == 0:
- fo.write("\t ")
+ fo.write("\t\t")
n += 1
fo.write(p + "VCL_MET_" + j.upper())
p = " | "
@@ -830,38 +830,38 @@ const struct var vcc_vars[] = {
for i in sp_variables:
typ = i[1]
- if typ[:4] == "HDR_":
- typ = "HEADER"
-
cnam = i[0].replace(".", "_")
ctyp = vcltypes[typ]
fo.write("\t{ \"%s\", %s, %d,\n" % (i[0], typ, len(i[0])))
- if len(i[2]) > 0:
- fo.write('\t "VRT_r_%s(req)",\n' % cnam)
- if typ != "HEADER":
- fh.write(ctyp + " VRT_r_%s(const %s);\n" % (cnam, i[4]))
- else:
+ if len(i[2]) == 0:
fo.write('\t NULL,\t/* No reads allowed */\n')
+ elif typ == "HEADER":
+ fo.write('\t "VRT_MkGethdr(req, HDR_')
+ fo.write(i[0].split(".")[0].upper())
+ fo.write(', ",\n')
+ else:
+ fo.write('\t "VRT_r_%s(req)",\n' % cnam)
+ fh.write(ctyp + " VRT_r_%s(const %s);\n" % (cnam, i[4]))
restrict(fo, i[2])
- if len(i[3]) > 0:
- fo.write('\t "VRT_l_%s(req, ",\n' % cnam)
- if typ != "HEADER":
- fh.write("void VRT_l_%s(%s, " % (cnam, i[4]))
- if typ != "STRING":
- fh.write(ctyp + ");\n")
- else:
- fh.write(ctyp + ", ...);\n")
- else:
+ if len(i[3]) == 0:
fo.write('\t NULL,\t/* No writes allowed */\n')
+ elif typ == "HEADER":
+ fo.write('\t "VRT_SetHdr(req, VRT_MkGethdr(req, HDR_')
+ fo.write(i[0].split(".")[0].upper())
+ fo.write(', ",\n')
+ else:
+ fo.write('\t "VRT_l_%s(req, ",\n' % cnam)
+ fh.write("void VRT_l_%s(%s, " % (cnam, i[4]))
+ if typ != "STRING":
+ fh.write(ctyp + ");\n")
+ else:
+ fh.write(ctyp + ", ...);\n")
restrict(fo, i[3])
- if typ == "HEADER":
- fo.write('\t "%s",\n' % i[1])
- else:
- fo.write('\t 0,\n') # XXX: shoule be NULL
+ fo.write('\t 0,\n') # XXX: shoule be NULL
fo.write("\t},\n")
fo.write("\t{ NULL }\n};\n")
diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c
index 4b3d69b..eae6231 100644
--- a/lib/libvcl/vcc_action.c
+++ b/lib/libvcl/vcc_action.c
@@ -137,7 +137,9 @@ parse_set(struct vcc *tl)
}
if (ap->type == VOID)
SkipToken(tl, ap->oper);
- if (fmt == STRING) {
+ if (fmt == HEADER) {
+ vcc_Expr(tl, STRING_LIST);
+ } else if (fmt == STRING) {
vcc_Expr(tl, STRING_LIST);
} else {
vcc_Expr(tl, fmt);
@@ -153,12 +155,13 @@ parse_unset(struct vcc *tl)
{
const struct var *vp;
+ /* XXX: Wrong, should use VCC_Expr(HEADER) */
vcc_NextToken(tl);
ExpectErr(tl, ID);
vp = vcc_FindVar(tl, tl->t, 1, "cannot be unset");
ERRCHK(tl);
assert(vp != NULL);
- if (vp->fmt != STRING || vp->http == NULL) {
+ if (vp->fmt != HEADER) {
VSB_printf(tl->sb,
"Only http header variables can be unset.\n");
vcc_ErrWhere(tl, tl->t);
diff --git a/lib/libvcl/vcc_expr.c b/lib/libvcl/vcc_expr.c
index 3710490..17b0853 100644
--- a/lib/libvcl/vcc_expr.c
+++ b/lib/libvcl/vcc_expr.c
@@ -441,7 +441,14 @@ vcc_expr_tostring(struct expr **e, enum var_type fmt)
case BYTES: p = "VRT_REAL_string(req, \v1)"; break; /* XXX */
case REAL: p = "VRT_REAL_string(req, \v1)"; break;
case TIME: p = "VRT_TIME_string(req, \v1)"; break;
- default: break;
+ case HEADER: p = "VRT_GetHdr(req, \v1)"; break;
+ case ENUM:
+ case STRING:
+ case STRING_LIST:
+ break;
+ default:
+ INCOMPL();
+ break;
}
if (p != NULL) {
*e = vcc_expr_edit(fmt, p, *e, NULL);
@@ -539,7 +546,7 @@ void
vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym)
{
const char *p, *r;
- const struct var *v;
+ // const struct var *v;
struct expr *e1, *e2;
enum var_type fmt;
char buf[32];
@@ -591,34 +598,6 @@ vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym)
SkipToken(tl, ID);
if (*p != '\0')
SkipToken(tl, ',');
- } else if (fmt == HEADER) {
- ExpectErr(tl, ID);
- sym = VCC_FindSymbol(tl, tl->t, SYM_NONE);
- ERRCHK(tl);
- SkipToken(tl, ID);
- if (sym == NULL) {
- VSB_printf(tl->sb, "Symbol not found.\n");
- vcc_ErrWhere(tl, tl->t);
- return;
- }
- vcc_AddUses(tl, tl->t, sym->r_methods, "Not available");
- if (sym->kind != SYM_VAR) {
- VSB_printf(tl->sb, "Wrong kind of symbol.\n");
- vcc_ErrWhere(tl, tl->t);
- return;
- }
- AN(sym->var);
- v = sym->var;
- if (v->http == NULL) {
- VSB_printf(tl->sb,
- "Variable not an HTTP header.\n");
- vcc_ErrWhere(tl, tl->t);
- return;
- }
- e1 = vcc_mk_expr(VOID, "VRT_MkGethdr(req, %s, \"%s\")",
- v->http, v->hdr);
- if (*p != '\0')
- SkipToken(tl, ',');
} else {
vcc_expr0(tl, &e1, fmt);
ERRCHK(tl);
@@ -803,7 +782,7 @@ vcc_expr_mul(struct vcc *tl, struct expr **e, enum var_type fmt)
*/
static void
-vcc_expr_string_add(struct vcc *tl, struct expr **e, enum var_type fmt)
+vcc_expr_string_add(struct vcc *tl, struct expr **e)
{
struct expr *e2;
enum var_type f2;
@@ -838,12 +817,6 @@ vcc_expr_string_add(struct vcc *tl, struct expr **e, enum var_type fmt)
(*e)->constant = EXPR_VAR;
}
}
- if (fmt != STRING_LIST && (*e)->fmt == STRING_LIST)
- *e = vcc_expr_edit(STRING,
- "\v+VRT_ReqString(req,\n\v1,\nvrt_magic_string_end)",
- *e, NULL);
- if (fmt == STRING_LIST && (*e)->fmt == STRING)
- (*e)->fmt = STRING_LIST;
}
static void
@@ -858,6 +831,16 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
ERRCHK(tl);
f2 = (*e)->fmt;
+ /* Unless we specifically ask for a HEADER, fold them to string here */
+ if (fmt != HEADER && f2 == HEADER) {
+ vcc_expr_tostring(e, STRING);
+ f2 = (*e)->fmt;
+ assert(f2 == STRING);
+ }
+
+ if (tl->t->tok != '+' && tl->t->tok != '-')
+ return;
+
switch(f2) {
case STRING: break;
case STRING_LIST: break;
@@ -865,9 +848,8 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
case TIME: break;
case DURATION: break;
case BYTES: break;
+ case HEADER: break;
default:
- if (tl->t->tok != '+' && tl->t->tok != '-')
- return;
VSB_printf(tl->sb, "Operator %.*s not possible on type %s.\n",
PF(tl->t), vcc_Type(f2));
vcc_ErrWhere(tl, tl->t);
@@ -875,7 +857,7 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
}
if (f2 == STRING || f2 == STRING_LIST) {
- vcc_expr_string_add(tl, e, fmt);
+ vcc_expr_string_add(tl, e);
return;
}
@@ -910,6 +892,24 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
}
/*--------------------------------------------------------------------
+ * Fold the STRING types correctly
+ */
+
+static void
+vcc_expr_strfold(struct vcc *tl, struct expr **e, enum var_type fmt)
+{
+
+ vcc_expr_add(tl, e, fmt);
+
+ if (fmt != STRING_LIST && (*e)->fmt == STRING_LIST)
+ *e = vcc_expr_edit(STRING,
+ "\v+VRT_ReqString(req,\n\v1,\nvrt_magic_string_end)",
+ *e, NULL);
+ if (fmt == STRING_LIST && (*e)->fmt == STRING)
+ (*e)->fmt = STRING_LIST;
+}
+
+/*--------------------------------------------------------------------
* SYNTAX:
* ExprCmp:
* ExprAdd
@@ -958,7 +958,7 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
*e = NULL;
- vcc_expr_add(tl, e, fmt);
+ vcc_expr_strfold(tl, e, fmt);
ERRCHK(tl);
if ((*e)->fmt == BOOL)
@@ -970,7 +970,7 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
break;
if (cp->fmt != VOID) {
vcc_NextToken(tl);
- vcc_expr_add(tl, &e2, (*e)->fmt);
+ vcc_expr_strfold(tl, &e2, (*e)->fmt);
ERRCHK(tl);
if (e2->fmt != (*e)->fmt) { /* XXX */
VSB_printf(tl->sb, "Comparison of different types: ");
diff --git a/lib/libvcl/vcc_var.c b/lib/libvcl/vcc_var.c
index aa728e6..661ca85 100644
--- a/lib/libvcl/vcc_var.c
+++ b/lib/libvcl/vcc_var.c
@@ -50,19 +50,19 @@ vcc_Var_Wildcard(struct vcc *tl, const struct token *t, const struct symbol *wc)
v = TlAlloc(tl, sizeof *v);
AN(v);
+ assert(vh->fmt == HEADER);
v->name = TlDupTok(tl, t);
v->r_methods = vh->r_methods;
v->w_methods = vh->w_methods;
- v->fmt = STRING;
+ v->fmt = vh->fmt;
v->http = vh->http;
l = strlen(v->name + vh->len) + 1;
bprintf(buf, "\\%03o%s:", (unsigned)l, v->name + vh->len);
v->hdr = TlDup(tl, buf);
- bprintf(buf, "VRT_GetHdr(req, %s, \"%s\")", v->http, v->hdr);
+ bprintf(buf, "%s\"%s\")", vh->rname, v->hdr);
v->rname = TlDup(tl, buf);
-
- bprintf(buf, "VRT_SetHdr(req, %s, \"%s\", ", v->http, v->hdr);
+ bprintf(buf, "%s\"%s\"), ", vh->lname, v->hdr);
v->lname = TlDup(tl, buf);
sym = VCC_AddSymbolTok(tl, t, SYM_VAR);
@@ -108,7 +108,6 @@ vcc_FindVar(struct vcc *tl, const struct token *t, int wr_access,
} else {
vcc_AddUses(tl, t, v->r_methods, use);
}
- assert(v->fmt != HEADER);
return (v);
}
VSB_printf(tl->sb, "Unknown variable ");
More information about the varnish-commit
mailing list