[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