Commit 8c246533 authored by Geoff Simmons's avatar Geoff Simmons

Add the set.saved() method.

parent 7091d02b
......@@ -69,6 +69,8 @@ SYNOPSIS
[, ENUM select])
STRING <obj>.extract(STRING text, STRING rewrite [, INT n]
[, ENUM select])
BOOL <obj>.saved([ENUM {REGEX, STR, BE} which] [, INT n]
[, ENUM select])
# VMOD version
STRING re2.version()
......@@ -1573,6 +1575,81 @@ Example::
}
.. _func_set.saved:
BOOL xset.saved(ENUM which, INT n, ENUM select)
-----------------------------------------------
::
BOOL xset.saved(
ENUM {REGEX, STR, BE} which=REGEX,
INT n=0,
ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
)
Returns true if and only if an object of the type indicated by
``which`` was saved at initialization time for the ``nth`` pattern
added to the set, or for the pattern indicated by ``select`` after the
most recent ``.match()`` call.
In other words, ``.saved()`` returns true for ``which=REGEX`` if the
individual regex was saved with ``.add(save=true)`` for the indicated
pattern; for ``which=STR`` if a string was stored with the ``string``
parameter in ``.add()``, and for ``which=BE`` if a backend was stored
with the ``.backend()`` attribute. The default value of ``which`` is
``REGEX``.
The pattern in the set is identified by ``n`` and ``select`` according
to the rules given above. ``.saved()`` fails, returning false with a
``VCL_Error`` message in the log, if the values of ``n`` or ``select``
are invalid.
Example::
sub vcl_init {
new s = re2.set();
s.add("1", save=true, string="1", backend=b1);
s.add("2", save=true, string="2");
s.add("3", save=true, backend=b3);
s.add("4", save=true);
s.add("5", string="5", backend=b5);
s.add("6", string="6");
s.add("7", backend=b7);
s.add("8");
s.compile();
}
# Then the following holds for this set:
# s.saved(n=1) == true # for any value of which
# s.saved(which=REGEX, n=2) == true
# s.saved(which=STR, n=2) == true
# s.saved(which=BE, n=2) == false
# s.saved(which=REGEX, n=3) == true
# s.saved(which=STR, n=3) == false
# s.saved(which=BE, n=3) == true
# s.saved(which=REGEX, n=4) == true
# s.saved(which=STR, n=4) == false
# s.saved(which=BE, n=4) == false
# s.saved(which=REGEX, n=5) == false
# s.saved(which=STR, n=5) == true
# s.saved(which=BE, n=5) == true
# s.saved(which=REGEX, n=6) == false
# s.saved(which=STR, n=6) == true
# s.saved(which=BE, n=6) == false
# s.saved(which=REGEX, n=7) == false
# s.saved(which=STR, n=7) == false
# s.saved(which=BE, n=7) == true
# s.saved(n=8) == false # for any value of which
if (s.match("4")) {
# The fourth pattern has been uniquely matched.
# So in this context: s.saved() == true
# Since save=true was used in .add() for the 4th pattern,
# and which=REGEX by default.
}
......
......@@ -605,3 +605,25 @@ vmod_set_backend(VRT_CTX, struct vmod_re2_set *set, VCL_INT n, VCL_ENUM selects)
}
return set->backend[idx];
}
VCL_BOOL
vmod_set_saved(VRT_CTX, struct vmod_re2_set *set, VCL_ENUM whichs, VCL_INT n,
VCL_ENUM selects)
{
int idx;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_RE2_SET_MAGIC);
idx = get_match_idx(ctx, set, n, selects, "saved");
if (idx < 0)
return 0;
if (whichs == vmod_enum_REGEX)
return vbit_test(set->added[RE_ADDED], idx);
if (whichs == vmod_enum_BE)
return vbit_test(set->added[BE_ADDED], idx);
if (whichs == vmod_enum_STR)
return vbit_test(set->added[STR_ADDED], idx);
WRONG("illegal which ENUM");
return 0;
}
This diff is collapsed.
# looks like -*- vcl -*-
varnishtest "set.sub() method"
varnishtest "set.sub() method, and set.saved() for REGEX"
varnish v1 -vcl {
import ${vmod_re2};
......@@ -12,11 +12,6 @@ varnish v1 -vcl {
s.add("\w+", save=true);
s.add("b", save=true);
s.compile();
new n = re2.set();
n.add("b");
n.add("b+", save=true);
n.compile();
}
sub vcl_recv {
......@@ -24,6 +19,15 @@ varnish v1 -vcl {
}
sub vcl_synth {
set resp.http.s-saved-1 = s.saved(n=1);
set resp.http.s-saved-2 = s.saved(n=2);
set resp.http.s-saved-3 = s.saved(n=3);
set resp.http.s-saved-regex-1 = s.saved(REGEX, n=1);
set resp.http.s-saved-regex-2 = s.saved(REGEX, n=2);
set resp.http.s-saved-regex-3 = s.saved(REGEX, n=3);
set resp.http.s-saved-b4-match = s.saved();
set resp.http.s-saved-regex-b4-match = s.saved(REGEX);
set resp.http.s-sub-1
= s.sub("the quick brown fox jumps over the lazy dogs.",
"\2\1ay", n=1);
......@@ -38,12 +42,14 @@ varnish v1 -vcl {
"\2\1ay", select=FIRST);
set resp.http.s-ab = s.sub("ababababab", "bb", select=LAST);
set resp.http.n-sub-1 = n.sub("bbbbbb", "bb", n=1);
set resp.http.n-sub-2 = n.sub("bbbbbb", "bb", n=2);
set resp.http.n-match = n.match("bbbbbb");
set resp.http.n-n = n.nmatches();
set resp.http.n-first = n.sub("bbbbbb", "bb", select=FIRST);
set resp.http.n-last = n.sub("bbbbbb", "bb", select=LAST);
set resp.http.s-saved-match = s.saved();
set resp.http.s-saved-regex-match = s.saved(REGEX);
set resp.http.s-saved-match-first = s.saved(select=FIRST);
set resp.http.s-saved-match-last = s.saved(select=LAST);
set resp.http.s-saved-regex-match-first
= s.saved(REGEX, select=FIRST);
set resp.http.s-saved-regex-match-last
= s.saved(REGEX, select=LAST);
}
} -start
......@@ -51,6 +57,14 @@ client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.s-saved-1 == "true"
expect resp.http.s-saved-2 == "true"
expect resp.http.s-saved-3 == "true"
expect resp.http.s-saved-regex-1 == "true"
expect resp.http.s-saved-regex-2 == "true"
expect resp.http.s-saved-regex-3 == "true"
expect resp.http.s-saved-b4-match == "false"
expect resp.http.s-saved-regex-b4-match == "false"
expect resp.http.s-sub-1 == "ethay quick brown fox jumps over the lazy dogs."
expect resp.http.s-sub-2 == "abcd-NOSPAM.efghi@google.com"
expect resp.http.s-sub-3 == "abbabababab"
......@@ -58,23 +72,105 @@ client c1 {
expect resp.http.s-n == "3"
expect resp.http.s-pangram == resp.http.s-sub-1
expect resp.http.s-ab == resp.http.s-sub-3
expect resp.http.n-sub-1 == ""
expect resp.http.n-sub-2 == "bb"
expect resp.http.n-match == "true"
expect resp.http.n-n == "2"
expect resp.http.n-first == resp.http.n-sub-1
expect resp.http.n-last == resp.http.n-sub-2
expect resp.http.s-saved-match == "false"
expect resp.http.s-saved-regex-match == "false"
expect resp.http.s-saved-match-first == "true"
expect resp.http.s-saved-match-last == "true"
expect resp.http.s-saved-regex-match-first == "true"
expect resp.http.s-saved-regex-match-last == "true"
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod re2 error: s.saved.. called without prior match$"
expect * = VCL_Error "^vmod re2 error: s.saved.. called without prior match$"
expect * = VCL_Error "^vmod re2 error: s.saved.0.: 3 successful matches$"
expect * = VCL_Error "^vmod re2 error: s.saved.0.: 3 successful matches$"
expect * = End
} -run
varnish v1 -vcl {
import ${vmod_re2};
backend be { .host = "${bad_ip}"; }
sub vcl_init {
new n = re2.set();
n.add("b");
n.add("b+", save=true);
n.compile();
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.n-saved-neg = n.saved(n=-1);
set resp.http.n-saved-0 = n.saved(n=0);
set resp.http.n-saved-1 = n.saved(n=1);
set resp.http.n-saved-2 = n.saved(n=2);
set resp.http.n-saved-regex-neg = n.saved(REGEX, n=-1);
set resp.http.n-saved-regex-0 = n.saved(REGEX, n=0);
set resp.http.n-saved-regex-1 = n.saved(REGEX, n=1);
set resp.http.n-saved-regex-2 = n.saved(REGEX, n=2);
set resp.http.n-sub-1 = n.sub("bbbbbb", "bb", n=1);
set resp.http.n-sub-2 = n.sub("bbbbbb", "bb", n=2);
set resp.http.n-match = n.match("bbbbbb");
set resp.http.n-n = n.nmatches();
set resp.http.n-first = n.sub("bbbbbb", "bb", select=FIRST);
set resp.http.n-last = n.sub("bbbbbb", "bb", select=LAST);
set resp.http.n-saved-match = n.saved();
set resp.http.n-saved-regex-match = n.saved(REGEX);
set resp.http.n-saved-match-first = n.saved(select=FIRST);
set resp.http.n-saved-match-last = n.saved(select=LAST);
set resp.http.n-saved-regex-match-first
= n.saved(REGEX, select=FIRST);
set resp.http.n-saved-regex-match-last
= n.saved(REGEX, select=LAST);
}
}
logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod re2 error: n.sub.bbbbbb, bb, 1, UNIQUE.: Pattern 1 was not saved$"
expect * = VCL_Error "^vmod re2 error: n.sub.bbbbbb, bb, 0, FIRST.: Pattern 1 was not saved$"
expect * = End
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.n-saved-neg == "false"
expect resp.http.n-saved-0 == "false"
expect resp.http.n-saved-1 == "false"
expect resp.http.n-saved-2 == "true"
expect resp.http.n-saved-regex-neg == resp.http.n-saved-neg
expect resp.http.n-saved-regex-0 == resp.http.n-saved-0
expect resp.http.n-saved-regex-1 == resp.http.n-saved-1
expect resp.http.n-saved-regex-2 == resp.http.n-saved-2
expect resp.http.n-sub-1 == ""
expect resp.http.n-sub-2 == "bb"
expect resp.http.n-match == "true"
expect resp.http.n-n == "2"
expect resp.http.n-first == resp.http.n-sub-1
expect resp.http.n-last == resp.http.n-sub-2
expect resp.http.n-saved-match == "false"
expect resp.http.n-saved-regex-match == resp.http.n-saved-match
expect resp.http.n-saved-match-first == "false"
expect resp.http.n-saved-match-last == "true"
expect resp.http.n-saved-regex-match-first == resp.http.n-saved-match-first
expect resp.http.n-saved-regex-match-last == resp.http.n-saved-match-last
} -run
logexpect l1 -wait
# Tests for the off-by-one error discovered in vre2_rewrite().
varnish v1 -vcl {
import ${vmod_re2};
......
......@@ -56,6 +56,8 @@ SYNOPSIS
[, ENUM select])
STRING <obj>.extract(STRING text, STRING rewrite [, INT n]
[, ENUM select])
BOOL <obj>.saved([ENUM {REGEX, STR, BE} which] [, INT n]
[, ENUM select])
# VMOD version
STRING re2.version()
......@@ -1278,6 +1280,70 @@ Example::
}
}
$Method BOOL .saved(ENUM {REGEX, STR, BE} which=REGEX, INT n=0,
ENUM {FIRST, LAST, UNIQUE} select=UNIQUE)
Returns true if and only if an object of the type indicated by
``which`` was saved at initialization time for the ``nth`` pattern
added to the set, or for the pattern indicated by ``select`` after the
most recent ``.match()`` call.
In other words, ``.saved()`` returns true for ``which=REGEX`` if the
individual regex was saved with ``.add(save=true)`` for the indicated
pattern; for ``which=STR`` if a string was stored with the ``string``
parameter in ``.add()``, and for ``which=BE`` if a backend was stored
with the ``.backend()`` attribute. The default value of ``which`` is
``REGEX``.
The pattern in the set is identified by ``n`` and ``select`` according
to the rules given above. ``.saved()`` fails, returning false with a
``VCL_Error`` message in the log, if the values of ``n`` or ``select``
are invalid.
Example::
sub vcl_init {
new s = re2.set();
s.add("1", save=true, string="1", backend=b1);
s.add("2", save=true, string="2");
s.add("3", save=true, backend=b3);
s.add("4", save=true);
s.add("5", string="5", backend=b5);
s.add("6", string="6");
s.add("7", backend=b7);
s.add("8");
s.compile();
}
# Then the following holds for this set:
# s.saved(n=1) == true # for any value of which
# s.saved(which=REGEX, n=2) == true
# s.saved(which=STR, n=2) == true
# s.saved(which=BE, n=2) == false
# s.saved(which=REGEX, n=3) == true
# s.saved(which=STR, n=3) == false
# s.saved(which=BE, n=3) == true
# s.saved(which=REGEX, n=4) == true
# s.saved(which=STR, n=4) == false
# s.saved(which=BE, n=4) == false
# s.saved(which=REGEX, n=5) == false
# s.saved(which=STR, n=5) == true
# s.saved(which=BE, n=5) == true
# s.saved(which=REGEX, n=6) == false
# s.saved(which=STR, n=6) == true
# s.saved(which=BE, n=6) == false
# s.saved(which=REGEX, n=7) == false
# s.saved(which=STR, n=7) == false
# s.saved(which=BE, n=7) == true
# s.saved(n=8) == false # for any value of which
if (s.match("4")) {
# The fourth pattern has been uniquely matched.
# So in this context: s.saved() == true
# Since save=true was used in .add() for the 4th pattern,
# and which=REGEX by default.
}
$Function STRING version()
Return the version string for this VMOD.
......
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