Commit d84398c4 authored by Geoff Simmons's avatar Geoff Simmons

Add the namedref() function (still could use some refactoring).

parent 974cc032
Pipeline #246 skipped
...@@ -40,6 +40,7 @@ CONTENTS ...@@ -40,6 +40,7 @@ CONTENTS
* regex(STRING, BOOL, BOOL, ENUM {ANYCRLF,UNICODE}, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, STRING, BOOL, INT, BOOL, BOOL, BOOL, BOOL, ENUM {CR,LF,CRLF,ANYCRLF,ANY}, BOOL, BOOL, BOOL, BOOL, BOOL, INT, BOOL, BOOL, BOOL, BOOL) * regex(STRING, BOOL, BOOL, ENUM {ANYCRLF,UNICODE}, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, STRING, BOOL, INT, BOOL, BOOL, BOOL, BOOL, ENUM {CR,LF,CRLF,ANYCRLF,ANY}, BOOL, BOOL, BOOL, BOOL, BOOL, INT, BOOL, BOOL, BOOL, BOOL)
* BOOL match(PRIV_CALL, PRIV_TASK, STRING, STRING, BOOL, BOOL, ENUM {ANYCRLF,UNICODE}, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, STRING, BOOL, INT, BOOL, BOOL, BOOL, BOOL, ENUM {CR,LF,CRLF,ANYCRLF,ANY}, BOOL, BOOL, BOOL, BOOL, BOOL, INT, BOOL, BOOL, BOOL, BOOL, INT, INT, INT, BOOL, BOOL, BOOL, BOOL, BOOL, ENUM {HARD,SOFT}, INT) * BOOL match(PRIV_CALL, PRIV_TASK, STRING, STRING, BOOL, BOOL, ENUM {ANYCRLF,UNICODE}, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, STRING, BOOL, INT, BOOL, BOOL, BOOL, BOOL, ENUM {CR,LF,CRLF,ANYCRLF,ANY}, BOOL, BOOL, BOOL, BOOL, BOOL, INT, BOOL, BOOL, BOOL, BOOL, INT, INT, INT, BOOL, BOOL, BOOL, BOOL, BOOL, ENUM {HARD,SOFT}, INT)
* STRING backref(PRIV_TASK, INT, STRING) * STRING backref(PRIV_TASK, INT, STRING)
* STRING namedref(PRIV_TASK, STRING, STRING)
* BOOL config_bool(ENUM {JIT,STACKRECURSE,UNICODE}) * BOOL config_bool(ENUM {JIT,STACKRECURSE,UNICODE})
* STRING config_str(ENUM {BSR,JITTARGET,NEWLINE,UNICODE_VERSION,VERSION}) * STRING config_str(ENUM {BSR,JITTARGET,NEWLINE,UNICODE_VERSION,VERSION})
* INT config_int(ENUM {LINKSIZE,MATCHLIMIT,PARENSLIMIT,RECURSIONLIMIT}) * INT config_int(ENUM {LINKSIZE,MATCHLIMIT,PARENSLIMIT,RECURSIONLIMIT})
...@@ -101,6 +102,15 @@ backref ...@@ -101,6 +102,15 @@ backref
STRING backref(PRIV_TASK, INT ref, STRING fallback="**BACKREF FUNCTION FAILED**") STRING backref(PRIV_TASK, INT ref, STRING fallback="**BACKREF FUNCTION FAILED**")
.. _func_namedref:
namedref
--------
::
STRING namedref(PRIV_TASK, STRING name, STRING fallback="**NAMEDREF FUNCTION FAILED**")
.. _func_config_bool: .. _func_config_bool:
config_bool config_bool
......
...@@ -37,6 +37,31 @@ varnish v1 -vcl { ...@@ -37,6 +37,31 @@ varnish v1 -vcl {
else { else {
set resp.status = 999; set resp.status = 999;
} }
# Again with the namedref function
if (pcre2.match("(?<bar>bar)(?<baz>baz)", "barbaz")) {
set resp.http.bar-bar-f
= pcre2.namedref("bar", "err_bar");
set resp.http.bar-baz-f
= pcre2.namedref("baz", "err_baz");
set resp.http.bar0-f = pcre2.backref(0, "error0");
set resp.http.bar1-f = pcre2.backref(1, "error1");
set resp.http.bar2-f = pcre2.backref(2, "error2");
}
else {
set resp.status = 999;
}
if (pcre2.match("(?<baz>baz)(?<dots>.+)", "bazquux")) {
set resp.http.baz-baz-f
= pcre2.namedref("baz", "err_baz");
set resp.http.baz-dots-f
= pcre2.namedref("dots", "err_dots");
set resp.http.baz0-f = pcre2.backref(0, "error0");
set resp.http.baz1-f = pcre2.backref(1, "error1");
set resp.http.baz2-f = pcre2.backref(2, "error2");
}
else {
set resp.status = 999;
}
} }
} -start } -start
...@@ -54,6 +79,16 @@ client c1 -repeat 2 { ...@@ -54,6 +79,16 @@ client c1 -repeat 2 {
expect resp.http.baz0 == "bazquux" expect resp.http.baz0 == "bazquux"
expect resp.http.baz1 == "baz" expect resp.http.baz1 == "baz"
expect resp.http.baz2 == "quux" expect resp.http.baz2 == "quux"
expect resp.http.bar-bar-f == "bar"
expect resp.http.bar-baz-f == "baz"
expect resp.http.baz-baz-f == "baz"
expect resp.http.baz-dots-f == "quux"
expect resp.http.bar0-f == "barbaz"
expect resp.http.bar1-f == "bar"
expect resp.http.bar2-f == "baz"
expect resp.http.baz0-f == "bazquux"
expect resp.http.baz1-f == "baz"
expect resp.http.baz2-f == "quux"
} -run } -run
# failure # failure
...@@ -169,3 +204,114 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" { ...@@ -169,3 +204,114 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect * = VCL_Error "^vmod pcre2 error: in foo.backref..: unknown substring$" expect * = VCL_Error "^vmod pcre2 error: in foo.backref..: unknown substring$"
expect * = End expect * = End
} -run } -run
# failure again with the namedref function
varnish v1 -vcl {
import pcre2 from "${vmod_topbuild}/src/.libs/libvmod_pcre2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new frobnitz = pcre2.regex("(?<frob>frob)(?<nitz>nitz)");
new barbaz = pcre2.regex("(?<bar>bar)(?<baz>baz)");
new azbc = pcre2.regex("(?<a>a|(?<z>z))(?<bc>bc)");
new foo = pcre2.regex("(?<f>f)(?<o>o)(o)",
no_auto_capture=true);
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.nomatch = pcre2.namedref("bar");
if (pcre2.match("(?<bar>bar)(?<baz>baz)", "barbaz")) {
set resp.http.bar-bar
= pcre2.namedref("bar", "err_bar");
# no such name
set resp.http.bar-quux
= pcre2.namedref("quux", "err_quux");
# fallback is NULL
set resp.http.fallback
= pcre2.namedref("bar", req.http.undef);
}
set resp.http.frob1
= pcre2.match("(?<frob>frob)(?<nitz>nitz)", "barbaz");
set resp.http.frob1-frob
= pcre2.namedref("frob", "err_frob");
set resp.http.frob1-nitz
= pcre2.namedref("nitz", "err_nitz");
set resp.http.frob-yes
= pcre2.match("(?<frob>frob)(?<nitz>nitz)", "frobnitz");
set resp.http.frob-no
= pcre2.match("(?<frob>frob)(?<nitz>nitz)", "barbaz");
set resp.http.frob2-frob
= pcre2.namedref("frob", "err_frob");
set resp.http.frob2-nitz
= pcre2.namedref("nitz", "err_nitz");
set resp.http.azbc
= pcre2.match("(?<a>a|(?<z>z))(?<bc>bc)", "abc");
set resp.http.azbc-a = pcre2.namedref("a", "err_a");
set resp.http.azbc-z = pcre2.namedref("z", "err_z");
set resp.http.azbc-bc = pcre2.namedref("bc", "err_bc");
set resp.http.foo
= pcre2.match("(?<f>f)(?<o>o)(o)", "foo",
no_auto_capture=true);
set resp.http.foo-f = pcre2.namedref("f", "err_f");
set resp.http.foo-o = pcre2.namedref("o", "err_o");
set resp.http.foo-0 = pcre2.backref(0, "error0");
set resp.http.foo-1 = pcre2.backref(1, "error1");
set resp.http.foo-2 = pcre2.backref(2, "error2");
set resp.http.foo-3 = pcre2.backref(3, "error3");
}
}
logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod pcre2 error: pcre2.namedref.. called without prior match$"
expect * = VCL_Error "^vmod pcre2 error: in pcre2.namedref..: unknown substring$"
expect * = VCL_Error "^vmod pcre2 error: in pcre2.namedref..: fallback is undefined$"
expect * = VCL_Error "^vmod pcre2 error: in pcre2.namedref..: no match$"
expect * = VCL_Error "^vmod pcre2 error: in pcre2.namedref..: no match$"
expect * = VCL_Error "^vmod pcre2 error: in pcre2.namedref..: no match$"
expect * = VCL_Error "^vmod pcre2 error: in pcre2.namedref..: no match$"
expect * = VCL_Error "^vmod pcre2 error: in pcre2.namedref..: requested value is not set$"
expect * = VCL_Error "^vmod pcre2 error: in pcre2.backref..: unknown substring$"
expect * = End
} -start
client c1 -repeat 2 {
txreq
rxresp
expect resp.status == "200"
expect resp.http.nomatch == "**NAMEDREF FUNCTION FAILED**"
expect resp.http.bar-bar == "bar"
expect resp.http.bar-quux == "err_quux"
expect resp.http.fallback == "**NAMEDREF FUNCTION FAILED**"
expect resp.http.frob1 == "false"
expect resp.http.frob1-frob == "err_frob"
expect resp.http.frob1-nitz == "err_nitz"
expect resp.http.frob-yes == "true"
expect resp.http.frob-no == "false"
expect resp.http.frob2-frob == "err_frob"
expect resp.http.frob2-nitz == "err_nitz"
expect resp.http.azbc == "true"
expect resp.http.azbc-a == "a"
expect resp.http.azbc-z == "err_z"
expect resp.http.azbc-bc == "bc"
expect resp.http.foo == "true"
expect resp.http.foo-f == "f"
expect resp.http.foo-o == "o"
expect resp.http.foo-0 == "foo"
expect resp.http.foo-1 == "f"
expect resp.http.foo-2 == "o"
expect resp.http.foo-3 == "error3"
} -run
logexpect l1 -wait
...@@ -904,6 +904,30 @@ vmod_backref(VRT_CTX, struct vmod_priv *task, VCL_INT ref, VCL_STRING fallback) ...@@ -904,6 +904,30 @@ vmod_backref(VRT_CTX, struct vmod_priv *task, VCL_INT ref, VCL_STRING fallback)
"pcre2", "backref", "**BACKREF FUNCTION FAILED**"); "pcre2", "backref", "**BACKREF FUNCTION FAILED**");
} }
VCL_STRING
vmod_namedref(VRT_CTX, struct vmod_priv *task, VCL_STRING name,
VCL_STRING fallback)
{
struct task *match_task;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(task);
if (fallback == NULL) {
ERR(ctx, "in pcre2.namedref(): fallback is undefined");
return "**NAMEDREF FUNCTION FAILED**";
}
if (task->priv == NULL) {
ERR(ctx, "pcre2.namedref() called without prior match");
return fallback;
}
WS_Assert_Allocated(ctx->ws, task->priv, sizeof(*match_task));
CAST_OBJ(match_task, task->priv, VMOD_PCRE2_TASK_MAGIC);
return refer(ctx, -1, name, fallback, NAMED, match_task->mdata, "pcre2",
"namedref", "**NAMEDREF FUNCTION FAILED**");
}
/* Functions */ /* Functions */
VCL_BOOL VCL_BOOL
......
...@@ -67,6 +67,9 @@ $Function BOOL match(PRIV_CALL, PRIV_TASK, STRING pattern, STRING subject, ...@@ -67,6 +67,9 @@ $Function BOOL match(PRIV_CALL, PRIV_TASK, STRING pattern, STRING subject,
$Function STRING backref(PRIV_TASK, INT ref, $Function STRING backref(PRIV_TASK, INT ref,
STRING fallback = "**BACKREF FUNCTION FAILED**") STRING fallback = "**BACKREF FUNCTION FAILED**")
$Function STRING namedref(PRIV_TASK, STRING name,
STRING fallback = "**NAMEDREF FUNCTION FAILED**")
$Function BOOL config_bool(ENUM {JIT, STACKRECURSE, UNICODE}) $Function BOOL config_bool(ENUM {JIT, STACKRECURSE, UNICODE})
$Function STRING config_str(ENUM {BSR, JITTARGET, NEWLINE, UNICODE_VERSION, $Function STRING config_str(ENUM {BSR, JITTARGET, NEWLINE, UNICODE_VERSION,
......
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