Commit 425244ba authored by Geoff Simmons's avatar Geoff Simmons

add the function interface for match(), backref() and namedref()

parent c1c5be51
......@@ -27,6 +27,9 @@ import re2 [from "path"] ;
CONTENTS
========
* STRING backref(PRIV_TASK, INT, STRING)
* BOOL match(PRIV_TASK, STRING, STRING, BOOL, BOOL, BOOL, INT, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL)
* STRING namedref(PRIV_TASK, STRING, STRING)
* Object regex
* STRING regex.backref(INT, STRING)
* STRING regex.backref_named(STRING, STRING)
......@@ -63,6 +66,30 @@ STRING regex.backref_named(STRING, STRING)
Prototype
STRING regex.backref_named(STRING name, STRING fallback)
.. _func_match:
BOOL match(PRIV_TASK, STRING, STRING, BOOL, BOOL, BOOL, INT, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL)
------------------------------------------------------------------------------------------------------------
Prototype
BOOL match(PRIV_TASK, STRING pattern, STRING subject, BOOL utf8, BOOL posix_syntax, BOOL longest_match, INT max_mem, BOOL literal, BOOL never_nl, BOOL dot_nl, BOOL never_capture, BOOL case_sensitive, BOOL perl_classes, BOOL word_boundary, BOOL one_line)
.. _func_backref:
STRING backref(PRIV_TASK, INT, STRING)
--------------------------------------
Prototype
STRING backref(PRIV_TASK, INT ref, STRING fallback)
.. _func_namedref:
STRING namedref(PRIV_TASK, STRING, STRING)
------------------------------------------
Prototype
STRING namedref(PRIV_TASK, STRING name, STRING fallback)
.. _func_version:
STRING version()
......
......@@ -55,6 +55,22 @@ varnish v1 -vcl+backend {
} else {
set beresp.status = 999;
}
if (re2.match("(bar)(baz)", beresp.http.foo)) {
set beresp.http.foo0f = re2.backref(0, "error0");
set beresp.http.foo1f = re2.backref(1, "error1");
set beresp.http.foo2f = re2.backref(2, "error2");
} else {
set beresp.status = 999;
}
if (re2.match("(baz)(.+)", beresp.http.bar)) {
set beresp.http.bar0f = re2.backref(0, "error0");
set beresp.http.bar1f = re2.backref(1, "error1");
set beresp.http.bar2f = re2.backref(2, "error2");
} else {
set beresp.status = 999;
}
}
} -start
......@@ -62,6 +78,7 @@ varnish v1 -vcl+backend {
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.foo0 == "barbaz"
expect resp.http.foo1 == "bar"
expect resp.http.foo2 == "baz"
......@@ -75,4 +92,11 @@ client c1 {
expect resp.http.bar21 == "baz"
expect resp.http.bar22 == "quux"
expect resp.http.frap == "_barf_frap_"
expect resp.http.foo0f == "barbaz"
expect resp.http.foo1f == "bar"
expect resp.http.foo2f == "baz"
expect resp.http.bar0f == "bazquux"
expect resp.http.bar1f == "baz"
expect resp.http.bar2f == "quux"
} -run
This diff is collapsed.
......@@ -111,7 +111,77 @@ client c1 {
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod re2 error: elevendots\.backref\(12, \"fallback\"\): backref out of range \(max 11\)$"
expect * = VCL_Error "^vmod re2 error: twentydots\.backref\(21, \"error21\"\): backref out of range \(max 20\)$"
expect * = VCL_Error "^vmod re2 error: elevendots.backref.ref=12, fallback=.fallback..: backref out of range .max 11.$"
expect * = VCL_Error "^vmod re2 error: twentydots.backref.ref=21, fallback=.error21..: backref out of range .max 20.$"
expect * = End
} -run
varnish v1 -vcl {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
if (re2.match("(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)",
"123456789012")) {
set resp.http.foo0 = re2.backref(0, "error0");
set resp.http.foo1 = re2.backref(1, "error1");
set resp.http.foo2 = re2.backref(2, "error2");
set resp.http.foo3 = re2.backref(3, "error3");
set resp.http.foo4 = re2.backref(4, "error4");
set resp.http.foo5 = re2.backref(5, "error5");
set resp.http.foo6 = re2.backref(6, "error6");
set resp.http.foo7 = re2.backref(7, "error7");
set resp.http.foo8 = re2.backref(8, "error8");
set resp.http.foo9 = re2.backref(9, "error9");
set resp.http.foo10 = re2.backref(10, "error10");
set resp.http.foo11 = re2.backref(11, "error11");
set resp.http.foo12 = re2.backref(12, "fallback");
} else {
set resp.status = 999;
}
if (re2.match("(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)",
"123456789012345678901")) {
set resp.http.bar0 = re2.backref(0, "error0");
set resp.http.bar1 = re2.backref(1, "error1");
set resp.http.bar2 = re2.backref(2, "error2");
set resp.http.bar3 = re2.backref(3, "error3");
set resp.http.bar4 = re2.backref(4, "error4");
set resp.http.bar5 = re2.backref(5, "error5");
set resp.http.bar6 = re2.backref(6, "error6");
set resp.http.bar7 = re2.backref(7, "error7");
set resp.http.bar8 = re2.backref(8, "error8");
set resp.http.bar9 = re2.backref(9, "error9");
set resp.http.bar10 = re2.backref(10, "error10");
set resp.http.bar11 = re2.backref(11, "error11");
set resp.http.bar12 = re2.backref(12, "error12");
set resp.http.bar13 = re2.backref(13, "error13");
set resp.http.bar14 = re2.backref(14, "error14");
set resp.http.bar15 = re2.backref(15, "error15");
set resp.http.bar16 = re2.backref(16, "error16");
set resp.http.bar17 = re2.backref(17, "error17");
set resp.http.bar18 = re2.backref(18, "error18");
set resp.http.bar19 = re2.backref(19, "error19");
set resp.http.bar20 = re2.backref(20, "error20");
set resp.http.bar21 = re2.backref(21, "error21");
} else {
set resp.status = 999;
}
}
}
logexpect l2 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect * * Begin req
expect * = VCL_Error "^vmod re2 error: re2.backref.ref=12, fallback=.fallback..: backref out of range .max 11.$"
expect * = VCL_Error "^vmod re2 error: re2.backref.ref=21, fallback=.error21..: backref out of range .max 20.$"
expect * = End
} -start
client c1 -run
logexpect l2 -wait
......@@ -37,7 +37,27 @@ varnish v1 -vcl {
set resp.http.neverquux
= never.backref_named("quux", "error_quux");
}
}
if (re2.match("(?P<bar>bar)(?P<baz>baz)", "barbaz")) {
set resp.http.num0f = re2.backref(0, "error0");
set resp.http.num1f = re2.backref(1, "error1");
set resp.http.num2f = re2.backref(2, "error2");
set resp.http.barf = re2.namedref("bar", "error_bar");
set resp.http.bazf = re2.namedref("baz", "error_baz");
set resp.http.quuxf
= re2.namedref("quux", "error_quux");
}
if (re2.match("(?P<bar>bar)(?P<baz>baz)", "barbaz",
never_capture=true)) {
set resp.http.neverf = "match";
set resp.http.neverbarf
= re2.namedref("bar", "error_bar");
set resp.http.neverbazf
= re2.namedref("baz", "error_baz");
set resp.http.neverquuxf
= re2.namedref("quux", "error_quux");
}
}
} -start
......@@ -54,13 +74,28 @@ client c1 {
expect resp.http.neverbar == "error_bar"
expect resp.http.neverbaz == "error_baz"
expect resp.http.neverquux == "error_quux"
expect resp.http.num0f == "barbaz"
expect resp.http.num1f == "bar"
expect resp.http.num2f == "baz"
expect resp.http.barf == "bar"
expect resp.http.bazf == "baz"
expect resp.http.quuxf == "error_quux"
expect resp.http.neverf == "match"
expect resp.http.neverbarf == "error_bar"
expect resp.http.neverbazf == "error_baz"
expect resp.http.neverquuxf == "error_quux"
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod re2 error: barbaz\.backref_named\(\"quux\", \"error_quux\"\): no such named group$"
expect * = VCL_Error "^vmod re2 error: never\.backref_named\(\"bar\", \"error_bar\"\): never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: never\.backref_named\(\"baz\", \"error_baz\"\): never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: never\.backref_named\(\"quux\", \"error_quux\"\): never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: namedref name=.quux., fallback=.error_quux.: no such named group$"
expect * = VCL_Error "^vmod re2 error: never.backref_named.name=.bar., fallback=.error_bar..: never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: never.backref_named.name=.baz., fallback=.error_baz..: never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: never.backref_named.name=.quux., fallback=.error_quux..: never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: namedref name=.quux., fallback=.error_quux.: no such named group$"
expect * = VCL_Error "^vmod re2 error: re2.namedref.name=.bar., fallback=.error_bar..: never_capture was true in previous match$"
expect * = VCL_Error "^vmod re2 error: re2.namedref.name=.baz., fallback=.error_baz..: never_capture was true in previous match$"
expect * = VCL_Error "^vmod re2 error: re2.namedref.name=.quux., fallback=.error_quux..: never_capture was true in previous match$"
expect * = End
} -run
......@@ -273,3 +273,165 @@ varnish v1 -vcl {
word_boundary=true);
}
}
# Function interface
varnish v1 -vcl {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
if (re2.match("(", "foo")) {
set resp.http.r1 = "match";
}
if (re2.match("a\1", "foo")) {
set resp.http.r2 = "match";
}
if (re2.match("a[x", "foo")) {
set resp.http.r3 = "match";
}
if (re2.match("a[z-a]", "foo")) {
set resp.http.r4 = "match";
}
if (re2.match("a[[:foobar:]]", "foo")) {
set resp.http.r5 = "match";
}
if (re2.match("a(b", "foo")) {
set resp.http.r6 = "match";
}
if (re2.match("a\", "foo")) { #"
set resp.http.r7 = "match";
}
if (re2.match("[a-b-c]", "a")) {
set resp.http.r8 = "match";
}
if (re2.match("[a-b-c]", "a", posix_syntax=true)) {
set resp.http.r9 = "match";
}
if (re2.match("\Qabc\E", "abc")) {
set resp.http.r10 = "match";
}
if (re2.match("\Qabc\E", "abc", posix_syntax=true)) {
set resp.http.r11 = "match";
}
if (re2.match("(?:a)", "a")) {
set resp.http.r12 = "match";
}
if (re2.match("(?:a)", "a", posix_syntax=true)) {
set resp.http.r13 = "match";
}
if (re2.match("(?P<name>a)", "a")) {
set resp.http.r14 = "match";
}
if (re2.match("(?P<name>a)", "a", posix_syntax=true)) {
set resp.http.r15 = "match";
}
if (re2.match("(a++)", "a", posix_syntax=true)) {
set resp.http.r16 = "match";
}
if (re2.match("(a++)", "a")) {
set resp.http.r17 = "match";
}
if (re2.match("(a**)", "a", posix_syntax=true)) {
set resp.http.r18 = "match";
}
if (re2.match("(a**)", "a")) {
set resp.http.r19 = "match";
}
if (re2.match("(a?*)", "a", posix_syntax=true)) {
set resp.http.r20 = "match";
}
if (re2.match("(a?*)", "a")) {
set resp.http.r21 = "match";
}
if (re2.match("(a+*)", "a", posix_syntax=true)) {
set resp.http.r22 = "match";
}
if (re2.match("(a+*)", "a")) {
set resp.http.r23 = "match";
}
if (re2.match("(a{1}*)", "a", posix_syntax=true)) {
set resp.http.r24 = "match";
}
if (re2.match("(a{1}*)", "a")) {
set resp.http.r25 = "match";
}
if (re2.match("\d \s \w \D \S \W", "0 a a a !",
posix_syntax=true)) {
set resp.http.r26 = "match";
}
if (re2.match("\d \s \w \D \S \W", "0 a a a !",
posix_syntax=true, perl_classes=true)) {
set resp.http.r27 = "match";
}
if (re2.match("\ba \B", "a ", posix_syntax=true)) {
set resp.http.r28 = "match";
}
if (re2.match("\ba \B", "a ", posix_syntax=true,
word_boundary=true)) {
set resp.http.r29 = "match";
}
}
}
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.r1 == <undef>
expect resp.http.r2 == <undef>
expect resp.http.r3 == <undef>
expect resp.http.r4 == <undef>
expect resp.http.r5 == <undef>
expect resp.http.r6 == <undef>
expect resp.http.r7 == <undef>
expect resp.http.r8 == "match"
expect resp.http.r9 == <undef>
expect resp.http.r10 == "match"
expect resp.http.r11 == <undef>
expect resp.http.r12 == "match"
expect resp.http.r13 == <undef>
expect resp.http.r14 == "match"
expect resp.http.r15 == <undef>
expect resp.http.r16 == "match"
expect resp.http.r17 == <undef>
expect resp.http.r18 == "match"
expect resp.http.r19 == <undef>
expect resp.http.r20 == "match"
expect resp.http.r21 == <undef>
expect resp.http.r22 == "match"
expect resp.http.r23 == <undef>
expect resp.http.r24 == "match"
expect resp.http.r25 == <undef>
expect resp.http.r26 == <undef>
expect resp.http.r27 == "match"
expect resp.http.r28 == <undef>
expect resp.http.r29 == "match"
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..., text=.foo..: Cannot compile: missing .: .$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=.a.1., text=.foo..: Cannot compile: invalid escape sequence: .1$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=.a.x., text=.foo..: Cannot compile: missing .: .x$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=.a.z-a.., text=.foo..: Cannot compile: invalid character class range: z-a$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=.a..:foobar:..., text=.foo..: Cannot compile: invalid character class range: .:foobar:.$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=.a.b., text=.foo..: Cannot compile: missing .: a.b$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=.a.., text=.foo..: Cannot compile: trailing .$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..a-b-c.., text=.a..: Cannot compile: invalid character class range: -c$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..Qabc.E., text=.abc..: Cannot compile: invalid escape sequence: .Q$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=...:a.., text=.a..: Cannot compile: no argument for repetition operator: .$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=...P<name>a.., text=.a..: Cannot compile: no argument for repetition operator: .$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..a...., text=.a..: Cannot compile: bad repetition operator: ..$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..a...., text=.a..: Cannot compile: bad repetition operator: ..$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..a...., text=.a..: Cannot compile: bad repetition operator: ..$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..a...., text=.a..: Cannot compile: bad repetition operator: ..$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..a.1...., text=.a..: Cannot compile: bad repetition operator: .1..$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..d .s .w .D .S .W., text=.0 a a a !..: Cannot compile: invalid escape sequence: .d$"
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=..ba .B., text=.a ..: Cannot compile: invalid escape sequence: .b$"
expect * = End
} -run
......@@ -51,6 +51,46 @@ varnish v1 -vcl {
if (patternchars.match({"日扼語"})) {
set resp.http.patternchars = "match";
}
# Function interface
if (re2.match("^.........$",
{"日扼語"})) {
set resp.http.ninebytesf = "match";
}
if (re2.match("^...$",
{"日扼語"},
utf8=true)) {
set resp.http.threecharsf = "match";
}
if (re2.match("(.)",{"日扼語"})) {
if (re2.backref(1) == {""}) {
set resp.http.captured_one_bytef = "true";
}
}
if (re2.match("(.)",
{"日扼語"},
utf8=true)) {
if (re2.backref(1) == {"日"}) {
set resp.http.captured_one_charf = "true";
}
}
if (re2.match({"日扼語"},
{"日扼語"})) {
set resp.http.bytesf = "match";
}
if (re2.match({"日扼語"},
{"日扼語"})) {
set resp.http.charsf = "match";
}
if (re2.match({"^.扼.$"},
{"日扼語"})) {
set resp.http.patternbytesf = "match";
}
if (re2.match({"^.扼.$"},
{"日扼語"},
utf8=true)) {
set resp.http.patterncharsf = "match";
}
}
} -start
......@@ -66,4 +106,13 @@ client c1 {
expect resp.http.chars == "match"
expect resp.http.patternbytes == <undef>
expect resp.http.patternchars == "match"
expect resp.http.ninebytesf == "match"
expect resp.http.threecharsf == "match"
expect resp.http.captured_one_bytef == "true"
expect resp.http.captured_one_charf == "true"
expect resp.http.bytesf == "match"
expect resp.http.charsf == "match"
expect resp.http.patternbytesf == <undef>
expect resp.http.patterncharsf == "match"
} -run
# looks like -*- vcl -*-
varnishtest "regexp match and no-match (cf. varnish b00028.vtc & v00016.vtc)"
varnishtest "regexp match and no-match (cf. varnish b00028.vtc)"
server s1 {
rxreq
......@@ -11,21 +11,9 @@ varnish v1 -vcl+backend {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
sub vcl_init {
new foobar = re2.regex("foobar");
new snafu = re2.regex("snafu");
new bar = re2.regex("bar");
}
sub vcl_recv {
if (foobar.match(req.url)) {
return(pass);
} else if (snafu.match(req.url)) {
return(pipe);
} else {
return(pass);
}
}
sub vcl_backend_response {
if (bar.match(beresp.http.foo)) {
set beresp.http.foo1 = "1";
......@@ -38,6 +26,18 @@ varnish v1 -vcl+backend {
} else {
set beresp.status = 999;
}
if (re2.match("bar", beresp.http.foo)) {
set beresp.http.foo1f = "1";
} else {
set beresp.status = 999;
}
if (!re2.match("bar", beresp.http.bar)) {
set beresp.http.bar1f = "2";
} else {
set beresp.status = 999;
}
}
} -start
......@@ -48,4 +48,6 @@ client c1 {
expect resp.status == "200"
expect resp.http.foo1 == "1"
expect resp.http.bar1 == "2"
expect resp.http.foo1f == "1"
expect resp.http.bar1f == "2"
} -run
......@@ -35,4 +35,35 @@ varnish v1 -errvcl {vmod re2 error: Cannot compile '.{1000}x' in rep constructor
sub vcl_init {
new rep = re2.regex(".{1000}x", max_mem=1024);
}
}
\ No newline at end of file
}
varnish v1 -vcl {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
if (re2.match(".{1000}x", "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccx")) {
set resp.http.rep = "match";
}
if (re2.match(".{1000}x", "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccx", max_mem=1024)) {
set resp.http.repmem = "match";
}
}
}
client c1 {
txreq
rxresp
expect resp.http.rep == "match"
expect resp.http.repmem == <undef>
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod re2 error: re2.match.pattern=...1000.x., text=.c+"
expect * = End
} -run
......@@ -22,6 +22,13 @@ varnish v1 -vcl+backend {
} else {
set beresp.status = 999;
}
if (re2.match("(?:bar)(baz)", beresp.http.foo)) {
set beresp.http.foo0f = re2.backref(0, "error0");
set beresp.http.foo1f = re2.backref(1, "error1");
set beresp.http.foo2f = re2.backref(2, "fallback");
} else {
set beresp.status = 999;
}
}
} -start
......@@ -32,11 +39,14 @@ client c1 {
expect resp.http.foo0 == "barbaz"
expect resp.http.foo1 == "baz"
expect resp.http.foo2 == "fallback"
expect resp.http.foo0f == "barbaz"
expect resp.http.foo1f == "baz"
expect resp.http.foo2f == "fallback"
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
# due to calling barbaz.backref() before .match()
expect * = VCL_Error "^vmod re2 error: barbaz\.backref\(2, \"fallback\"\): backref out of range \(max 1\)$"
expect * = VCL_Error "^vmod re2 error: barbaz.backref.ref=2, fallback=.fallback..: backref out of range .max 1.$"
expect * = VCL_Error "^vmod re2 error: re2.backref.ref=2, fallback=.fallback..: backref out of range .max 1.$"
expect * = End
} -run
......@@ -108,3 +108,80 @@ client c1 {
expect resp.http.not_one == "match"
expect resp.http.one == <undef>
} -run
# Function interface
varnish v1 -vcl {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
if (re2.match("(|)^$.[*+?]{5,10},\\", "(|)^$.[*+?]{5,10},\\",
literal=true)) {
set resp.http.literal = "match";
}
if (re2.match(pattern="(.*)", never_nl=true, subject={"abc
def
ghi
"} )) {
set resp.http.never1 = "match";
set resp.http.never11 = re2.backref(1);
}
if (re2.match("(?s)(abc.*def)", {"abc
def
"}, never_nl=true)) {
set resp.http.never2 = "match";
}
if (re2.match(pattern={"(abc(.|
)def)"}, never_nl=true, subject={"abc
def
"}, )) {
set resp.http.never3 = "match";
}
if (re2.match("(abc[^x]*def)", {"abc
def
"}, never_nl=true)) {
set resp.http.never4 = "match";
}
if (re2.match("(abc[^x]*def)", {"abczzzdef
def
"}, never_nl=true)) {
set resp.http.never5 = "match";
set resp.http.never51 = re2.backref(1);
}
if (re2.match(pattern=".", dot_nl=true, subject={"
"} )) {
set resp.http.dot1 = "match";
}
if (re2.match(pattern="(?-s).", dot_nl=true, subject={"
"} )) {
set resp.http.dot2 = "match";
}
if (re2.match(".", {"
"}, dot_nl=true, never_nl=true)) {
set resp.http.dot3 = "match";
}
if (re2.match("(?i)([wand]{5})", "A fish named *Wanda*",
case_sensitive=true)) {
set resp.http.case = "match";
set resp.http.case1 = re2.backref(1);
}
if (re2.match(pattern="^a$", posix_syntax=true, subject={"a
a
a"} )) {
set resp.http.not_one = "match";
}
if (re2.match(pattern="^a$", posix_syntax=true, subject={"a
a
a"}, one_line=true)) {
set resp.http.one = "match";
}
}
}
client c1 -run
......@@ -18,6 +18,10 @@ varnish v1 -vcl+backend {
if (longregex.match(req.http.host)) {
return(synth(500, "not ok"));
}
if (re2.match("^(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)",
req.http.host)) {
return(synth(500, "not ok"));
}
}
} -start
......
......@@ -22,6 +22,12 @@ varnish v1 -vcl+backend {
if (empty.match(beresp.http.foo)) {
set beresp.http.bar = "YYY";
}
if (re2.match("$", beresp.http.bar)) {
set beresp.http.foof = "XXX";
}
if (re2.match("", beresp.http.foo)) {
set beresp.http.barf = "YYY";
}
}
} -start
......@@ -31,4 +37,6 @@ client c1 {
expect resp.status == 200
expect resp.http.foo == "XXX"
expect resp.http.bar == "YYY"
expect resp.http.foof == "XXX"
expect resp.http.barf == "YYY"
} -run
......@@ -2,46 +2,47 @@
varnishtest "re2.backref not affected by standard VCL regex code"
server s1 {
rxreq
txresp -hdr "Foo: barbaz" -body "1111\n"
} -start
varnish v1 -vcl+backend {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new barbaz = re2.regex("(bar)baz");
}
sub vcl_backend_response {
if (!barbaz.match(beresp.http.foo)) {
set beresp.status = 999;
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.foo = "barbaz";
if (!barbaz.match(resp.http.foo)) {
set resp.status = 999;
}
if (beresp.http.foo ~ "bar(baz)") {
set beresp.http.tilde0 = barbaz.backref(0, "tilde0");
set beresp.http.tilde1 = barbaz.backref(1, "tilde1");
if (resp.http.foo ~ "bar(baz)") {
set resp.http.tilde0 = barbaz.backref(0, "tilde0");
set resp.http.tilde1 = barbaz.backref(1, "tilde1");
} else {
set beresp.status = 999;
set resp.status = 999;
}
if (beresp.http.foo !~ "bar(quux)") {
set beresp.http.neg0 = barbaz.backref(0, "neg0");
set beresp.http.neg1 = barbaz.backref(1, "neg1");
if (resp.http.foo !~ "bar(quux)") {
set resp.http.neg0 = barbaz.backref(0, "neg0");
set resp.http.neg1 = barbaz.backref(1, "neg1");
} else {
set beresp.status = 999;
set resp.status = 999;
}
set beresp.http.regsub
= regsub(beresp.http.foo, "bar(baz)", "\1");
set beresp.http.regsub0 = barbaz.backref(0, "regsub0");
set beresp.http.regsub1 = barbaz.backref(1, "regsub1");
set resp.http.regsub
= regsub(resp.http.foo, "bar(baz)", "\1");
set resp.http.regsub0 = barbaz.backref(0, "regsub0");
set resp.http.regsub1 = barbaz.backref(1, "regsub1");
set beresp.http.regsuball
= regsuball(beresp.http.foo, "(.)", "x");
set beresp.http.regsuball0 = barbaz.backref(0, "regsuball0");
set beresp.http.regsuball1 = barbaz.backref(1, "regsuball1");
set resp.http.regsuball
= regsuball(resp.http.foo, "(.)", "x");
set resp.http.regsuball0 = barbaz.backref(0, "regsuball0");
set resp.http.regsuball1 = barbaz.backref(1, "regsuball1");
}
} -start
......@@ -61,3 +62,48 @@ client c1 {
expect resp.http.regsuball0 == "barbaz"
expect resp.http.regsuball1 == "bar"
} -run
# Function interface
varnish v1 -vcl+backend {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.foo = "barbaz";
if (!re2.match("(bar)baz", resp.http.foo)) {
set resp.status = 999;
}
if (resp.http.foo ~ "bar(baz)") {
set resp.http.tilde0 = re2.backref(0, "tilde0");
set resp.http.tilde1 = re2.backref(1, "tilde1");
} else {
set resp.status = 999;
}
if (resp.http.foo !~ "bar(quux)") {
set resp.http.neg0 = re2.backref(0, "neg0");
set resp.http.neg1 = re2.backref(1, "neg1");
} else {
set resp.status = 999;
}
set resp.http.regsub
= regsub(resp.http.foo, "bar(baz)", "\1");
set resp.http.regsub0 = re2.backref(0, "regsub0");
set resp.http.regsub1 = re2.backref(1, "regsub1");
set resp.http.regsuball
= regsuball(resp.http.foo, "(.)", "x");
set resp.http.regsuball0 = re2.backref(0, "regsuball0");
set resp.http.regsuball1 = re2.backref(1, "regsuball1");
}
}
client c1 -run
This diff is collapsed.
......@@ -22,4 +22,17 @@ $Method STRING .backref(INT ref, STRING fallback = "**BACKREF FAILED**")
$Method STRING .backref_named(STRING name,
STRING fallback = "**BACKREF FAILED**")
$Function BOOL match(PRIV_TASK, STRING pattern, STRING subject, BOOL utf8=0,
BOOL posix_syntax=0, BOOL longest_match=0,
INT max_mem=8388608, BOOL literal=0, BOOL never_nl=0,
BOOL dot_nl=0, BOOL never_capture=0,
BOOL case_sensitive=1, BOOL perl_classes=0,
BOOL word_boundary=0, BOOL one_line=0)
$Function STRING backref(PRIV_TASK, INT ref,
STRING fallback = "**BACKREF FUNCTION FAILED**")
$Function STRING namedref(PRIV_TASK, STRING name,
STRING fallback = "**NAMEDREF FUNCTION FAILED**")
$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