Commit cacd60f1 authored by Geoff Simmons's avatar Geoff Simmons

Add the .sub() and .suball() methods.

parent e194e3eb
......@@ -34,6 +34,8 @@ CONTENTS
* :ref:`func_set.nmatches`
* :ref:`func_set.re_match`
* :ref:`func_set.string`
* :ref:`func_set.sub`
* :ref:`func_set.suball`
* :ref:`func_set.which`
* :ref:`func_version`
......@@ -262,6 +264,52 @@ Example::
}
.. _func_set.sub:
STRING xset.sub(STRING str, STRING sub, INT n, ENUM select)
-----------------------------------------------------------
::
STRING xset.sub(
STRING str,
STRING sub,
INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
.. _func_set.suball:
set.suball(...)
---------------
::
STRING xset.suball(
STRING str,
STRING sub,
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 ".sub() and .suball() methods"
# cf. Varnish c00001.vtc, r00251.vtc, r00913.vtc, r00921.vtc.
varnish v1 -vcl {
import ${vmod_selector};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set();
s.add("foo", regex="ar");
s.add("bar", regex="(b)(a)(r)(f)");
s.add("baz", regex="$");
s.add("quux", regex=".*");
s.add("foobar", regex=":.*");
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
set resp.http.N-1-1 = s.sub("_barf_", "\0\0", 1);
set resp.http.N-1-2
= s.sub("_barf_", resp.http.nosuchheader, 1);
set resp.http.N-1-3
= "zoom" + s.sub(resp.http.Foomble, "\0\0", 1) + "box";
set resp.http.N-2-1 = s.sub("_barf_", "\4\3\2p", 2);
set resp.http.N-2-2 = s.sub("_barf_", "\4\\\3\2p", 2);
set resp.http.N-2-3 = s.sub("_barf_", "\4\&\3\2p", 2);
set resp.http.N-2-4 = s.sub("_barf_", "\0\4\3\2\\p", 2);
set resp.http.N-3 = s.sub(resp.http.bar, "XXX", 3);
set resp.http.N-4 = s.sub("/", client.ip, 4);
set resp.http.N-5 = s.sub(client.ip, client.ip, 5);
return (deliver);
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.N-1-1 == "_bararf_"
expect resp.http.N-1-2 == "_bf_"
expect resp.http.N-1-3 == "zoombox"
expect resp.http.N-2-1 == "_frap_"
expect resp.http.N-2-2 == "_f\\rap_"
expect resp.http.N-2-3 == "_f&rap_"
expect resp.http.N-2-4 == "_barffra\\p_"
expect resp.http.N-3 == "XXX"
expect resp.http.N-4 == "${localhost}"
expect resp.http.N-5 == "${localhost}"
} -run
# cf. Varnish c00047.vtc, r01557.vtc, r01566.vtc
varnish v1 -vcl {
import ${vmod_selector};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set();
s.add("1", regex="barb");
s.add("2", regex="ar");
s.add("3", regex="^");
s.add("4", regex="^[;]*");
s.add("5", regex="^b*");
s.add("6", regex="ping");
s.add("7", regex="(?<=[&\?])(foo|bar)=[^&]+(?:&|$)");
s.add("8", regex="\??(p|pi)=.*?(&|$)");
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
set resp.http.N-1 = s.suball("barbar", "zz", 1);
set resp.http.N-2 = s.suball("barbar", "zz", 2);
set resp.http.N-3 = s.suball("barbar", "baz", 3);
set resp.http.N-4 = s.suball("barbar", "baz", 4);
set resp.http.N-5-1 = s.suball("bbbar", "b", 5);
set resp.http.N-5-2 = s.suball("barbar", "z", 5);
set resp.http.N-6 = s.suball("barbar", "pong", 6);
set resp.http.N-7 = s.suball("/?foo=0&bar=1&foobar=2", "", 7);
return (deliver);
}
}
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.N-1 == "zzar"
expect resp.http.N-2 == "bzzbzz"
expect resp.http.N-3 == "bazbarbar"
expect resp.http.N-4 == "bazbarbar"
expect resp.http.N-5-1 == "bar"
expect resp.http.N-5-2 == "zarbar"
expect resp.http.N-6 == "barbar"
expect resp.http.N-7 == "/?foobar=2"
} -run
......@@ -616,9 +616,10 @@ 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)
static vre_t *
get_re(VRT_CTX, const struct vmod_selector_set * const restrict set,
VCL_INT n, VCL_ENUM const restrict selects,
const char * const restrict method)
{
unsigned idx;
vre_t *re;
......@@ -626,17 +627,56 @@ vmod_set_re_match(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "re_match", selects);
idx = get_idx(ctx, n, set, method, selects);
if (idx == UINT_MAX)
return (0);
if (!check_added(ctx, set, idx, REGEX, "re_match", "regex"))
return (0);
return (NULL);
if (!check_added(ctx, set, idx, REGEX, method, "regex"))
return (NULL);
re = set->table[idx]->re;
AN(re);
return (re);
}
VCL_BOOL
vmod_set_re_match(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject,
VCL_INT n, VCL_ENUM selects)
{
vre_t *re;
re = get_re(ctx, set, n, selects, "re_match");
if (re == NULL)
return (0);
return (VRT_re_match(ctx, subject, re));
}
static VCL_STRING
sub(VRT_CTX, struct vmod_selector_set * const restrict set, int all,
VCL_STRING const restrict str, VCL_STRING const restrict sub, VCL_INT n,
VCL_ENUM const restrict selects, const char * const restrict method)
{
vre_t *re;
re = get_re(ctx, set, n, selects, method);
if (re == NULL)
return (NULL);
return (VRT_regsub(ctx, all, str, re, sub));
}
VCL_STRING
vmod_set_sub(VRT_CTX, struct vmod_selector_set *set, VCL_STRING str,
VCL_STRING subst, VCL_INT n, VCL_ENUM selects)
{
return (sub(ctx, set, 0, str, subst, n, selects, "sub"));
}
VCL_STRING
vmod_set_suball(VRT_CTX, struct vmod_selector_set *set, VCL_STRING str,
VCL_STRING subst, VCL_INT n, VCL_ENUM selects)
{
return (sub(ctx, set, 1, str, subst, n, selects, "suball"));
}
VCL_STRING
vmod_set_debug(VRT_CTX, struct vmod_selector_set *set)
{
......
......@@ -147,6 +147,30 @@ $Method BOOL .re_match(STRING subject, INT n=0,
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
$Method STRING .sub(STRING str, STRING sub, INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
$Method STRING .suball(STRING str, STRING sub, 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