Commit d445e56a authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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.
parent 7157107e
......@@ -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);
}
}
......
......@@ -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, ...);
......
......@@ -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")
......
......@@ -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);
......
......@@ -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;
}
......@@ -909,6 +891,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:
......@@ -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: ");
......
......@@ -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 ");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment