]> err.no Git - varnish/commitdiff
Implement purging on either of hash or url.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 8 Aug 2007 19:43:51 +0000 (19:43 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 8 Aug 2007 19:43:51 +0000 (19:43 +0000)
In VCL:
purge_url(<regexp>)
purge_hash(<regexp>)
(for an interrim period purge(<regexp>) will be the same as purge_url).
In CLI
url.purge <regexp>
hash.purge <regexp>

purge_hash operates on the hash-string which results from vcl_hash(),
by default it is composed of:

req.url "#" req.http.host "#"

To purge everything on the virtual host foo.bar.com:

In CLI:
url.purge "#foo.bar.com#$"

In VCL:
purge_hash("#foo.bar.com#$");

The general format, if you have defined vcl_hash(), is:

Each "req.hash +=" operator appends the right hand side of the
+= and a "#" separator.

You'll have to figure out your own regexps.

Under the hood:

Move the hash string from object to objecthead and save space while
we're at it.

Fix indentation in generated source.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1816 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_ban.c
varnish-cache/bin/varnishd/cache_cli.c
varnish-cache/bin/varnishd/cache_hash.c
varnish-cache/bin/varnishd/cache_vrt.c
varnish-cache/bin/varnishd/hash_classic.c
varnish-cache/bin/varnishd/hash_simple_list.c
varnish-cache/include/cli.h
varnish-cache/include/vrt.h
varnish-cache/lib/libvcl/vcc_action.c
varnish-cache/lib/libvcl/vcc_fixed_token.c

index b28c0c75a79ff5db338eae80da11cb24fcf68d30..ba6b426fc6b25ccc7557e82e2a55197d66662e5d 100644 (file)
@@ -262,6 +262,8 @@ struct objhead {
 
        pthread_mutex_t         mtx;
        TAILQ_HEAD(,object)     objects;
+       char                    *hash;
+       unsigned                hashlen;
 };
 
 /* -------------------------------------------------------------------*/
@@ -368,11 +370,12 @@ struct bereq *vbe_new_bereq(void);
 void vbe_free_bereq(struct bereq *bereq);
 
 /* cache_ban.c */
-void AddBan(const char *);
+void AddBan(const char *, int hash);
 void BAN_Init(void);
 void cli_func_url_purge(struct cli *cli, char **av, void *priv);
+void cli_func_hash_purge(struct cli *cli, char **av, void *priv);
 void BAN_NewObj(struct object *o);
-int BAN_CheckObject(struct object *o, const char *url);
+int BAN_CheckObject(struct object *o, const char *url, const char *hash);
 
 /* cache_center.c [CNT] */
 void CNT_Session(struct sess *sp);
@@ -392,8 +395,8 @@ int Fetch(struct sess *sp);
 
 /* cache_hash.c */
 void HSH_Prealloc(struct sess *sp);
-int HSH_Compare(struct sess *sp, const char *b, const char *e);
-void HSH_Copy(struct sess *sp, char *b, const char *e);
+int HSH_Compare(struct sess *sp, struct objhead *o);
+void HSH_Copy(struct sess *sp, struct objhead *o);
 struct object *HSH_Lookup(struct sess *sp);
 void HSH_Unbusy(struct object *o);
 void HSH_Ref(struct object *o);
index e56c6cbd082373aa540c201a5fdd31f184eca3ad..d29ced3fdf0b58120778f95ed9d4c28eeedac82c 100644 (file)
@@ -46,6 +46,7 @@ struct ban {
        unsigned                gen;
        regex_t                 regexp;
        char                    *ban;
+       int                     hash;
 };
 
 static TAILQ_HEAD(,ban) ban_head = TAILQ_HEAD_INITIALIZER(ban_head);
@@ -53,7 +54,7 @@ static unsigned ban_next;
 static struct ban *ban_start;
 
 void
-AddBan(const char *regexp)
+AddBan(const char *regexp, int hash)
 {
        struct ban *b;
        int i;
@@ -68,6 +69,7 @@ AddBan(const char *regexp)
                (void)regerror(i, &b->regexp, buf, sizeof buf);
                VSL(SLT_Debug, 0, "REGEX: <%s>", buf);
        }
+       b->hash = hash;
        b->gen = ++ban_next;
        b->ban = strdup(regexp);
        TAILQ_INSERT_HEAD(&ban_head, b, list);
@@ -82,7 +84,7 @@ BAN_NewObj(struct object *o)
 }
 
 int
-BAN_CheckObject(struct object *o, const char *url)
+BAN_CheckObject(struct object *o, const char *url, const char *hash)
 {
        struct ban *b, *b0;
        int i;
@@ -91,7 +93,7 @@ BAN_CheckObject(struct object *o, const char *url)
        for (b = b0;
            b != NULL && b->gen > o->ban_seq;
            b = TAILQ_NEXT(b, list)) {
-               i = regexec(&b->regexp, url, 0, NULL, 0);
+               i = regexec(&b->regexp, b->hash ? hash : url, 0, NULL, 0);
                if (!i)
                        return (1);
        }
@@ -104,7 +106,16 @@ cli_func_url_purge(struct cli *cli, char **av, void *priv)
 {
 
        (void)priv;
-       AddBan(av[2]);
+       AddBan(av[2], 0);
+       cli_out(cli, "PURGE %s\n", av[2]);
+}
+
+void
+cli_func_hash_purge(struct cli *cli, char **av, void *priv)
+{
+
+       (void)priv;
+       AddBan(av[2], 1);
        cli_out(cli, "PURGE %s\n", av[2]);
 }
 
@@ -112,5 +123,5 @@ void
 BAN_Init(void)
 {
 
-       AddBan("a");
+       AddBan("\001", 0);
 }
index 43ccae7e169fb26c4a838ac47eb2ebdb59402722..8eb7cfe933fb4ba0e135929b227b48f3c4ad40b9 100644 (file)
@@ -67,6 +67,7 @@ struct cli_proto CLI_cmds[] = {
        { CLI_URL_QUERY,        cli_func_url_query },
 #endif
        { CLI_URL_PURGE,        cli_func_url_purge },
+       { CLI_HASH_PURGE,       cli_func_hash_purge },
        { CLI_VCL_LOAD,         cli_func_config_load },
        { CLI_VCL_LIST,         cli_func_config_list },
        { CLI_VCL_DISCARD,      cli_func_config_discard },
index 1453922a5026293722fdc9b6ea1e0727dea5a0b9..55e90def0f90329ea480d8790a2a7cd8bf1eb83c 100644 (file)
@@ -110,14 +110,16 @@ HSH_Freestore(struct object *o)
 }
 
 int
-HSH_Compare(struct sess *sp, const char *b, const char *e)
+HSH_Compare(struct sess *sp, struct objhead *obj)
 {
        int i;
        unsigned u, v;
+       const char *b;
 
-       i = sp->lhashptr - (e - b);
+       i = sp->lhashptr - obj->hashlen;
        if (i)
                return (i);
+       b = obj->hash;
        for (u = 0; u < sp->ihashptr; u += 2) {
                v = sp->hashptr[u + 1] - sp->hashptr[u];
                i = memcmp(sp->hashptr[u], b, v);
@@ -130,16 +132,19 @@ HSH_Compare(struct sess *sp, const char *b, const char *e)
        }
        assert(*b == '\0');
        b++;
-       assert(b == e);
+       assert(b == obj->hash + obj->hashlen);
+       VSL(SLT_Debug, sp->fd, "Hash Match: %s", obj->hash);
        return (0);
 }
 
 void
-HSH_Copy(struct sess *sp, char *b, const char *e)
+HSH_Copy(struct sess *sp, struct objhead *obj)
 {
        unsigned u, v;
+       char *b;
 
-       assert((e - b) >= sp->lhashptr);
+       assert(obj->hashlen >= sp->lhashptr);
+       b = obj->hash;
        for (u = 0; u < sp->ihashptr; u += 2) {
                v = sp->hashptr[u + 1] - sp->hashptr[u];
                memcpy(b, sp->hashptr[u], v);
@@ -147,7 +152,8 @@ HSH_Copy(struct sess *sp, char *b, const char *e)
                *b++ = '#';
        }
        *b++ = '\0';
-       assert(b <= e);
+       VSL(SLT_Debug, sp->fd, "Hash: %s", obj->hash);
+       assert(b <= obj->hash + obj->hashlen);
 }
 
 struct object *
@@ -195,7 +201,8 @@ HSH_Lookup(struct sess *sp)
                        /* Object banned but not reaped yet */
                } else if (o->ttl <= sp->t_req) {
                        /* Object expired */
-               } else if (BAN_CheckObject(o, h->hd[HTTP_HDR_URL].b)) {
+               } else if (BAN_CheckObject(o,
+                   h->hd[HTTP_HDR_URL].b, oh->hash)) {
                        o->ttl = 0;
                        VSL(SLT_ExpBan, 0, "%u was banned", o->xid);
                        if (o->heap_idx != 0)
index bb17e9bd29badd696414fb07076bb5b419ca86a7..d8b2d86661198994c16fe60d60d8b918ddfc161f 100644 (file)
@@ -552,8 +552,8 @@ VRT_int_string(struct sess *sp, int num)
 /*--------------------------------------------------------------------*/
 
 void
-VRT_purge(const char *regexp)
+VRT_purge(const char *regexp, int hash)
 {
        
-       AddBan(regexp);
+       AddBan(regexp, hash);
 }
index 928a9f036ba84571df89d34b8d7610267f5aa419..a52f86671ba7b1cb20c5e18fbb3b997b5a4d651e 100644 (file)
@@ -46,8 +46,6 @@ struct hcl_entry {
 #define HCL_ENTRY_MAGIC                0x0ba707bf
        TAILQ_ENTRY(hcl_entry)  list;
        struct hcl_hd           *head;
-       char                    *key;
-       unsigned                klen;
        struct objhead          *oh;
        unsigned                refcnt;
        unsigned                digest;
@@ -146,15 +144,15 @@ hcl_lookup(struct sess *sp, struct objhead *noh)
                LOCK(&hp->mtx);
                TAILQ_FOREACH(he, &hp->head, list) {
                        CHECK_OBJ_NOTNULL(he, HCL_ENTRY_MAGIC);
-                       if (sp->lhashptr < he->klen)
+                       if (sp->lhashptr < he->oh->hashlen)
                                continue;
-                       if (sp->lhashptr > he->klen)
+                       if (sp->lhashptr > he->oh->hashlen)
                                break;
                        if (he->digest < digest)
                                continue;
                        if (he->digest > digest)
                                break;
-                       i = HSH_Compare(sp, he->key, he->key + he->klen);
+                       i = HSH_Compare(sp, he->oh);
                        if (i < 0)
                                continue;
                        if (i > 0)
@@ -182,19 +180,19 @@ hcl_lookup(struct sess *sp, struct objhead *noh)
                }
                UNLOCK(&hp->mtx);
 
-               i = sizeof *he2 + sp->lhashptr;
-               he2 = calloc(i, 1);
+               he2 = calloc(sizeof *he2, 1);
                XXXAN(he2);
                he2->magic = HCL_ENTRY_MAGIC;
                he2->oh = noh;
                he2->digest = digest;
                he2->hash = u1;
                he2->head = hp;
-               he2->klen = sp->lhashptr;
-               noh->hashpriv = he2;
 
-               he2->key = (void*)(he2 + 1);
-               HSH_Copy(sp, he2->key, he2->key + sp->lhashptr);
+               noh->hashpriv = he2;
+               noh->hash = malloc(sp->lhashptr);
+               XXXAN(noh->hash);
+               noh->hashlen = sp->lhashptr;
+               HSH_Copy(sp, noh);
        }
        assert(he2 == NULL);            /* FlexeLint */
        INCOMPL();
index d5158af3a2340aa161023c547f3bdc007abf7fa4..ba265274496ebd6c2945147ade204a3df0796936 100644 (file)
@@ -44,8 +44,6 @@
 
 struct hsl_entry {
        TAILQ_ENTRY(hsl_entry)  list;
-       char                    *key;
-       int                     keylen;
        struct objhead          *obj;
        unsigned                refcnt;
 };
@@ -80,7 +78,7 @@ hsl_lookup(struct sess *sp, struct objhead *nobj)
 
        LOCK(&hsl_mutex);
        TAILQ_FOREACH(he, &hsl_head, list) {
-               i = HSH_Compare(sp, he->key, he->key + he->keylen);
+               i = HSH_Compare(sp, he->obj);
                if (i < 0)
                        continue;
                if (i > 0)
@@ -94,14 +92,17 @@ hsl_lookup(struct sess *sp, struct objhead *nobj)
                UNLOCK(&hsl_mutex);
                return (NULL);
        }
-       he2 = calloc(sizeof *he2 + sp->lhashptr, 1);
+       he2 = calloc(sizeof *he2, 1);
        XXXAN(he2);
        he2->obj = nobj;
        he2->refcnt = 1;
-       he2->key = (void*)(he2 + 1);
-       he2->keylen = sp->lhashptr;
-       HSH_Copy(sp, he2->key, he2->key + he2->keylen);
+
        nobj->hashpriv = he2;
+       nobj->hash = malloc(sp->lhashptr);
+       XXXAN(nobj->hash);
+       nobj->hashlen = sp->lhashptr;
+       HSH_Copy(sp, nobj);
+
        if (he != NULL)
                TAILQ_INSERT_BEFORE(he, he2, list);
        else
index 2852b208a0c9d8019c6c40d5097f48478b8c8f00..931884a956b49dbdc4a8eb14dca1370365de3cf6 100644 (file)
 #define CLI_URL_PURGE                                                  \
        "url.purge",                                                    \
        "url.purge <regexp>",                                           \
-       "\tAll urls matching regexp will consider currently cached\n"   \
-           "\tobjects obsolete",                                       \
+       "\tAll objects where the urls matches regexp will be "          \
+           "marked obsolete.",                                         \
+       1, 1
+
+#define CLI_HASH_PURGE                                                 \
+       "hash.purge",                                                   \
+       "hash.purge <regexp>",                                          \
+       "\tAll objects where the hash string matches regexp will be "   \
+           "marked obsolete.",                                         \
        1, 1
 
 #define CLI_URL_STATUS                                                 \
index 7edf14f42a17486501c45fe76bb6ac4d2aea5bf7..840aaf04bd1d6af839a45a108075bd4d30887347 100644 (file)
@@ -70,7 +70,7 @@ int VRT_re_match(const char *, void *re);
 int VRT_re_test(struct vsb *, const char *, int sub);
 const char *VRT_regsub(struct sess *sp, const char *, void *, const char *);
 
-void VRT_purge(const char *);
+void VRT_purge(const char *, int hash);
 
 void VRT_count(struct sess *, unsigned);
 int VRT_rewrite(const char *, const char *);
index 6ad2cdadc07a31c712bf565e617ff46b66073262..5cad91eaaa983eca313dc584b240dec9112347cd 100644 (file)
@@ -273,12 +273,12 @@ parse_remove(struct tokenlist *tl)
 /*--------------------------------------------------------------------*/
 
 static void
-parse_purge(struct tokenlist *tl)
+parse_purge_url(struct tokenlist *tl)
 {
 
        vcc_NextToken(tl);
        
-       Fb(tl, 0, "VRT_purge(");
+       Fb(tl, 1, "VRT_purge(");
        
        Expect(tl, '(');
        vcc_NextToken(tl);
@@ -290,7 +290,31 @@ parse_purge(struct tokenlist *tl)
        
        Expect(tl, ')');
        vcc_NextToken(tl);
-       Fb(tl, 0, ");");
+       Fb(tl, 0, ", 0);\n");
+}
+
+
+/*--------------------------------------------------------------------*/
+
+static void
+parse_purge_hash(struct tokenlist *tl)
+{
+
+       vcc_NextToken(tl);
+       
+       Fb(tl, 1, "VRT_purge(");
+       
+       Expect(tl, '(');
+       vcc_NextToken(tl);
+       
+       if (!vcc_StringVal(tl)) {
+               vcc_ExpectedStringval(tl);
+               return;
+       }
+       
+       Expect(tl, ')');
+       vcc_NextToken(tl);
+       Fb(tl, 0, ", 1);\n");
 }
 
 
@@ -310,7 +334,12 @@ static struct action_table {
        { "call",       parse_call },
        { "set",        parse_set },
        { "remove",     parse_remove },
-       { "purge",      parse_purge },
+       { "purge_url",  parse_purge_url },
+       { "purge_hash", parse_purge_hash },
+
+       /* XXX: Compat remove in 1.2/2.0 */
+       { "purge",      parse_purge_url },
+
        { NULL,         NULL }
 };
 
index 3a0dd45f8068498673c8f22d55b99465ddb0c442..60af001753179908a4cbacb29caac79673e150b0 100644 (file)
@@ -428,7 +428,7 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "int VRT_re_test(struct vsb *, const char *, int sub);\n");
        vsb_cat(sb, "const char *VRT_regsub(struct sess *sp, const char *, void *, const char *);\n");
        vsb_cat(sb, "\n");
-       vsb_cat(sb, "void VRT_purge(const char *);\n");
+       vsb_cat(sb, "void VRT_purge(const char *, int hash);\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "void VRT_count(struct sess *, unsigned);\n");
        vsb_cat(sb, "int VRT_rewrite(const char *, const char *);\n");