From: phk Date: Sun, 18 Jun 2006 10:02:35 +0000 (+0000) Subject: Add support for investigating random HTTP headers. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=affba6fa68ac5b456b862c26b0526624b2763fae;p=varnish Add support for investigating random HTTP headers. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@199 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/include/vcl_lang.h b/varnish-cache/include/vcl_lang.h index 31d995ca..5242ce7e 100644 --- a/varnish-cache/include/vcl_lang.h +++ b/varnish-cache/include/vcl_lang.h @@ -100,6 +100,8 @@ int VCL_rewrite(const char *, const char *); void VCL_error(VCL_FARGS, unsigned, const char *); int VCL_switch_config(const char *); +char *VCL_GetHdr(VCL_FARGS, const char *); + typedef void vcl_init_f(void); typedef void vcl_func_f(VCL_FARGS); diff --git a/varnish-cache/lib/libvcl/vcl_compile.c b/varnish-cache/lib/libvcl/vcl_compile.c index c538dea0..febd4e4a 100644 --- a/varnish-cache/lib/libvcl/vcl_compile.c +++ b/varnish-cache/lib/libvcl/vcl_compile.c @@ -89,7 +89,8 @@ enum var_type { STRING, IP, HOSTNAME, - PORTNAME + PORTNAME, + HEADER }; struct var { @@ -124,6 +125,7 @@ static struct var vars[] = { { "req.request", STRING, 0, "\"GET\"" }, { "obj.valid", BOOL, 0, "sess->obj->valid" }, { "obj.cacheable", BOOL, 0, "sess->obj->cacheable" }, + { "req.http.", HEADER, 0, NULL }, #if 0 { "req.ttlfactor", FLOAT, 0, "req->ttlfactor" }, { "req.url.host", STRING, 0, "req->url.host" }, @@ -549,6 +551,28 @@ IpVal(struct tokenlist *tl) return (0); } +/*--------------------------------------------------------------------*/ +static struct var * +HeaderVar(struct tokenlist *tl, struct token *t, struct var *vh) +{ + char *p; + struct var *v; + int i; + + v = calloc(sizeof *v, 1); + i = t->e - t->b; + p = malloc(i + 1); + assert(p != NULL); + memcpy(p, t->b, i); + p[i] = '\0'; + v->name = p; + v->fmt = STRING; + asprintf(&p, "VCL_GetHdr(VCL_PASS_ARGS, \"%s\")", v->name + vh->len); + assert(p != NULL); + v->cname = p; + return (v); +} + /*--------------------------------------------------------------------*/ static struct var * @@ -557,10 +581,15 @@ FindVar(struct tokenlist *tl, struct token *t, struct var *vl) struct var *v; for (v = vl; v->name != NULL; v++) { - if (t->e - t->b != v->len) + if (v->fmt == HEADER && t->e - t->b <= v->len) + continue; + if (v->fmt != HEADER && t->e - t->b != v->len) continue; - if (!memcmp(t->b, v->name, v->len)) + if (memcmp(t->b, v->name, v->len)) + continue; + if (v->fmt != HEADER) return (v); + return (HeaderVar(tl, t, v)); } sbuf_printf(tl->sb, "Unknown variable "); ErrToken(tl, t); @@ -651,7 +680,6 @@ static void Cond_String(struct var *vp, struct tokenlist *tl) { - (void)vp; switch (tl->t->tok) { case '~': I(tl); sbuf_printf(tl->fc, "string_match(%s, ", vp->cname); @@ -662,8 +690,11 @@ Cond_String(struct var *vp, struct tokenlist *tl) tl->t->e - tl->t->b, tl->t->b); NextToken(tl); break; + case T_EQ: case T_NEQ: - I(tl); sbuf_printf(tl->fc, "strcmp(%s, ", vp->cname); + I(tl); + sbuf_printf(tl->fc, "%sstrcmp(%s, ", + tl->t->tok == T_EQ ? "" : "!", vp->cname); NextToken(tl); ExpectErr(tl, CSTR); sbuf_printf(tl->fc, "%*.*s)\n", @@ -672,11 +703,7 @@ Cond_String(struct var *vp, struct tokenlist *tl) NextToken(tl); break; default: - sbuf_printf(tl->sb, "Illegal condition "); - ErrToken(tl, tl->t); - sbuf_printf(tl->sb, " on string variable\n"); - sbuf_printf(tl->sb, " only '~' is legal\n"); - ErrWhere(tl, tl->t); + I(tl); sbuf_printf(tl->fc, "%s != (void*)0", vp->cname); break; } } diff --git a/varnish-cache/lib/libvcl/vcl_fixed_token.c b/varnish-cache/lib/libvcl/vcl_fixed_token.c index 520fb0e3..e677105c 100644 --- a/varnish-cache/lib/libvcl/vcl_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcl_fixed_token.c @@ -499,6 +499,8 @@ vcl_output_lang_h(FILE *f) fputs("void VCL_error(VCL_FARGS, unsigned, const char *);\n", f); fputs("int VCL_switch_config(const char *);\n", f); fputs("\n", f); + fputs("char *VCL_GetHdr(VCL_FARGS, const char *);\n", f); + fputs("\n", f); fputs("typedef void vcl_init_f(void);\n", f); fputs("typedef void vcl_func_f(VCL_FARGS);\n", f); fputs("\n", f);