Commit 6c8a3e77 authored by Geoff Simmons's avatar Geoff Simmons

Add the .re_match() method.

parent 4a899580
......@@ -32,6 +32,7 @@ CONTENTS
* :ref:`func_set.match`
* :ref:`func_set.matched`
* :ref:`func_set.nmatches`
* :ref:`func_set.re_match`
* :ref:`func_set.string`
* :ref:`func_set.which`
* :ref:`func_version`
......@@ -239,6 +240,28 @@ Example::
}
.. _func_set.re_match:
BOOL xset.re_match(STRING subject, INT n, ENUM select)
------------------------------------------------------
::
BOOL xset.re_match(
STRING subject,
INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
.. _func_set.debug:
STRING xset.debug()
......
# looks like -*- vcl -*-
varnishtest "string() method"
varnish v1 -vcl {
import ${vmod_selector};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set();
s.add("foo", regex="oof");
s.add("bar", regex="rab");
s.add("baz", regex="zab");
s.add("quux", regex="xuuq");
s.add("foobar", regex="raboof");
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
set resp.http.N-1 = s.re_match(req.http.Subject, 1);
set resp.http.N-2 = s.re_match(req.http.Subject, 2);
set resp.http.N-3 = s.re_match(req.http.Subject, 3);
set resp.http.N-4 = s.re_match(req.http.Subject, 4);
set resp.http.N-5 = s.re_match(req.http.Subject, 5);
set resp.http.N--1 = s.re_match(req.http.Subject, -1);
set resp.http.N-0 = s.re_match(req.http.Subject, 0);
set resp.http.N-6 = s.re_match(req.http.Subject, 6);
if (s.match(req.http.Word)) {
set resp.http.Match = s.re_match(req.http.Subject);
set resp.http.Match-Unique
= s.re_match(req.http.Subject, select=UNIQUE);
set resp.http.Match-Exact
= s.re_match(req.http.Subject, select=EXACT);
set resp.http.Match-First
= s.re_match(req.http.Subject, select=FIRST);
set resp.http.Match-Last
= s.re_match(req.http.Subject, select=LAST);
set resp.http.Match-Shortest
= s.re_match(req.http.Subject, select=SHORTEST);
set resp.http.Match-Longest
= s.re_match(req.http.Subject, select=LONGEST);
set resp.http.Nonmatch = s.re_match(req.http.Word);
set resp.http.Nonmatch-Unique
= s.re_match(req.http.Word, select=UNIQUE);
set resp.http.Nonmatch-Exact
= s.re_match(req.http.Word, select=EXACT);
set resp.http.Nonmatch-First
= s.re_match(req.http.Word, select=FIRST);
set resp.http.Nonmatch-Last
= s.re_match(req.http.Word, select=LAST);
set resp.http.Nonmatch-Shortest
= s.re_match(req.http.Word, select=SHORTEST);
set resp.http.Nonmatch-Longest
= s.re_match(req.http.Word, select=LONGEST);
}
return (deliver);
}
} -start
client c1 {
txreq -hdr "Word: foo" -hdr "Subject: oof"
rxresp
expect resp.status == 200
expect resp.http.N-1 == "true"
expect resp.http.N-2 == "false"
expect resp.http.N-3 == "false"
expect resp.http.N-4 == "false"
expect resp.http.N-5 == "false"
expect resp.http.N--1 == "false"
expect resp.http.N-0 == "false"
expect resp.http.N-6 == "false"
expect resp.http.Match == "true"
expect resp.http.Match-Unique == resp.http.Match
expect resp.http.Match-Exact == resp.http.Match
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "true"
expect resp.http.Match-Shortest == "true"
expect resp.http.Match-Longest == "true"
expect resp.http.Nonmatch == "false"
expect resp.http.Nonmatch-Unique == resp.http.Nonmatch
expect resp.http.Nonmatch-Exact == resp.http.Nonmatch
expect resp.http.Nonmatch-First == "false"
expect resp.http.Nonmatch-Last == "false"
expect resp.http.Nonmatch-Shortest == "false"
expect resp.http.Nonmatch-Longest == "false"
txreq -hdr "Word: bar" -hdr "Subject: rab"
rxresp
expect resp.status == 200
expect resp.http.N-1 == "false"
expect resp.http.N-2 == "true"
expect resp.http.N-3 == "false"
expect resp.http.N-4 == "false"
expect resp.http.N-5 == "false"
expect resp.http.Match == "true"
expect resp.http.Match-Unique == resp.http.Match
expect resp.http.Match-Exact == resp.http.Match
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "true"
expect resp.http.Match-Shortest == "true"
expect resp.http.Match-Longest == "true"
expect resp.http.Nonmatch == "false"
expect resp.http.Nonmatch-Unique == resp.http.Nonmatch
expect resp.http.Nonmatch-Exact == resp.http.Nonmatch
expect resp.http.Nonmatch-First == "false"
expect resp.http.Nonmatch-Last == "false"
expect resp.http.Nonmatch-Shortest == "false"
expect resp.http.Nonmatch-Longest == "false"
txreq -hdr "Word: baz" -hdr "Subject: zab"
rxresp
expect resp.status == 200
expect resp.http.N-1 == "false"
expect resp.http.N-2 == "false"
expect resp.http.N-3 == "true"
expect resp.http.N-4 == "false"
expect resp.http.N-5 == "false"
expect resp.http.Match == "true"
expect resp.http.Match-Unique == resp.http.Match
expect resp.http.Match-Exact == resp.http.Match
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "true"
expect resp.http.Match-Shortest == "true"
expect resp.http.Match-Longest == "true"
expect resp.http.Nonmatch == "false"
expect resp.http.Nonmatch-Unique == resp.http.Nonmatch
expect resp.http.Nonmatch-Exact == resp.http.Nonmatch
expect resp.http.Nonmatch-First == "false"
expect resp.http.Nonmatch-Last == "false"
expect resp.http.Nonmatch-Shortest == "false"
expect resp.http.Nonmatch-Longest == "false"
txreq -hdr "Word: quux" -hdr "Subject: xuuq"
rxresp
expect resp.status == 200
expect resp.http.N-1 == "false"
expect resp.http.N-2 == "false"
expect resp.http.N-3 == "false"
expect resp.http.N-4 == "true"
expect resp.http.N-5 == "false"
expect resp.http.Match == "true"
expect resp.http.Match-Unique == resp.http.Match
expect resp.http.Match-Exact == resp.http.Match
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "true"
expect resp.http.Match-Shortest == "true"
expect resp.http.Match-Longest == "true"
expect resp.http.Nonmatch == "false"
expect resp.http.Nonmatch-Unique == resp.http.Nonmatch
expect resp.http.Nonmatch-Exact == resp.http.Nonmatch
expect resp.http.Nonmatch-First == "false"
expect resp.http.Nonmatch-Last == "false"
expect resp.http.Nonmatch-Shortest == "false"
expect resp.http.Nonmatch-Longest == "false"
txreq -hdr "Word: foobar" -hdr "Subject: raboof"
rxresp
expect resp.status == 200
# "raboof" matches /oof/, /rab/ and /raboof/
expect resp.http.N-1 == "true"
expect resp.http.N-2 == "true"
expect resp.http.N-3 == "false"
expect resp.http.N-4 == "false"
expect resp.http.N-5 == "true"
expect resp.http.Match == "true"
expect resp.http.Match-Unique == resp.http.Match
expect resp.http.Match-Exact == resp.http.Match
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "true"
expect resp.http.Match-Shortest == "true"
expect resp.http.Match-Longest == "true"
expect resp.http.Nonmatch == "false"
expect resp.http.Nonmatch-Unique == resp.http.Nonmatch
expect resp.http.Nonmatch-Exact == resp.http.Nonmatch
expect resp.http.Nonmatch-First == "false"
expect resp.http.Nonmatch-Last == "false"
expect resp.http.Nonmatch-Shortest == "false"
expect resp.http.Nonmatch-Longest == "false"
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error {^vmod selector error: s\.re_match\(\) called without prior match$}
expect * = VCL_Error {^vmod selector error: s\.re_match\(\) called without prior match$}
expect * = VCL_Error {^vmod selector error: s\.re_match\(6\): set has 5 elements$}
expect * = End
} -run
varnish v1 -vcl {
import ${vmod_selector};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set();
s.add("foobarbazquux", regex="foo");
s.add("foobarbaz", regex="bar");
s.add("foobar", regex="baz");
s.add("foo", regex="quux");
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
if (s.hasprefix(req.http.Word)) {
set resp.http.Match = s.re_match(req.http.Subject);
set resp.http.Match-Unique
= s.re_match(req.http.Subject, select=UNIQUE);
set resp.http.Match-Exact
= s.re_match(req.http.Subject, select=EXACT);
set resp.http.Match-First
= s.re_match(req.http.Subject, select=FIRST);
set resp.http.Match-Last
= s.re_match(req.http.Subject, select=LAST);
set resp.http.Match-Shortest
= s.re_match(req.http.Subject, select=SHORTEST);
set resp.http.Match-Longest
= s.re_match(req.http.Subject, select=LONGEST);
}
return (deliver);
}
}
logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect * 1008 Begin req
expect * = VCL_Error {^vmod selector error: s\.re_match\(select=UNIQUE\): 2 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.re_match\(select=UNIQUE\): 2 elements were matched$}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {^vmod selector error: s\.re_match\(select=UNIQUE\): 3 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.re_match\(select=UNIQUE\): 3 elements were matched$}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {^vmod selector error: s\.re_match\(select=UNIQUE\): 4 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.re_match\(select=UNIQUE\): 4 elements were matched$}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {^vmod selector error: s\.re_match\(select=UNIQUE\): 2 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.re_match\(select=UNIQUE\): 2 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.re_match\(select=EXACT\): no element matched exactly$}
expect * = End
} -start
client c1 {
txreq -hdr "Word: foo" -hdr "Subject: quux"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.Match-Unique == "true"
expect resp.http.Match-Exact == "true"
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "true"
expect resp.http.Match-Shortest == "true"
expect resp.http.Match-Longest == "true"
txreq -hdr "Word: foobar" -hdr "Subject: baz"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.Match-Unique == "false"
expect resp.http.Match-Exact == "true"
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "false"
expect resp.http.Match-Shortest == "false"
expect resp.http.Match-Longest == "true"
txreq -hdr "Word: foobarbaz" -hdr "Subject: bar"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.Match-Unique == "false"
expect resp.http.Match-Exact == "true"
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "false"
expect resp.http.Match-Shortest == "false"
expect resp.http.Match-Longest == "true"
txreq -hdr "Word: foobarbazquux" -hdr "Subject: foo"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.Match-Unique == "false"
expect resp.http.Match-Exact == "true"
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "false"
expect resp.http.Match-Shortest == "false"
expect resp.http.Match-Longest == "true"
txreq -hdr "Word: foobarb" -hdr "Subject: baz"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.Match-Unique == "false"
expect resp.http.Match-Exact == "false"
expect resp.http.Match-First == "true"
expect resp.http.Match-Last == "false"
expect resp.http.Match-Shortest == "false"
expect resp.http.Match-Longest == "true"
} -run
logexpect l1 -wait
varnish v1 -vcl {
import ${vmod_selector};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set();
s.add("foo", regex="foo");
s.add("bar");
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
if (s.match(req.http.Word)) {
set resp.http.Match = s.re_match(req.http.Subject);
}
return (deliver);
}
}
logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error {^vmod selector error: s\.re_match\(\): regex not added for element 2$}
expect * = End
} -start
client c1 {
txreq -hdr "Word: foo" -hdr "Subject: foo"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
txreq -hdr "Word: bar" -hdr "Subject: foo"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
} -run
logexpect l1 -wait
......@@ -616,6 +616,27 @@ vmod_set_string(VRT_CTX, struct vmod_selector_set * set, VCL_INT n,
return (s);
}
VCL_BOOL
vmod_set_re_match(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject,
VCL_INT n, VCL_ENUM selects)
{
unsigned idx;
vre_t *re;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "re_match", selects);
if (idx == UINT_MAX)
return (0);
if (!check_added(ctx, set, idx, REGEX, "re_match", "regex"))
return (0);
re = set->table[idx]->re;
AN(re);
return (VRT_re_match(ctx, subject, re));
}
VCL_STRING
vmod_set_debug(VRT_CTX, struct vmod_selector_set *set)
{
......
......@@ -135,6 +135,18 @@ $Method STRING .string(INT n=0,
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
$Method BOOL .re_match(STRING subject, INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
Returns ...
Example::
if (myset.hasprefix(req.url)) {
......
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