Commit f3293c2a authored by Geoff Simmons's avatar Geoff Simmons

Add the .element() method.

parent 39124a41
......@@ -26,6 +26,7 @@ CONTENTS
* :ref:`obj_set`
* :ref:`func_set.add`
* :ref:`func_set.debug`
* :ref:`func_set.element`
* :ref:`func_set.hasprefix`
* :ref:`func_set.match`
* :ref:`func_set.matched`
......@@ -173,6 +174,27 @@ Example::
}
.. _func_set.element:
STRING xset.element(INT n, ENUM select)
---------------------------------------
::
STRING xset.element(
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 "element() method"
varnish v1 -vcl {
import ${vmod_selector};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set();
s.add("foo");
s.add("bar");
s.add("baz");
s.add("quux");
s.add("foobar");
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
set resp.http.N-1 = s.element(1);
set resp.http.N-2 = s.element(2);
set resp.http.N-3 = s.element(3);
set resp.http.N-4 = s.element(4);
set resp.http.N-5 = s.element(5);
set resp.http.N--1 = s.element(-1);
set resp.http.N-0 = s.element(0);
set resp.http.N-6 = s.element(6);
if (s.match(req.http.Word)) {
set resp.http.Element = s.element();
set resp.http.Element-Unique = s.element(select=UNIQUE);
set resp.http.Element-Exact = s.element(select=EXACT);
set resp.http.Element-First = s.element(select=FIRST);
set resp.http.Element-Last = s.element(select=LAST);
set resp.http.Element-Shortest
= s.element(select=SHORTEST);
set resp.http.Element-Longest
= s.element(select=LONGEST);
}
return (deliver);
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.N-1 == "foo"
expect resp.http.N-2 == "bar"
expect resp.http.N-3 == "baz"
expect resp.http.N-4 == "quux"
expect resp.http.N-5 == "foobar"
expect resp.http.N--1 == ""
expect resp.http.N-0 == ""
expect resp.http.N-6 == ""
txreq -hdr "Word: foo"
rxresp
expect resp.status == 200
expect resp.http.Element == "foo"
expect resp.http.Element-Unique == resp.http.Element
expect resp.http.Element-Exact == resp.http.Element
expect resp.http.Element-First == "foo"
expect resp.http.Element-Last == "foo"
expect resp.http.Element-Shortest == "foo"
expect resp.http.Element-Longest == "foo"
txreq -hdr "Word: bar"
rxresp
expect resp.status == 200
expect resp.http.Element == "bar"
expect resp.http.Element-Unique == resp.http.Element
expect resp.http.Element-Exact == resp.http.Element
expect resp.http.Element-First == "bar"
expect resp.http.Element-Last == "bar"
expect resp.http.Element-Shortest == "bar"
expect resp.http.Element-Longest == "bar"
txreq -hdr "Word: baz"
rxresp
expect resp.status == 200
expect resp.http.Element == "baz"
expect resp.http.Element-Unique == resp.http.Element
expect resp.http.Element-Exact == resp.http.Element
expect resp.http.Element-First == "baz"
expect resp.http.Element-Last == "baz"
expect resp.http.Element-Shortest == "baz"
expect resp.http.Element-Longest == "baz"
txreq -hdr "Word: quux"
rxresp
expect resp.status == 200
expect resp.http.Element == "quux"
expect resp.http.Element-Unique == resp.http.Element
expect resp.http.Element-Exact == resp.http.Element
expect resp.http.Element-First == "quux"
expect resp.http.Element-Last == "quux"
expect resp.http.Element-Shortest == "quux"
expect resp.http.Element-Longest == "quux"
txreq -hdr "Word: foobar"
rxresp
expect resp.status == 200
expect resp.http.Element == "foobar"
expect resp.http.Element-Unique == resp.http.Element
expect resp.http.Element-Exact == resp.http.Element
expect resp.http.Element-First == "foobar"
expect resp.http.Element-Last == "foobar"
expect resp.http.Element-Shortest == "foobar"
expect resp.http.Element-Longest == "foobar"
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error {^vmod selector error: s\.element\(\) called without prior match$}
expect * = VCL_Error {^vmod selector error: s\.element\(\) called without prior match$}
expect * = VCL_Error {^vmod selector error: s\.element\(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");
s.add("foobarbaz");
s.add("foobar");
s.add("foo");
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
if (s.hasprefix(req.http.Word)) {
set resp.http.Element = s.element();
set resp.http.Element-Unique = s.element(select=UNIQUE);
set resp.http.Element-Exact = s.element(select=EXACT);
set resp.http.Element-First = s.element(select=FIRST);
set resp.http.Element-Last = s.element(select=LAST);
set resp.http.Element-Shortest
= s.element(select=SHORTEST);
set resp.http.Element-Longest
= s.element(select=LONGEST);
}
return (deliver);
}
}
logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect * 1009 Begin req
expect * = VCL_Error {^vmod selector error: s\.element\(select=UNIQUE\): 2 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.element\(select=UNIQUE\): 2 elements were matched$}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {^vmod selector error: s\.element\(select=UNIQUE\): 3 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.element\(select=UNIQUE\): 3 elements were matched$}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {^vmod selector error: s\.element\(select=UNIQUE\): 4 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.element\(select=UNIQUE\): 4 elements were matched$}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {^vmod selector error: s\.element\(select=UNIQUE\): 2 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.element\(select=UNIQUE\): 2 elements were matched$}
expect * = VCL_Error {^vmod selector error: s\.element\(select=EXACT\): no element matched exactly$}
expect * = End
} -start
client c1 {
txreq -hdr "Word: foo"
rxresp
expect resp.status == 200
expect resp.http.Element == "foo"
expect resp.http.Element-Unique == "foo"
expect resp.http.Element-Exact == "foo"
expect resp.http.Element-First == "foo"
expect resp.http.Element-Last == "foo"
expect resp.http.Element-Shortest == "foo"
expect resp.http.Element-Longest == "foo"
txreq -hdr "Word: foobar"
rxresp
expect resp.status == 200
expect resp.http.Element == ""
expect resp.http.Element-Unique == ""
expect resp.http.Element-Exact == "foobar"
expect resp.http.Element-First == "foobar"
expect resp.http.Element-Last == "foo"
expect resp.http.Element-Shortest == "foo"
expect resp.http.Element-Longest == "foobar"
txreq -hdr "Word: foobarbaz"
rxresp
expect resp.status == 200
expect resp.http.Element == ""
expect resp.http.Element-Unique == ""
expect resp.http.Element-Exact == "foobarbaz"
expect resp.http.Element-First == "foobarbaz"
expect resp.http.Element-Last == "foo"
expect resp.http.Element-Shortest == "foo"
expect resp.http.Element-Longest == "foobarbaz"
txreq -hdr "Word: foobarbazquux"
rxresp
expect resp.status == 200
expect resp.http.Element == ""
expect resp.http.Element-Unique == ""
expect resp.http.Element-Exact == "foobarbazquux"
expect resp.http.Element-First == "foobarbazquux"
expect resp.http.Element-Last == "foo"
expect resp.http.Element-Shortest == "foo"
expect resp.http.Element-Longest == "foobarbazquux"
txreq -hdr "Word: foobarb"
rxresp
expect resp.status == 200
expect resp.http.Element == ""
expect resp.http.Element-Unique == ""
expect resp.http.Element-Exact == ""
expect resp.http.Element-First == "foobar"
expect resp.http.Element-Last == "foo"
expect resp.http.Element-Shortest == "foo"
expect resp.http.Element-Longest == "foobar"
} -run
logexpect l1 -wait
......@@ -470,6 +470,42 @@ vmod_set_which(VRT_CTX, struct vmod_selector_set *set, VCL_ENUM selects)
return (select(ctx, match, set->vcl_name, selects, "which") + 1);
}
static unsigned
get_idx(VRT_CTX, VCL_INT n, const struct vmod_selector_set * const restrict set,
const char * const restrict method, VCL_ENUM const restrict selects)
{
struct match_data *match;
if (n > 0) {
if (n > set->nmembers) {
VERR(ctx, "%s.%s(%ld): set has %d elements",
set->vcl_name, method, n, set->nmembers);
return (UINT_MAX);
}
return (n - 1);
}
match = get_existing_match_data(ctx, set, method);
if (match == NULL || match->n == 0)
return (UINT_MAX);
return (select(ctx, match, set->vcl_name, selects, method));
}
VCL_STRING
vmod_set_element(VRT_CTX, struct vmod_selector_set *set, VCL_INT n,
VCL_ENUM selects)
{
unsigned idx;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "element", selects);
if (idx == UINT_MAX)
return (NULL);
return (set->members[idx]);
}
VCL_STRING
vmod_set_debug(VRT_CTX, struct vmod_selector_set *set)
{
......
......@@ -99,6 +99,18 @@ $Method INT .which(ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
$Method STRING .element(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