Commit a43e7ab7 authored by Geoff Simmons's avatar Geoff Simmons

Implement case-insensitive prefix matching.

parent add2a97d
......@@ -776,3 +776,284 @@ client c1 {
rxresp
expect resp.http.Match == "false"
} -run
# Case-insensitive prefix matching
varnish v1 -vcl {
import ${vmod_selector};
import std;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set(case_sensitive=false);
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-Exact = s.which(select=EXACT);
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-Exact == "4"
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-Exact == "3"
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-Exact == "2"
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-Exact == "1"
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-Exact == "0"
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-Exact == "0"
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-Exact == "0"
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-Exact == "0"
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
# Part of the test from prefix.vtc with randomized capitalization.
varnish v1 -vcl {
import ${vmod_selector};
import std;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = selector.set(case_sensitive=false);
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
}
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-Exact = s.which(select=EXACT);
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-Exact == "3"
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-Exact == "1"
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-Exact == "5"
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-Exact == "0"
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-Exact == "0"
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
......@@ -307,11 +307,12 @@ VCL_BOOL
vmod_set_hasprefix(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject)
{
struct match_data *match;
char **members;
const char *subj;
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.hasprefix(): subject string is NULL",
......@@ -324,6 +325,23 @@ vmod_set_hasprefix(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject)
return (0);
}
members = set->members;
subj = subject;
if (!set->case_sensitive) {
char *copy;
if ((copy = WS_Copy(ctx->ws, subject, -1)) == NULL) {
VERRNOMEM(ctx, "%s.hasprefix(): copying subject for "
"case-insensitive match", set->vcl_name);
return (0);
}
for (char *c = copy; *c; c++)
*c = tolower(*c);
subj = copy;
members = set->lomembers;
}
AN(members);
match = get_match_data(ctx, set, "hasprefix");
if ((match->limit = WS_ReserveLumps(ctx->ws, sizeof(unsigned))) == 0) {
VERRNOMEM(ctx, "Reserving index array in "
......@@ -332,7 +350,7 @@ vmod_set_hasprefix(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject)
}
match->indices = (unsigned *)WS_Front(ctx->ws);
if (PT_Prefixes(set->origo, set->members, subject, match) != 0) {
if (PT_Prefixes(set->origo, members, subj, match) != 0) {
VERRNOMEM(ctx, "Adding indices in %s.hasprefix(\"%.40s\")",
set->vcl_name, subject);
WS_Release(ctx->ws, 0);
......
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