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 {
int cost;
char *test;
ban_cond_f *func;
int flags;
#define BAN_T_REGEXP (1 << 0)
#define BAN_T_NOT (1 << 1)
regex_t re;
char *dst;
};
struct ban {
......@@ -145,7 +149,10 @@ ban_free_ban(struct ban *b)
bt = VTAILQ_FIRST(&b->tests);
VTAILQ_REMOVE(&b->tests, bt, list);
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(b);
......@@ -188,33 +195,67 @@ ban_compare(const struct ban *b1, const struct ban *b2)
*/
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)
{
(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
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)
{
(void)sp;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
CHECK_OBJ_NOTNULL(o->objhead, OBJHEAD_MAGIC);
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
*/
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
ban_parse_test(struct cli *cli, struct ban *b, const char *a1, const char *a2, const char *a3)
{
struct ban_test *bt;
char buf[512];
struct vsb *sb;
int i;
......@@ -226,27 +267,32 @@ ban_parse_test(struct cli *cli, struct ban *b, const char *a1, const char *a2, c
return (-1);
}
if (strcmp(a2, "~")) {
/* XXX: Add more conditionals */
cli_out(cli, "expected \"~\" got \"%s\"", a2);
cli_result(cli, CLIS_PARAM);
return (-1);
}
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);
if (!strcmp(a2, "~")) {
i = ban_parse_regexp(cli, bt, a3);
if (i)
return (i);
} else if (!strcmp(a2, "!~")) {
bt->flags |= BAN_T_NOT;
i = ban_parse_regexp(cli, bt, a3);
if (i)
return (i);
} else if (!strcmp(a2, "==")) {
bt->dst = strdup(a3);
XXXAN(bt->dst);
} 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);
return (-1);
}
if (!strcmp(a1, "req.url"))
bt->func = ban_cond_url_regexp;
bt->func = ban_cond_url;
else if (!strcmp(a1, "obj.hash"))
bt->func = ban_cond_hash_regexp;
bt->func = ban_cond_hash;
else {
cli_out(cli, "unknown or unsupported field \"%s\"", a1);
cli_result(cli, CLIS_PARAM);
......
......@@ -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 b"
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.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