Commit bedfc9f4 authored by Geoff Simmons's avatar Geoff Simmons

added match_dyn()

parent 7bcd7cce
...@@ -13,6 +13,10 @@ varnish v1 -vcl+backend { ...@@ -13,6 +13,10 @@ varnish v1 -vcl+backend {
return(pass); return(pass);
} else if (re.match(req.url, "snafu")) { } else if (re.match(req.url, "snafu")) {
return(pipe); return(pipe);
} else if ((re.match_dyn(req.url, "foobar"))) {
return(pass);
} else if (re.match_dyn(req.url, "snafu")) {
return(pipe);
} else { } else {
return(pass); return(pass);
} }
...@@ -24,11 +28,24 @@ varnish v1 -vcl+backend { ...@@ -24,11 +28,24 @@ varnish v1 -vcl+backend {
} else { } else {
error 999; error 999;
} }
if (!re.match(beresp.http.bar, "bar")) { if (!re.match(beresp.http.bar, "bar")) {
set beresp.http.bar1 = "2"; set beresp.http.bar1 = "2";
} else { } else {
error 999; error 999;
} }
if (re.match_dyn(beresp.http.foo, "bar")) {
set beresp.http.foo1d = "1";
} else {
error 999;
}
if (!re.match_dyn(beresp.http.bar, "bar")) {
set beresp.http.bar1d = "2";
} else {
error 999;
}
} }
} -start } -start
...@@ -38,4 +55,6 @@ client c1 { ...@@ -38,4 +55,6 @@ client c1 {
rxresp rxresp
expect resp.http.foo1 == "1" expect resp.http.foo1 == "1"
expect resp.http.bar1 == "2" expect resp.http.bar1 == "2"
expect resp.http.foo1d == "1"
expect resp.http.bar1d == "2"
} -run } -run
...@@ -3,9 +3,9 @@ varnishtest "cached compiled regexen" ...@@ -3,9 +3,9 @@ varnishtest "cached compiled regexen"
# run two clients, to test caching of compiled regexen # run two clients, to test caching of compiled regexen
server s1 { server s1 {
rxreq rxreq
txresp -hdr "Foo: barbaz" -hdr "Bar: bazquux" -body "1111\n" txresp -hdr "Foo: barbaz" -body "1111\n"
rxreq rxreq
txresp -hdr "Foo: barbaz" -hdr "Bar: bazquux" -body "1111\n" txresp -hdr "Foo: barbaz" -body "1111\n"
} -start } -start
varnish v1 -vcl+backend { varnish v1 -vcl+backend {
...@@ -18,6 +18,13 @@ varnish v1 -vcl+backend { ...@@ -18,6 +18,13 @@ varnish v1 -vcl+backend {
} else { } else {
error 999; error 999;
} }
if (re.match_dyn(beresp.http.foo, "(bar)(baz)")) {
set beresp.http.foo1d = re.backref(1, "error1");
set beresp.http.foo2d = re.backref(2, "error2");
} else {
error 999;
}
} }
} -start } -start
...@@ -27,6 +34,8 @@ client c1 { ...@@ -27,6 +34,8 @@ client c1 {
rxresp rxresp
expect resp.http.foo1 == "bar" expect resp.http.foo1 == "bar"
expect resp.http.foo2 == "baz" expect resp.http.foo2 == "baz"
expect resp.http.foo1d == "bar"
expect resp.http.foo2d == "baz"
} -run } -run
client c2 { client c2 {
...@@ -34,4 +43,6 @@ client c2 { ...@@ -34,4 +43,6 @@ client c2 {
rxresp rxresp
expect resp.http.foo1 == "bar" expect resp.http.foo1 == "bar"
expect resp.http.foo2 == "baz" expect resp.http.foo2 == "baz"
expect resp.http.foo1d == "bar"
expect resp.http.foo2d == "baz"
} -run } -run
...@@ -11,7 +11,11 @@ varnish v1 -vcl+backend { ...@@ -11,7 +11,11 @@ varnish v1 -vcl+backend {
sub vcl_recv { sub vcl_recv {
if (re.match(req.http.host, "^(abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij)")) { if (re.match(req.http.host, "^(abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij)")) {
error 500 "not ok"; error 500 "not ok";
} }
if (re.match_dyn(req.http.host, "^(abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij|abcdefghij)")) {
error 500 "not ok";
}
} }
} -start } -start
......
...@@ -2,7 +2,6 @@ varnishtest "test null match (varnish r00913.vtc)" ...@@ -2,7 +2,6 @@ varnishtest "test null match (varnish r00913.vtc)"
server s1 { server s1 {
rxreq rxreq
expect req.url == "/bar"
txresp -body "foobar" txresp -body "foobar"
} -start } -start
...@@ -16,13 +15,21 @@ varnish v1 -vcl+backend { ...@@ -16,13 +15,21 @@ varnish v1 -vcl+backend {
if (re.match(beresp.http.foo, "")) { if (re.match(beresp.http.foo, "")) {
set beresp.http.bar = "YYY"; set beresp.http.bar = "YYY";
} }
if (re.match_dyn(beresp.http.bar, "$")) {
set beresp.http.food = "XXX";
}
if (re.match_dyn(beresp.http.foo, "")) {
set beresp.http.bard = "YYY";
}
} }
} -start } -start
client c1 { client c1 {
txreq -url /bar -hdr "Foo: bar" txreq
rxresp rxresp
expect resp.http.content-length == 6 expect resp.http.content-length == 6
expect resp.http.foo == "XXX" expect resp.http.foo == "XXX"
expect resp.http.bar == "YYY" expect resp.http.bar == "YYY"
expect resp.http.food == "XXX"
expect resp.http.bard == "YYY"
} -run } -run
varnishtest "regex compilation failre" varnishtest "regex compilation failure"
server s1 { server s1 {
rxreq rxreq
txresp -hdr "Foo: bar" -body "foobar" txresp -hdr "Foo: bar" -hdr "Baz: quux" -body "foobar"
} -start } -start
varnish v1 -vcl+backend { varnish v1 -vcl+backend {
...@@ -12,6 +12,9 @@ varnish v1 -vcl+backend { ...@@ -12,6 +12,9 @@ varnish v1 -vcl+backend {
if (re.match(beresp.http.foo, "(")) { if (re.match(beresp.http.foo, "(")) {
set beresp.http.foo = "baz"; set beresp.http.foo = "baz";
} }
if (re.match_dyn(beresp.http.baz, "(")) {
set beresp.http.baz = "waldo";
}
} }
} -start } -start
...@@ -20,4 +23,5 @@ client c1 { ...@@ -20,4 +23,5 @@ client c1 {
rxresp rxresp
expect resp.http.content-length == 6 expect resp.http.content-length == 6
expect resp.http.foo == "bar" expect resp.http.foo == "bar"
expect resp.http.baz == "quux"
} -run } -run
varnishtest "dynamic matches"
server s1 {
rxreq
txresp -hdr "Foo: baz" -hdr "Bar: baz" -body "foobar"
rxreq
expect req.url == "/foo"
txresp -hdr "Foo: baz" -hdr "Bar: quux" -body "foobar"
} -start
varnish v1 -vcl+backend {
import re from "${vmod_topbuild}/src/.libs/libvmod_re.so";
sub vcl_fetch {
if (re.match(beresp.http.foo, beresp.http.bar)) {
set beresp.http.static = "match";
}
else {
set beresp.http.static = "nomatch";
}
if (re.match_dyn(beresp.http.foo, beresp.http.bar)) {
set beresp.http.dynamic = "match";
}
else {
set beresp.http.dynamic = "nomatch";
}
}
} -start
client c1 {
txreq
rxresp
expect resp.http.foo == "baz"
expect resp.http.bar == "baz"
expect resp.http.static == "match"
expect resp.http.dynamic == "match"
txreq -url "/foo"
rxresp
expect resp.http.foo == "baz"
expect resp.http.bar == "quux"
expect resp.http.static == "match"
expect resp.http.dynamic == "nomatch"
} -run
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
struct sess_ov { struct sess_ov {
unsigned magic; unsigned magic;
#define SESS_OV_MAGIC 0x844bfa39 #define SESS_OV_MAGIC 0x844bfa39
const char *pattern;
char *subject; char *subject;
int ovector[MAX_OV]; int ovector[MAX_OV];
int count; int count;
...@@ -110,44 +111,49 @@ re_init(struct vmod_priv *priv, ...@@ -110,44 +111,49 @@ re_init(struct vmod_priv *priv,
return (0); return (0);
} }
unsigned __match_proto__() static unsigned
vmod_match(struct sess *sp, struct vmod_priv *priv_vcl, match(struct sess *sp, struct vmod_priv *priv_vcl, struct vmod_priv *priv_call,
struct vmod_priv *priv_call, const char *str, const char *pattern) const char *str, const char *pattern, int dynamic)
{ {
vre_t *re; vre_t *re;
struct sess_tbl *tbl; struct sess_tbl *tbl;
int s; int s;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
AN(pattern);
CAST_OBJ_NOTNULL(tbl, priv_vcl->priv, SESS_TBL_MAGIC); CAST_OBJ_NOTNULL(tbl, priv_vcl->priv, SESS_TBL_MAGIC);
assert(sp->id < tbl->nsess); assert(sp->id < tbl->nsess);
CHECK_OBJ_NOTNULL(&tbl->sess[sp->id], SESS_OV_MAGIC); CHECK_OBJ_NOTNULL(&tbl->sess[sp->id], SESS_OV_MAGIC);
if (str == NULL) AN(pattern);
str = "";
if (priv_call->priv == NULL) { if (priv_call->priv == NULL
|| (dynamic && pattern != tbl->sess[sp->id].pattern)) {
int erroffset = 0; int erroffset = 0;
const char *error = NULL; const char *error = NULL;
AZ(pthread_mutex_lock(&re_mutex)); AZ(pthread_mutex_lock(&re_mutex));
if (priv_call->priv == NULL) { if (priv_call->priv == NULL
|| (dynamic && strcmp(pattern,tbl->sess[sp->id].pattern))) {
priv_call->priv = VRE_compile(pattern, 0, &error, priv_call->priv = VRE_compile(pattern, 0, &error,
&erroffset); &erroffset);
if (priv_call->priv == NULL) if (priv_call->priv == NULL)
WSP(sp, SLT_VCL_error, WSP(sp, SLT_VCL_error,
"vmod re: error compiling regex [%s]: " "vmod re: error compiling regex \"%s\": "
"%s at position %d", pattern, error, "%s (position %d)", pattern, error,
erroffset); erroffset);
else else
priv_call->free = VRT_re_fini; priv_call->free = VRT_re_fini;
} }
if (dynamic)
tbl->sess[sp->id].pattern
= WS_Dup(sp->wrk->ws, pattern);
AZ(pthread_mutex_unlock(&re_mutex)); AZ(pthread_mutex_unlock(&re_mutex));
} }
re = (vre_t *) priv_call->priv; re = (vre_t *) priv_call->priv;
if (re == NULL) if (re == NULL)
return 0; return 0;
if (str == NULL)
str = "";
s = VRE_exec(re, str, strlen(str), 0, 0, &tbl->sess[sp->id].ovector[0], s = VRE_exec(re, str, strlen(str), 0, 0, &tbl->sess[sp->id].ovector[0],
MAX_OV, &params->vre_limits); MAX_OV, &params->vre_limits);
tbl->sess[sp->id].count = s; tbl->sess[sp->id].count = s;
...@@ -162,6 +168,20 @@ vmod_match(struct sess *sp, struct vmod_priv *priv_vcl, ...@@ -162,6 +168,20 @@ vmod_match(struct sess *sp, struct vmod_priv *priv_vcl,
return 1; return 1;
} }
unsigned __match_proto__()
vmod_match(struct sess *sp, struct vmod_priv *priv_vcl,
struct vmod_priv *priv_call, const char *str, const char *pattern)
{
return(match(sp, priv_vcl, priv_call, str, pattern, 0));
}
unsigned __match_proto__()
vmod_match_dyn(struct sess *sp, struct vmod_priv *priv_vcl,
struct vmod_priv *priv_call, const char *str, const char *pattern)
{
return(match(sp, priv_vcl, priv_call, str, pattern, 1));
}
const char * __match_proto__() const char * __match_proto__()
vmod_backref(struct sess *sp, struct vmod_priv *priv_vcl, int refnum, vmod_backref(struct sess *sp, struct vmod_priv *priv_vcl, int refnum,
const char *fallback) const char *fallback)
......
Module re Module re
Init re_init Init re_init
Function BOOL match(PRIV_VCL, PRIV_CALL, STRING, STRING) Function BOOL match(PRIV_VCL, PRIV_CALL, STRING, STRING)
Function BOOL match_dyn(PRIV_VCL, PRIV_CALL, STRING, STRING)
Function STRING backref(PRIV_VCL, INT, STRING) Function STRING backref(PRIV_VCL, INT, STRING)
Function STRING version() Function STRING version()
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