Commit 7f187041 authored by Geoff Simmons's avatar Geoff Simmons

Add methods .hasprefix(), .nmatches(), .matched() and .which().

parent c517ccfb
......@@ -26,7 +26,11 @@ CONTENTS
* :ref:`obj_set`
* :ref:`func_set.add`
* :ref:`func_set.debug`
* :ref:`func_set.hasprefix`
* :ref:`func_set.match`
* :ref:`func_set.matched`
* :ref:`func_set.nmatches`
* :ref:`func_set.which`
* :ref:`func_version`
......@@ -107,6 +111,68 @@ Example::
}
.. _func_set.hasprefix:
BOOL xset.hasprefix(STRING)
---------------------------
Returns ``true`` if and only if ...
Example::
if (myset.hasprefix(req.url)) {
call do_if_prefix_matched;
}
.. _func_set.nmatches:
INT xset.nmatches()
-------------------
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
.. _func_set.matched:
BOOL xset.matched(INT)
----------------------
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
.. _func_set.which:
INT xset.which(ENUM select)
---------------------------
::
INT xset.which(
ENUM {UNIQUE, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
.. _func_set.debug:
STRING xset.debug()
......
......@@ -256,6 +256,64 @@ PT_Lookup(const struct pt_y * const restrict root,
return (UINT_MAX);
}
static int
pt_search(const struct pt_y * const restrict y,
char * const restrict * const restrict strings,
const unsigned char * restrict c,
struct match_data * const restrict match)
{
const unsigned char * restrict s;
unsigned short i;
if (y == NULL)
return (0);
CHECK_OBJ(y, PT_Y_MAGIC);
s = (unsigned char *)strings[y->idx] + y->off;
for (i = 0; *c != '\0' && i < y->len && s[i] == *c; i++)
c++;
if (s[i] == '\0') {
if (match->n == match->limit)
return (-1);
match->indices[match->n] = y->idx;
match->n++;
if (y->idx < match->min)
match->min = y->idx;
if (y->idx > match->max)
match->max = y->idx;
}
if (i < y->len)
return (0);
if (pt_search(y->leaf[0], strings, c, match) != 0)
return (-1);
if (pt_search(y->leaf[1], strings, c, match) != 0)
return (-1);
return (0);
}
int
PT_Prefixes(const struct pt_y * const restrict root,
char * const restrict * const restrict strings,
const char * const restrict subject,
struct match_data * const restrict match)
{
CHECK_OBJ_NOTNULL(match, MATCH_DATA_MAGIC);
AN(match->indices);
AN(match->limit);
AN(strings);
AN(subject);
match->n = 0;
match->min = UINT_MAX;
match->max = 0;
return (pt_search(root, strings, (unsigned char *)subject, match));
}
void
PT_Free(struct pt_y *y)
{
......
......@@ -34,16 +34,15 @@
struct pt_y;
#if 0
struct t_stats {
struct match_data {
unsigned magic;
#define T_STATS_MAGIC 0xf92e6603
double d_mean;
unsigned d_max;
unsigned n_nodes;
unsigned n_leaves;
}
#endif
#define MATCH_DATA_MAGIC 0x0d9a845e
unsigned *indices;
unsigned limit;
unsigned n;
unsigned min;
unsigned max;
};
void PT_Init(void);
int PT_Inited(void);
......@@ -52,5 +51,9 @@ int PT_Insert(struct pt_y * * restrict root, unsigned idx,
unsigned PT_Lookup(const struct pt_y * const restrict root,
char * const restrict * const restrict strings,
const char * const restrict subject);
int PT_Prefixes(const struct pt_y * const restrict root,
char * const restrict * const restrict strings,
const char * const restrict subject,
struct match_data * const restrict match);
void PT_Free(struct pt_y *y);
struct vsb * PT_Dump(struct pt_y *root, char **strings);
# looks like -*- vcl -*-
varnishtest "hasprefix() method"
varnish v1 -vcl {
import ${vmod_selector};
import std;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set();
s.add("foo");
s.add("bar");
s.add("baz");
s.add("quux");
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
std.timestamp("BeforeMatch");
set resp.http.Match = s.hasprefix(req.http.Word);
std.timestamp("AfterMatch");
set resp.http.N = s.nmatches();
set resp.http.Which = s.which();
set resp.http.Matched-1 = s.matched(1);
set resp.http.Matched-2 = s.matched(2);
set resp.http.Matched-3 = s.matched(3);
set resp.http.Matched-4 = s.matched(4);
set resp.body = s.debug();
return (deliver);
}
} -start
client c1 {
txreq -hdr "Word: foobar"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "1"
expect resp.http.Matched-1 == "true"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: barbaz"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "2"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "true"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: bazquux"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "3"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "true"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: quuxxyzzy"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "4"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "true"
txreq -hdr "Word: oof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: rab"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: zab"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: xuuq"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: raboof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
} -run
varnish v1 -vcl {
import ${vmod_selector};
import std;
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 {
std.timestamp("BeforeMatch");
set resp.http.Match = s.hasprefix(req.http.Word);
std.timestamp("AfterMatch");
set resp.http.N = s.nmatches();
set resp.http.Which = s.which();
set resp.http.Which-Unique = s.which(select=UNIQUE);
set resp.http.Which-First = s.which(select=FIRST);
set resp.http.Which-Last = s.which(select=LAST);
set resp.http.Which-Shortest = s.which(select=SHORTEST);
set resp.http.Which-Longest = s.which(select=LONGEST);
set resp.http.Matched-1 = s.matched(1);
set resp.http.Matched-2 = s.matched(2);
set resp.http.Matched-3 = s.matched(3);
set resp.http.Matched-4 = s.matched(4);
set resp.body = s.debug();
return (deliver);
}
}
client c1 {
txreq -hdr "Word: foo"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "4"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "4"
expect resp.http.Which-Last == "4"
expect resp.http.Which-Shortest == "4"
expect resp.http.Which-Longest == "4"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "true"
txreq -hdr "Word: foobar"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "3"
expect resp.http.Which-Last == "4"
expect resp.http.Which-Shortest == "4"
expect resp.http.Which-Longest == "3"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "true"
expect resp.http.Matched-4 == "true"
txreq -hdr "Word: foobarbaz"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "2"
expect resp.http.Which-Last == "4"
expect resp.http.Which-Shortest == "4"
expect resp.http.Which-Longest == "2"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "true"
expect resp.http.Matched-3 == "true"
expect resp.http.Matched-4 == "true"
txreq -hdr "Word: foobarbazquux"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "4"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "1"
expect resp.http.Which-Last == "4"
expect resp.http.Which-Shortest == "4"
expect resp.http.Which-Longest == "1"
expect resp.http.Matched-1 == "true"
expect resp.http.Matched-2 == "true"
expect resp.http.Matched-3 == "true"
expect resp.http.Matched-4 == "true"
txreq -hdr "Word: oof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: raboof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: zabraboof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: xuuqzabraboof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
} -run
# The same test as the previous one, but the strings added in reverse order.
varnish v1 -vcl {
import ${vmod_selector};
import std;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set();
s.add("foo");
s.add("foobar");
s.add("foobarbaz");
s.add("foobarbazquux");
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
std.timestamp("BeforeMatch");
set resp.http.Match = s.hasprefix(req.http.Word);
std.timestamp("AfterMatch");
set resp.http.N = s.nmatches();
set resp.http.Which = s.which();
set resp.http.Which-Unique = s.which(select=UNIQUE);
set resp.http.Which-First = s.which(select=FIRST);
set resp.http.Which-Last = s.which(select=LAST);
set resp.http.Which-Shortest = s.which(select=SHORTEST);
set resp.http.Which-Longest = s.which(select=LONGEST);
set resp.http.Matched-1 = s.matched(1);
set resp.http.Matched-2 = s.matched(2);
set resp.http.Matched-3 = s.matched(3);
set resp.http.Matched-4 = s.matched(4);
set resp.body = s.debug();
return (deliver);
}
}
client c1 {
txreq -hdr "Word: foo"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "1"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "1"
expect resp.http.Which-Last == "1"
expect resp.http.Which-Shortest == resp.http.Which-First
expect resp.http.Which-Longest == resp.http.Which-Last
expect resp.http.Matched-1 == "true"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: foobar"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "1"
expect resp.http.Which-Last == "2"
expect resp.http.Which-Shortest == resp.http.Which-First
expect resp.http.Which-Longest == resp.http.Which-Last
expect resp.http.Matched-1 == "true"
expect resp.http.Matched-2 == "true"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: foobarbaz"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "1"
expect resp.http.Which-Last == "3"
expect resp.http.Which-Shortest == resp.http.Which-First
expect resp.http.Which-Longest == resp.http.Which-Last
expect resp.http.Matched-1 == "true"
expect resp.http.Matched-2 == "true"
expect resp.http.Matched-3 == "true"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: foobarbazquux"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "4"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "1"
expect resp.http.Which-Last == "4"
expect resp.http.Which-Shortest == resp.http.Which-First
expect resp.http.Which-Longest == resp.http.Which-Last
expect resp.http.Matched-1 == "true"
expect resp.http.Matched-2 == "true"
expect resp.http.Matched-3 == "true"
expect resp.http.Matched-4 == "true"
txreq -hdr "Word: oof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: raboof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: zabraboof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
txreq -hdr "Word: xuuqzabraboof"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
expect resp.http.Matched-1 == "false"
expect resp.http.Matched-2 == "false"
expect resp.http.Matched-3 == "false"
expect resp.http.Matched-4 == "false"
} -run
# Words with common prefixes chosen from /usr/share/dict/words
varnish v1 -vcl {
import ${vmod_selector};
import std;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set();
s.add("letterhead"); # 1
s.add("letters"); # 2
s.add("letterheads"); # 3
s.add("letterbox"); # 4
s.add("letter"); # 5
s.add("lettered"); # 6
s.add("lettering"); # 7
s.add("rhododendron"); # 8
s.add("rhombuses"); # 9
s.add("rhomboids"); # 10
s.add("rhombi"); # 11
s.add("rhodium"); # 12
s.add("rho"); # 13
s.add("rhomboid"); # 14
s.add("rhododendrons"); # 15
s.add("rhombus"); # 16
s.add("forgetfulness"); # 17
s.add("forgets"); # 18
s.add("forgettable"); # 19
s.add("forget"); # 20
s.add("forged"); # 21
s.add("forgetfully"); # 22
s.add("forgetting"); # 23
s.add("forges"); # 24
s.add("forger"); # 25
s.add("forgery"); # 26
s.add("forge"); # 27
s.add("forgetful"); # 28
s.add("forgers"); # 29
s.add("forgeries"); # 30
s.add("programmed"); # 31
s.add("programers"); # 32
s.add("programming"); # 33
s.add("programed"); # 34
s.add("programer"); # 35
s.add("programmer"); # 36
s.add("programing"); # 37
s.add("program"); # 38
s.add("programmables"); # 39
s.add("programmable"); # 40
s.add("programs"); # 41
s.add("programmers"); # 42
s.add("sited"); # 43
s.add("siting"); # 44
s.add("situations"); # 45
s.add("sitters"); # 46
s.add("sitars"); # 47
s.add("situating"); # 48
s.add("sites"); # 49
s.add("situation"); # 50
s.add("site"); # 51
s.add("situated"); # 52
s.add("sitcom"); # 53
s.add("sits"); # 54
s.add("sitcoms"); # 55
s.add("sit"); # 56
s.add("sittings"); # 57
s.add("sitting"); # 58
s.add("sitar"); # 59
s.add("sitter"); # 60
s.add("situates"); # 61
s.add("situate"); # 62
s.add("plaints"); # 63
s.add("plaintively"); # 64
s.add("plaint"); # 65
s.add("plainclothesmen"); # 66
s.add("plainclothes"); # 67
s.add("plaintiff"); # 68
s.add("plains"); # 69
s.add("plainness"); # 70
s.add("plaintive"); # 71
s.add("plainclothesman"); # 72
s.add("plainly"); # 73
s.add("plain"); # 74
s.add("plaintiffs"); # 75
s.add("plainer"); # 76
s.add("plainest"); # 77
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
std.timestamp("BeforeMatch");
set resp.http.Match = s.hasprefix(req.http.Word);
std.timestamp("AfterMatch");
set resp.http.N = s.nmatches();
set resp.http.Which = s.which();
set resp.http.Which-Unique = s.which(select=UNIQUE);
set resp.http.Which-First = s.which(select=FIRST);
set resp.http.Which-Last = s.which(select=LAST);
set resp.http.Which-Shortest = s.which(select=SHORTEST);
set resp.http.Which-Longest = s.which(select=LONGEST);
return (deliver);
}
}
client c1 {
txreq -hdr "Word: letterheads"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "1"
expect resp.http.Which-Last == "5"
expect resp.http.Which-Shortest == "5"
expect resp.http.Which-Longest == "3"
txreq -hdr "Word: letterhead"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "1"
expect resp.http.Which-Last == "5"
expect resp.http.Which-Shortest == "5"
expect resp.http.Which-Longest == "1"
txreq -hdr "Word: letter"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "5"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "5"
expect resp.http.Which-Last == "5"
expect resp.http.Which-Shortest == "5"
expect resp.http.Which-Longest == "5"
txreq -hdr "Word: letterer"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "5"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "5"
expect resp.http.Which-Last == "5"
expect resp.http.Which-Shortest == "5"
expect resp.http.Which-Longest == "5"
txreq -hdr "Word: letted"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: rhomboids"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "10"
expect resp.http.Which-Last == "14"
expect resp.http.Which-Shortest == "13"
expect resp.http.Which-Longest == "10"
txreq -hdr "Word: rhomboid"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "13"
expect resp.http.Which-Last == "14"
expect resp.http.Which-Shortest == "13"
expect resp.http.Which-Longest == "14"
txreq -hdr "Word: rho"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "13"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "13"
expect resp.http.Which-Last == "13"
expect resp.http.Which-Shortest == "13"
expect resp.http.Which-Longest == "13"
txreq -hdr "Word: rhomboidal"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "13"
expect resp.http.Which-Last == "14"
expect resp.http.Which-Shortest == "13"
expect resp.http.Which-Longest == "14"
txreq -hdr "Word: rhyme"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: forgetfulness"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "4"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "17"
expect resp.http.Which-Last == "28"
expect resp.http.Which-Shortest == "27"
expect resp.http.Which-Longest == "17"
txreq -hdr "Word: forgetful"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "20"
expect resp.http.Which-Last == "28"
expect resp.http.Which-Shortest == "27"
expect resp.http.Which-Longest == "28"
txreq -hdr "Word: forget"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "20"
expect resp.http.Which-Last == "27"
expect resp.http.Which-Shortest == "27"
expect resp.http.Which-Longest == "20"
txreq -hdr "Word: forge"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "27"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "27"
expect resp.http.Which-Last == "27"
expect resp.http.Which-Shortest == "27"
expect resp.http.Which-Longest == "27"
txreq -hdr "Word: forgetfulnesses"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "4"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "17"
expect resp.http.Which-Last == "28"
expect resp.http.Which-Shortest == "27"
expect resp.http.Which-Longest == "17"
txreq -hdr "Word: forgo"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: programmables"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "38"
expect resp.http.Which-Last == "40"
expect resp.http.Which-Shortest == "38"
expect resp.http.Which-Longest == "39"
txreq -hdr "Word: programmable"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "38"
expect resp.http.Which-Last == "40"
expect resp.http.Which-Shortest == "38"
expect resp.http.Which-Longest == "40"
txreq -hdr "Word: program"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "38"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "38"
expect resp.http.Which-Last == "38"
expect resp.http.Which-Shortest == "38"
expect resp.http.Which-Longest == "38"
txreq -hdr "Word: programmings"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "33"
expect resp.http.Which-Last == "38"
expect resp.http.Which-Shortest == "38"
expect resp.http.Which-Longest == "33"
txreq -hdr "Word: programmatic"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "38"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "38"
expect resp.http.Which-Last == "38"
expect resp.http.Which-Shortest == "38"
expect resp.http.Which-Longest == "38"
txreq -hdr "Word: programmatically"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "38"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "38"
expect resp.http.Which-Last == "38"
expect resp.http.Which-Shortest == "38"
expect resp.http.Which-Longest == "38"
txreq -hdr "Word: progeny"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: situates"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "56"
expect resp.http.Which-Last == "62"
expect resp.http.Which-Shortest == "56"
expect resp.http.Which-Longest == "61"
txreq -hdr "Word: situate"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "56"
expect resp.http.Which-Last == "62"
expect resp.http.Which-Shortest == "56"
expect resp.http.Which-Longest == "62"
txreq -hdr "Word: sit"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "56"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "56"
expect resp.http.Which-Last == "56"
expect resp.http.Which-Shortest == "56"
expect resp.http.Which-Longest == "56"
txreq -hdr "Word: sittings"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "56"
expect resp.http.Which-Last == "58"
expect resp.http.Which-Shortest == "56"
expect resp.http.Which-Longest == "57"
txreq -hdr "Word: sitting"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "56"
expect resp.http.Which-Last == "58"
expect resp.http.Which-Shortest == "56"
expect resp.http.Which-Longest == "58"
txreq -hdr "Word: situationally"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "50"
expect resp.http.Which-Last == "56"
expect resp.http.Which-Shortest == "56"
expect resp.http.Which-Longest == "50"
txreq -hdr "Word: side"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: plainclothesman"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "67"
expect resp.http.Which-Last == "74"
expect resp.http.Which-Shortest == "74"
expect resp.http.Which-Longest == "72"
txreq -hdr "Word: plainclothes"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "2"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "67"
expect resp.http.Which-Last == "74"
expect resp.http.Which-Shortest == "74"
expect resp.http.Which-Longest == "67"
txreq -hdr "Word: plain"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "1"
expect resp.http.Which == "74"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "74"
expect resp.http.Which-Last == "74"
expect resp.http.Which-Shortest == "74"
expect resp.http.Which-Longest == "74"
txreq -hdr "Word: plaintiveness"
rxresp
expect resp.status == 200
expect resp.http.Match == "true"
expect resp.http.N == "3"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "65"
expect resp.http.Which-Last == "74"
expect resp.http.Which-Shortest == "74"
expect resp.http.Which-Longest == "71"
txreq -hdr "Word: plaid"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
# Non-matches generated with pwgen.
txreq -hdr "Word: Pagoo6xohf"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: Sheing3chi"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: Vohl1peofe"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: wohheWaiy8"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: xoeke5uM6b"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: eY2eohiemi"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: zaexopoo4U"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: kuz9eiXaew"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: fo2leShohj"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: thooL5peu4"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: aifaeW5dae"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: Aifiehoz3m"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: ahg1Va1hee"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: sowoh6saiX"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: phahc0la8A"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: Eej5xeNies"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: ta2UBaem2k"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: caepez0AiT"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: Buc0ieCohm"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: wie1EHee1o"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: ha6Olo8foo"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: Veengae7Wo"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: ui7OhY8oro"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: aiqui8eTho"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: Wiequeeve1"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: ohMeim7sai"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: Equie2ohri"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: ga5Aepikie"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: Jaibie6che"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
txreq -hdr "Word: reide9aeGh"
rxresp
expect resp.status == 200
expect resp.http.Match == "false"
expect resp.http.N == "0"
expect resp.http.Which == "0"
expect resp.http.Which-Unique == resp.http.Which
expect resp.http.Which-First == "0"
expect resp.http.Which-Last == "0"
expect resp.http.Which-Shortest == "0"
expect resp.http.Which-Longest == "0"
} -run
......@@ -39,6 +39,7 @@
#include "vre.h"
#include "cache/cache_director.h"
#include "vcc_if.h"
#include "patricia.h"
#define VFAIL(ctx, fmt, ...) \
......@@ -48,6 +49,9 @@
VSLb((ctx)->vsl, SLT_VCL_Error, "vmod selector error: " fmt, \
__VA_ARGS__)
#define VERRNOMEM(ctx, fmt, ...) \
VERR((ctx), "out of space: " fmt, __VA_ARGS__)
struct entry {
unsigned magic;
#define VMOD_SELECTOR_ENTRY_MAGIC 0x733dbe63
......@@ -205,11 +209,42 @@ vmod_set_add(VRT_CTX, struct vmod_selector_set *set, VCL_STRING member,
set->table[n - 1] = entry;
}
static struct match_data *
get_match_data(VRT_CTX, struct vmod_selector_set *set, const char *method)
{
struct vmod_priv *task;
struct match_data *match;
task = VRT_priv_task(ctx, set);
AN(task);
if (task->priv == NULL) {
if ((task->priv = WS_Alloc(ctx->ws, sizeof(*match))) == NULL) {
VERRNOMEM(ctx, "Allocating match data in %s.%s()",
set->vcl_name, method);
return (NULL);
}
task->len = sizeof(*match);
task->free = NULL;
match = (struct match_data *)task->priv;
match->magic = MATCH_DATA_MAGIC;
}
else {
WS_Assert_Allocated(ctx->ws, task->priv, sizeof(*match));
CAST_OBJ(match, task->priv, MATCH_DATA_MAGIC);
}
return match;
}
VCL_BOOL
vmod_set_match(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject)
{
unsigned idx;
struct match_data *match;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
AN(set->origo);
AN(set->members);
if (subject == NULL) {
VERR(ctx, "%s.match(): subject string is NULL", set->vcl_name);
......@@ -220,9 +255,162 @@ vmod_set_match(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject)
return (0);
}
match = get_match_data(ctx, set, "match");
if ((idx = PT_Lookup(set->origo, set->members, subject)) == UINT_MAX) {
match->n = 0;
return (0);
}
if ((match->indices = WS_Alloc(ctx->ws, sizeof(unsigned))) == NULL) {
VERRNOMEM(ctx, "Reserving space for index in "
"%s.match(\"%.40s\")", set->vcl_name, subject);
return (0);
}
*match->indices = idx;
match->n = 1;
return (1);
}
VCL_BOOL
vmod_set_hasprefix(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject)
{
struct match_data *match;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
AN(set->origo);
AN(set->members);
return (PT_Lookup(set->origo, set->members, subject) != UINT_MAX);
if (subject == NULL) {
VERR(ctx, "%s.hasprefix(): subject string is NULL",
set->vcl_name);
return (0);
}
if (set->nmembers == 0) {
VERR(ctx, "%s.hasprefix(): no entries were added",
set->vcl_name);
return (0);
}
match = get_match_data(ctx, set, "hasprefix");
if ((match->limit = WS_ReserveLumps(ctx->ws, sizeof(unsigned))) == 0) {
VERRNOMEM(ctx, "Reserving index array in "
"%s.hasprefix(\"%.40s\")", set->vcl_name, subject);
return (0);
}
match->indices = (unsigned *)WS_Front(ctx->ws);
if (PT_Prefixes(set->origo, set->members, subject, match) != 0) {
VERRNOMEM(ctx, "Adding indices in %s.hasprefix(\"%.40s\")",
set->vcl_name, subject);
WS_Release(ctx->ws, 0);
return (0);
}
WS_Release(ctx->ws, match->n * sizeof(unsigned));
return (match->n > 0);
}
static struct match_data *
get_existing_match_data(VRT_CTX,
const struct vmod_selector_set * const restrict set,
const char * const restrict method)
{
struct vmod_priv *task;
struct match_data *match;
task = VRT_priv_task(ctx, set);
AN(task);
if (task->priv == NULL) {
VERR(ctx, "%s.%s() called without prior match", set->vcl_name,
method);
return (NULL);
}
WS_Assert_Allocated(ctx->ws, task->priv, sizeof(*match));
CAST_OBJ(match, task->priv, MATCH_DATA_MAGIC);
return match;
}
VCL_INT
vmod_set_nmatches(VRT_CTX, struct vmod_selector_set *set)
{
struct match_data *match;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
match = get_existing_match_data(ctx, set, "nmatches");
if (match == NULL)
return (0);
return (match->n);
}
VCL_BOOL
vmod_set_matched(VRT_CTX, struct vmod_selector_set *set, VCL_INT idx)
{
struct match_data *match;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
if (idx < 1 || idx > set->nmembers) {
VERR(ctx, "%s.matched(%ld) out of range (%d members)",
set->vcl_name, idx, set->nmembers);
return (0);
}
match = get_existing_match_data(ctx, set, "matched");
if (match == NULL || match->n == 0)
return (0);
AN(match->indices);
WS_Assert_Allocated(ctx->ws, match->indices,
match->n * sizeof(unsigned));
/* XXX search algorithm? */
idx--;
for (unsigned i = 0; i < match->n; i++)
if (match->indices[i] == idx)
return (1);
return (0);
}
static unsigned
select(VRT_CTX, const struct match_data * const restrict match,
const char * const restrict obj, VCL_ENUM const restrict selects,
const char * const restrict method)
{
if (selects == vmod_enum_UNIQUE) {
if (match->n != 1) {
VERR(ctx, "%s.%s(select=UNIQUE): "
"%d elements were matched", obj, method, match->n);
return (UINT_MAX);
}
return match->indices[0];
}
if (selects == vmod_enum_FIRST)
return match->min;
if (selects == vmod_enum_LAST)
return match->max;
if (selects == vmod_enum_SHORTEST)
return match->indices[0];
if (selects == vmod_enum_LONGEST)
return match->indices[match->n - 1];
WRONG("illegal select enum");
return (UINT_MAX);
}
VCL_INT
vmod_set_which(VRT_CTX, struct vmod_selector_set *set, VCL_ENUM selects)
{
struct match_data *match;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
match = get_existing_match_data(ctx, set, "which");
if (match == NULL || match->n == 0)
return (0);
return (select(ctx, match, set->vcl_name, selects, "which") + 1);
}
VCL_STRING
......
......@@ -64,6 +64,46 @@ Example::
call do_on_match;
}
$Method BOOL .hasprefix(STRING)
Returns ``true`` if and only if ...
Example::
if (myset.hasprefix(req.url)) {
call do_if_prefix_matched;
}
$Method INT .nmatches()
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
$Method BOOL .matched(INT)
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
$Method INT .which(ENUM {UNIQUE, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE)
Returns ...
Example::
if (myset.hasprefix(req.url)) {
# ...
}
$Method STRING .debug()
Intentionally not documented.
......
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