From 934497868b625dd500432ce3387eeca68aa11c5c Mon Sep 17 00:00:00 2001 From: phk Date: Fri, 23 Jan 2009 21:17:02 +0000 Subject: [PATCH] First cut at VCL support for new-purge. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@3541 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache.h | 5 +- varnish-cache/bin/varnishd/cache_ban.c | 52 ++++++--------- varnish-cache/bin/varnishd/cache_vrt.c | 30 ++++++++- varnish-cache/include/vrt.h | 4 +- varnish-cache/lib/libvcl/vcc_action.c | 77 +++++++++++++++++++--- varnish-cache/lib/libvcl/vcc_fixed_token.c | 8 +-- 6 files changed, 126 insertions(+), 50 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 52f4a0df..7c33cf2c 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -417,7 +417,10 @@ struct backend *VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb); void VBP_Init(void); /* cache_ban.c */ -int BAN_Add(struct cli *cli, const char *regexp, int hash); +struct ban *BAN_New(void); +int BAN_AddTest(struct cli *, struct ban *, const char *, const char *, const char *); +void BAN_Free(struct ban *b); +void BAN_Insert(struct ban *b); void BAN_Init(void); void BAN_NewObj(struct object *o); void BAN_DestroyObj(struct object *o); diff --git a/varnish-cache/bin/varnishd/cache_ban.c b/varnish-cache/bin/varnishd/cache_ban.c index ade27a1b..a67401e3 100644 --- a/varnish-cache/bin/varnishd/cache_ban.c +++ b/varnish-cache/bin/varnishd/cache_ban.c @@ -95,8 +95,8 @@ static struct lock ban_mtx; * Manipulation of bans */ -static struct ban * -ban_new_ban(void) +struct ban * +BAN_New(void) { struct ban *b; ALLOC_OBJ(b, BAN_MAGIC); @@ -140,8 +140,8 @@ ban_sort_by_cost(struct ban *b) } while (i); } -static void -ban_free_ban(struct ban *b) +void +BAN_Free(struct ban *b) { struct ban_test *bt; @@ -308,8 +308,8 @@ static const struct pvar { { 0, 0, 0} }; -static int -ban_parse_test(struct cli *cli, struct ban *b, const char *a1, const char *a2, const char *a3) +int +BAN_AddTest(struct cli *cli, struct ban *b, const char *a1, const char *a2, const char *a3) { struct ban_test *bt; struct vsb *sb; @@ -387,7 +387,7 @@ ban_parse_test(struct cli *cli, struct ban *b, const char *a1, const char *a2, c */ static struct ban * volatile ban_start; -static void +void BAN_Insert(struct ban *b) { struct ban *bi, *be; @@ -476,7 +476,7 @@ BAN_DestroyObj(struct object *o) b = BAN_CheckLast(); Lck_Unlock(&ban_mtx); if (b != NULL) - ban_free_ban(b); + BAN_Free(b); } @@ -564,38 +564,20 @@ ccf_purge(struct cli *cli, const char * const *av, void *priv) } } - b = ban_new_ban(); + b = BAN_New(); if (b == NULL) { cli_out(cli, "Out of Memory"); cli_result(cli, CLIS_CANT); return; } for (i = 0; i < narg; i += 4) - if (ban_parse_test(cli, b, av[i + 2], av[i + 3], av[i + 4])) { - ban_free_ban(b); + if (BAN_AddTest(cli, b, av[i + 2], av[i + 3], av[i + 4])) { + BAN_Free(b); return; } BAN_Insert(b); } -int -BAN_Add(struct cli *cli, const char *regexp, int hash) -{ - const char *aav[6]; - - aav[0] = NULL; - aav[1] = "purge"; - if (hash) - aav[2] = "obj.hash"; - else - aav[2] = "req.url"; - aav[3] = "~"; - aav[4] = regexp; - aav[5] = NULL; - ccf_purge(cli, aav, NULL); - return (0); -} - static void ccf_purge_url(struct cli *cli, const char * const *av, void *priv) { @@ -651,7 +633,7 @@ ccf_purge_list(struct cli *cli, const char * const *av, void *priv) VTAILQ_LAST(&ban_head, banhead)->refcount++; Lck_Unlock(&ban_mtx); if (b != NULL) - ban_free_ban(b); + BAN_Free(b); } while (b != NULL); VTAILQ_FOREACH(b, &ban_head, list) { @@ -692,9 +674,17 @@ static struct cli_proto ban_cmds[] = { void BAN_Init(void) { + const char *aav[6]; Lck_New(&ban_mtx); CLI_AddFuncs(PUBLIC_CLI, ban_cmds); + /* Add an initial ban, since the list can never be empty */ - (void)BAN_Add(NULL, ".", 0); + aav[0] = NULL; + aav[1] = "purge"; + aav[2] = "req.url"; + aav[3] = "~"; + aav[4] = "."; + aav[5] = NULL; + ccf_purge(NULL, aav, NULL); } diff --git a/varnish-cache/bin/varnishd/cache_vrt.c b/varnish-cache/bin/varnishd/cache_vrt.c index 70c1f75e..120c9c2a 100644 --- a/varnish-cache/bin/varnishd/cache_vrt.c +++ b/varnish-cache/bin/varnishd/cache_vrt.c @@ -762,11 +762,35 @@ VRT_synth_page(struct sess *sp, unsigned flags, const char *str, ...) /*--------------------------------------------------------------------*/ void -VRT_purge(const char *regexp, int hash) +VRT_purge(struct sess *sp, char *cmds, ...) { + char *a1, *a2, *a3; + va_list ap; + struct ban *b; + int good; - if (regexp != NULL) - (void)BAN_Add(NULL, regexp, hash); + (void)sp; + b = BAN_New(); + va_start(ap, cmds); + a1 = cmds; + good = 0; + while (a1 != NULL) { + good = 0; + a2 = va_arg(ap, char *); + if (a2 == NULL) + break; + a3 = va_arg(ap, char *); + if (a3 == NULL) + break; + if (BAN_AddTest(NULL, b, a1, a2, a3)) + break; + a1 = va_arg(ap, char *); + good = 1; + } + if (!good) + BAN_Free(b); + else + BAN_Insert(b); } /*-------------------------------------------------------------------- diff --git a/varnish-cache/include/vrt.h b/varnish-cache/include/vrt.h index df612d07..4569c479 100644 --- a/varnish-cache/include/vrt.h +++ b/varnish-cache/include/vrt.h @@ -141,8 +141,8 @@ int VRT_re_match(const char *, void *re); const char *VRT_regsub(const struct sess *sp, int all, const char *, void *, const char *); -void VRT_panic(struct sess *sp, const char *, ...); -void VRT_purge(const char *, int hash); +void VRT_panic(struct sess *sp, const char *, ...); +void VRT_purge(struct sess *sp, char *, ...); void VRT_count(const struct sess *, unsigned); int VRT_rewrite(const char *, const char *); diff --git a/varnish-cache/lib/libvcl/vcc_action.c b/varnish-cache/lib/libvcl/vcc_action.c index 0a452a62..586f4eda 100644 --- a/varnish-cache/lib/libvcl/vcc_action.c +++ b/varnish-cache/lib/libvcl/vcc_action.c @@ -348,27 +348,86 @@ parse_unset(struct tokenlist *tl) /*--------------------------------------------------------------------*/ static void -parse_purge_url(struct tokenlist *tl) +parse_purge(struct tokenlist *tl) { vcc_NextToken(tl); - Fb(tl, 1, "VRT_purge("); Expect(tl, '('); vcc_NextToken(tl); + if (tl->t->tok == VAR) { + Fb(tl, 1, "VRT_purge(sp,\n"); + tl->indent += INDENT; + while (1) { + ExpectErr(tl, VAR); + Fb(tl, 1, " \"%.*s\",\n", PF(tl->t)); + vcc_NextToken(tl); + switch(tl->t->tok) { + case '~': + case T_NOMATCH: + case T_EQ: + case T_NEQ: + Fb(tl, 1, " \"%.*s\",\n", PF(tl->t)); + break; + default: + vsb_printf(tl->sb, + "Expected ~, !~, == or !=.\n"); + vcc_ErrWhere(tl, tl->t); + return; + } + vcc_NextToken(tl); + Fb(tl, 1, " "); + if (!vcc_StringVal(tl)) { + vcc_ExpectedStringval(tl); + return; + } + Fb(tl, 0, ",\n"); + if (tl->t->tok == ')') + break; + ExpectErr(tl, T_CAND); + Fb(tl, 1, "\"%.*s\",\n", PF(tl->t)); + vcc_NextToken(tl); + } + Fb(tl, 1, "0);\n"); + tl->indent -= INDENT; + } else { + Fb(tl, 1, "VRT_purge_string(sp, "); + if (!vcc_StringVal(tl)) { + vcc_ExpectedStringval(tl); + return; + } + do + Fb(tl, 0, ", "); + while (vcc_StringVal(tl)); + Fb(tl, 0, ", 0);\n"); + } + + Expect(tl, ')'); + vcc_NextToken(tl); +} + +/*--------------------------------------------------------------------*/ + +static void +parse_purge_url(struct tokenlist *tl) +{ + + vcc_NextToken(tl); + Expect(tl, '('); + vcc_NextToken(tl); + + Fb(tl, 1, "VRT_purge(sp, \"req.url\", \"~\", "); if (!vcc_StringVal(tl)) { vcc_ExpectedStringval(tl); return; } - Expect(tl, ')'); vcc_NextToken(tl); Fb(tl, 0, ", 0);\n"); } - /*--------------------------------------------------------------------*/ static void @@ -376,22 +435,21 @@ parse_purge_hash(struct tokenlist *tl) { vcc_NextToken(tl); - - Fb(tl, 1, "VRT_purge("); - Expect(tl, '('); vcc_NextToken(tl); + Fb(tl, 1, "VRT_purge(sp, \"obj.hash\", \"~\", "); if (!vcc_StringVal(tl)) { vcc_ExpectedStringval(tl); return; } - Expect(tl, ')'); vcc_NextToken(tl); - Fb(tl, 0, ", 1);\n"); + Fb(tl, 0, ", 0);\n"); } +/*--------------------------------------------------------------------*/ + static void parse_esi(struct tokenlist *tl) { @@ -470,6 +528,7 @@ static struct action_table { { "call", parse_call }, { "esi", parse_esi }, { "panic", parse_panic }, + { "purge", parse_purge }, { "purge_hash", parse_purge_hash }, { "purge_url", parse_purge_url }, { "remove", parse_unset }, /* backward compatibility */ diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index 69d8a2fd..83c6482d 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -159,8 +159,8 @@ vcl_output_lang_h(struct vsb *sb) /* ../../include/vcl.h */ - vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 3484 2008-12-21 17"); - vsb_cat(sb, ":01:58Z phk $\n *\n * NB: This file is machine genera"); + vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 3534 2009-01-19 13"); + vsb_cat(sb, ":46:31Z phk $\n *\n * NB: This file is machine genera"); vsb_cat(sb, "ted, DO NOT EDIT!\n *\n * Edit and run vcc_gen_fixed_t"); vsb_cat(sb, "oken.tcl instead\n */\n\nstruct sess;\n"); vsb_cat(sb, "struct cli;\n\ntypedef void vcl_init_f(struct cli *);\n"); @@ -287,8 +287,8 @@ vcl_output_lang_h(struct vsb *sb) vsb_cat(sb, "int VRT_re_match(const char *, void *re);\n"); vsb_cat(sb, "const char *VRT_regsub(const struct sess *sp, int all,"); vsb_cat(sb, " const char *,\n void *, const char *);\n"); - vsb_cat(sb, "\nvoid VRT_panic(struct sess *sp, const char *, ...);"); - vsb_cat(sb, "\nvoid VRT_purge(const char *, int hash);\n"); + vsb_cat(sb, "\nvoid VRT_panic(struct sess *sp, const char *, ...);\n"); + vsb_cat(sb, "void VRT_purge(struct sess *sp, char *, ...);\n"); vsb_cat(sb, "\nvoid VRT_count(const struct sess *, unsigned);\n"); vsb_cat(sb, "int VRT_rewrite(const char *, const char *);\n"); vsb_cat(sb, "void VRT_error(struct sess *, unsigned, const char *);"); -- 2.39.5