Commit f6ebc9e4 authored by Tollef Fog Heen's avatar Tollef Fog Heen

Merge r3518: Implement exact matching and negatives for bans.

You can now purge using these four conditionals:

        purge req.url == "/diediedie.html"
        purge req.url != "/index.html"
        purge req.url !~ "\.html$"
        purge req.url ~ "\.jpg$"



git-svn-id: http://www.varnish-cache.org/svn/branches/2.0@3707 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent c3c8d232
...@@ -70,7 +70,11 @@ struct ban_test { ...@@ -70,7 +70,11 @@ struct ban_test {
int cost; int cost;
char *test; char *test;
ban_cond_f *func; ban_cond_f *func;
int flags;
#define BAN_T_REGEXP (1 << 0)
#define BAN_T_NOT (1 << 1)
regex_t re; regex_t re;
char *dst;
}; };
struct ban { struct ban {
...@@ -145,7 +149,10 @@ ban_free_ban(struct ban *b) ...@@ -145,7 +149,10 @@ ban_free_ban(struct ban *b)
bt = VTAILQ_FIRST(&b->tests); bt = VTAILQ_FIRST(&b->tests);
VTAILQ_REMOVE(&b->tests, bt, list); VTAILQ_REMOVE(&b->tests, bt, list);
free(bt->test); free(bt->test);
regfree(&bt->re); if (bt->flags & BAN_T_REGEXP)
regfree(&bt->re);
if (bt->dst != NULL)
free(bt->dst);
FREE_OBJ(bt); FREE_OBJ(bt);
} }
FREE_OBJ(b); FREE_OBJ(b);
...@@ -188,33 +195,67 @@ ban_compare(const struct ban *b1, const struct ban *b2) ...@@ -188,33 +195,67 @@ ban_compare(const struct ban *b1, const struct ban *b2)
*/ */
static int static int
ban_cond_url_regexp(const struct ban_test *bt, const struct object *o, ban_cond_str(const struct ban_test *bt, const char *p)
{
int i;
if (bt->flags & BAN_T_REGEXP)
i = regexec(&bt->re, p, 0, NULL, 0);
else
i = strcmp(bt->dst, p);
if (bt->flags & BAN_T_NOT)
return (i);
return (!i);
}
static int
ban_cond_url(const struct ban_test *bt, const struct object *o,
const struct sess *sp) const struct sess *sp)
{ {
(void)o; (void)o;
return (!regexec(&bt->re, sp->http->hd[HTTP_HDR_URL].b, 0, NULL, 0));
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return(ban_cond_str(bt, sp->http->hd[HTTP_HDR_URL].b));
} }
static int static int
ban_cond_hash_regexp(const struct ban_test *bt, const struct object *o, ban_cond_hash(const struct ban_test *bt, const struct object *o,
const struct sess *sp) const struct sess *sp)
{ {
(void)sp; (void)sp;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
CHECK_OBJ_NOTNULL(o->objhead, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(o->objhead, OBJHEAD_MAGIC);
AN(o->objhead->hash); AN(o->objhead->hash);
return (!regexec(&bt->re, o->objhead->hash, 0, NULL, 0)); return(ban_cond_str(bt, o->objhead->hash));
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Parse and add a ban test specification * Parse and add a ban test specification
*/ */
static int
ban_parse_regexp(struct cli *cli, struct ban_test *bt, const char *a3)
{
int i;
char buf[512];
i = regcomp(&bt->re, a3, REG_EXTENDED | REG_ICASE | REG_NOSUB);
if (i) {
(void)regerror(i, &bt->re, buf, sizeof buf);
regfree(&bt->re);
VSL(SLT_Debug, 0, "REGEX: <%s>", buf);
cli_out(cli, "%s", buf);
cli_result(cli, CLIS_PARAM);
return (-1);
}
bt->flags |= BAN_T_REGEXP;
return (0);
}
static int static int
ban_parse_test(struct cli *cli, struct ban *b, const char *a1, const char *a2, const char *a3) ban_parse_test(struct cli *cli, struct ban *b, const char *a1, const char *a2, const char *a3)
{ {
struct ban_test *bt; struct ban_test *bt;
char buf[512];
struct vsb *sb; struct vsb *sb;
int i; int i;
...@@ -226,27 +267,32 @@ ban_parse_test(struct cli *cli, struct ban *b, const char *a1, const char *a2, c ...@@ -226,27 +267,32 @@ ban_parse_test(struct cli *cli, struct ban *b, const char *a1, const char *a2, c
return (-1); return (-1);
} }
if (strcmp(a2, "~")) { if (!strcmp(a2, "~")) {
/* XXX: Add more conditionals */ i = ban_parse_regexp(cli, bt, a3);
cli_out(cli, "expected \"~\" got \"%s\"", a2); if (i)
cli_result(cli, CLIS_PARAM); return (i);
return (-1); } else if (!strcmp(a2, "!~")) {
} bt->flags |= BAN_T_NOT;
i = ban_parse_regexp(cli, bt, a3);
i = regcomp(&bt->re, a3, REG_EXTENDED | REG_ICASE | REG_NOSUB); if (i)
if (i) { return (i);
(void)regerror(i, &bt->re, buf, sizeof buf); } else if (!strcmp(a2, "==")) {
regfree(&bt->re); bt->dst = strdup(a3);
VSL(SLT_Debug, 0, "REGEX: <%s>", buf); XXXAN(bt->dst);
cli_out(cli, "%s", buf); } else if (!strcmp(a2, "!=")) {
bt->flags |= BAN_T_NOT;
bt->dst = strdup(a3);
XXXAN(bt->dst);
} else {
cli_out(cli,
"expected conditional (~, !~, == or !=) got \"%s\"", a2);
cli_result(cli, CLIS_PARAM); cli_result(cli, CLIS_PARAM);
return (-1); return (-1);
} }
if (!strcmp(a1, "req.url")) if (!strcmp(a1, "req.url"))
bt->func = ban_cond_url_regexp; bt->func = ban_cond_url;
else if (!strcmp(a1, "obj.hash")) else if (!strcmp(a1, "obj.hash"))
bt->func = ban_cond_hash_regexp; bt->func = ban_cond_hash;
else { else {
cli_out(cli, "unknown or unsupported field \"%s\"", a1); cli_out(cli, "unknown or unsupported field \"%s\"", a1);
cli_result(cli, CLIS_PARAM); cli_result(cli, CLIS_PARAM);
......
...@@ -28,6 +28,14 @@ varnish v1 -clierr 104 "purge foo bar" ...@@ -28,6 +28,14 @@ varnish v1 -clierr 104 "purge foo bar"
varnish v1 -clierr 106 "purge a b c && a" varnish v1 -clierr 106 "purge a b c && a"
varnish v1 -clierr 106 "purge a b c && a b" varnish v1 -clierr 106 "purge a b c && a b"
varnish v1 -clierr 106 "purge a b c || a b c" varnish v1 -clierr 106 "purge a b c || a b c"
varnish v1 -cliok "purge req.url == foo"
client c1 {
txreq -url "/foo"
rxresp
expect resp.status == 200
expect resp.http.content-length == 5
}
varnish v1 -cliok "purge req.url ~ foo && req.url ~ \"[ o]\"" varnish v1 -cliok "purge req.url ~ foo && req.url ~ \"[ o]\""
varnish v1 -cliok "purge.list" varnish v1 -cliok "purge.list"
......
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