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

Compilation failures cause the VCL load to fails; CHANGES THE INTERFACE.

The .failed() and .error() methods have been removed.
parent 1d119a29
Pipeline #201 skipped
...@@ -126,43 +126,11 @@ Description ...@@ -126,43 +126,11 @@ Description
should include any capturing parentheses that will be needed should include any capturing parentheses that will be needed
for extracting backreferences. for extracting backreferences.
Example If the regular expression fails to compile, then the VCL
``new myregex = re.regex("\bmax-age\s*=\s*(\d+)");`` load fails with an error message describing the problem.
.. _func_regex.failed:
regex.failed
------------
::
BOOL regex.failed()
Description
Returns true if regex compilation in the constructor failed.
NOTE: This method only pertains to compilation in the
constructor, not to compilation of a regex in ``match_dyn``.
Example Example
``if (myregex.failed()) { # ...`` ``new myregex = re.regex("\bmax-age\s*=\s*(\d+)");``
.. _func_regex.error:
regex.error
-----------
::
STRING regex.error()
Description
Returns an error message if regex compilation in the
constructor failed, or the empty string if compilation
succedded. Like ``failed`` this only pertains to failures of
compilation in the constructor, not in ``match_dyn``.
Example
``std.log("myregex failed to compile: " + myregex.error());``
.. _func_regex.match: .. _func_regex.match:
...@@ -228,6 +196,11 @@ Description ...@@ -228,6 +196,11 @@ Description
and determines whether it matches the string in the second and determines whether it matches the string in the second
argument. argument.
If the regular expression fails to compile, then an error
message describing the problem is emitted to the Varnish log
with the tag ``VCL_Error``, and ``match_dyn`` returns
``false``.
Example Example
``if (re.match_dyn(req.http.Foo + "(\d+)", beresp.http.Bar)) { # ...`` ``if (re.match_dyn(req.http.Foo + "(\d+)", beresp.http.Bar)) { # ...``
......
...@@ -15,16 +15,6 @@ varnish v1 -vcl+backend { ...@@ -15,16 +15,6 @@ varnish v1 -vcl+backend {
} }
sub vcl_recv { sub vcl_recv {
if (foobar.failed()) {
return(synth(999, "foobar failed"));
}
if (snafu.failed()) {
return(synth(999, "snafu failed"));
}
if (bar.failed()) {
return(synth(999, "bar failed"));
}
if (foobar.match(req.url)) { if (foobar.match(req.url)) {
return(pass); return(pass);
} else if (snafu.match(req.url)) { } else if (snafu.match(req.url)) {
...@@ -46,10 +36,6 @@ varnish v1 -vcl+backend { ...@@ -46,10 +36,6 @@ varnish v1 -vcl+backend {
} else { } else {
set beresp.status = 999; set beresp.status = 999;
} }
set beresp.http.foobarerr = foobar.error();
set beresp.http.snafuerr = snafu.error();
set beresp.http.barerr = bar.error();
} }
} -start } -start
...@@ -60,8 +46,4 @@ client c1 { ...@@ -60,8 +46,4 @@ client c1 {
expect resp.status == "200" expect resp.status == "200"
expect resp.http.foo1 == "1" expect resp.http.foo1 == "1"
expect resp.http.bar1 == "2" expect resp.http.bar1 == "2"
expect resp.http.foobarerr == ""
expect resp.http.snafuerr == ""
expect resp.http.barerr == ""
} -run } -run
varnishtest "regex compilation failure" varnishtest "regex compilation failure"
server s1 { varnish v1 -vcl { backend b { .host = "${bad_ip}"; } } -start
rxreq
txresp -hdr "Foo: bar" -hdr "Baz: quux" -body "foobar"
} -start
varnish v1 -vcl+backend { varnish v1 -errvcl {vmod re: error compiling regex} {
import re from "${vmod_topbuild}/src/.libs/libvmod_re.so"; import re from "${vmod_topbuild}/src/.libs/libvmod_re.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init { sub vcl_init {
new paren = re.regex("("); new paren = re.regex("(");
} }
}
sub vcl_recv {
if (!paren.failed()) {
return(synth(999, "paren should have failed"));
}
}
sub vcl_backend_response {
if (paren.match(beresp.http.foo)) {
set beresp.http.foo = "baz";
}
else {
set beresp.http.error = paren.error();
}
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.content-length == 6
expect resp.http.foo == "bar"
expect resp.http.baz == "quux"
expect resp.http.error != <undef>
expect resp.http.error != ""
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "vmod re: error compiling regex:"
expect * = End
} -run
varnishtest "backrefs always fail when compilation failed" varnishtest "dynamic backrefs always fail when compilation failed"
server s1 { server s1 {
rxreq rxreq
...@@ -8,32 +8,7 @@ server s1 { ...@@ -8,32 +8,7 @@ server s1 {
varnish v1 -vcl+backend { varnish v1 -vcl+backend {
import re from "${vmod_topbuild}/src/.libs/libvmod_re.so"; import re from "${vmod_topbuild}/src/.libs/libvmod_re.so";
sub vcl_init {
new paren = re.regex("(");
new parend = re.regex("");
}
sub vcl_deliver { sub vcl_deliver {
set resp.http.paren = paren.failed();
set resp.http.error = paren.error();
/* match fails */
if (paren.match(resp.http.foo)) {
set resp.http.match = "success";
}
/* ... so all backrefs fail */
set resp.http.paren0 = paren.backref(0, "fallback0");
set resp.http.paren1 = paren.backref(1, "fallback1");
set resp.http.paren2 = paren.backref(2, "fallback2");
set resp.http.paren3 = paren.backref(3, "fallback3");
set resp.http.paren4 = paren.backref(4, "fallback4");
set resp.http.paren5 = paren.backref(5, "fallback5");
set resp.http.paren6 = paren.backref(6, "fallback6");
set resp.http.paren7 = paren.backref(7, "fallback7");
set resp.http.paren8 = paren.backref(8, "fallback8");
set resp.http.paren9 = paren.backref(9, "fallback9");
set resp.http.paren10 = paren.backref(10, "fallback10");
if (!re.match_dyn("(bar)", resp.http.foo)) { if (!re.match_dyn("(bar)", resp.http.foo)) {
set resp.status = 999; set resp.status = 999;
return(deliver); return(deliver);
...@@ -63,22 +38,6 @@ client c1 { ...@@ -63,22 +38,6 @@ client c1 {
txreq txreq
rxresp rxresp
expect resp.status == 200 expect resp.status == 200
expect resp.http.paren == "true"
expect resp.http.error != <undef>
expect resp.http.error != ""
expect resp.http.match == <undef>
expect resp.http.paren0 == "fallback0"
expect resp.http.paren1 == "fallback1"
expect resp.http.paren2 == "fallback2"
expect resp.http.paren3 == "fallback3"
expect resp.http.paren4 == "fallback4"
expect resp.http.paren5 == "fallback5"
expect resp.http.paren6 == "fallback6"
expect resp.http.paren7 == "fallback7"
expect resp.http.paren8 == "fallback8"
expect resp.http.paren9 == "fallback9"
expect resp.http.paren10 == "fallback10"
expect resp.http.matchd == <undef> expect resp.http.matchd == <undef>
expect resp.http.paren0d == "fallback0" expect resp.http.paren0d == "fallback0"
expect resp.http.paren1d == "fallback1" expect resp.http.paren1d == "fallback1"
...@@ -96,9 +55,6 @@ client c1 { ...@@ -96,9 +55,6 @@ client c1 {
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" { logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req expect 0 * Begin req
# from match()
expect * = VCL_Error "^vmod re: error compiling regex:"
# from match_dyn() # from match_dyn()
expect * = VCL_Error "^vmod re: error compiling regex" expect * = VCL_Error "^vmod re: error compiling regex"
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "vcl.h"
#include "vre.h" #include "vre.h"
#include "cache/cache.h" #include "cache/cache.h"
#include "vrt.h" #include "vrt.h"
...@@ -59,8 +60,6 @@ struct vmod_re_regex { ...@@ -59,8 +60,6 @@ struct vmod_re_regex {
unsigned magic; unsigned magic;
#define VMOD_RE_REGEX_MAGIC 0x955706ee #define VMOD_RE_REGEX_MAGIC 0x955706ee
vre_t *vre; vre_t *vre;
int erroffset;
const char *error;
}; };
typedef struct ov_s { typedef struct ov_s {
...@@ -70,58 +69,51 @@ typedef struct ov_s { ...@@ -70,58 +69,51 @@ typedef struct ov_s {
int ovector[MAX_OV_USED]; int ovector[MAX_OV_USED];
} ov_t; } ov_t;
static void
errmsg(VRT_CTX, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
if (ctx->vsl)
VSLbv(ctx->vsl, SLT_VCL_Error, fmt, args);
else
VSLv(SLT_VCL_Error, 0, fmt, args);
va_end(args);
if (ctx->method == VCL_MET_INIT) {
AN(ctx->msg);
va_start(args, fmt);
VSB_vprintf(ctx->msg, fmt, args);
va_end(args);
VRT_handling(ctx, VCL_RET_FAIL);
}
}
VCL_VOID VCL_VOID
vmod_regex__init(VRT_CTX, struct vmod_re_regex **rep, const char *vcl_name, vmod_regex__init(VRT_CTX, struct vmod_re_regex **rep, const char *vcl_name,
VCL_STRING pattern) VCL_STRING pattern)
{ {
struct vmod_re_regex *re; struct vmod_re_regex *re;
vre_t *vre;
int erroffset;
const char *error;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(rep); AN(rep);
AZ(*rep); AZ(*rep);
AN(vcl_name); AN(vcl_name);
AN(pattern); AN(pattern);
if ((vre = VRE_compile(pattern, 0, &error, &erroffset)) == NULL)
errmsg(ctx, "vmod re: error compiling regex \"%s\" in %s "
"constructor: %s (at offset %d)", pattern, vcl_name,
error, erroffset);
ALLOC_OBJ(re, VMOD_RE_REGEX_MAGIC); ALLOC_OBJ(re, VMOD_RE_REGEX_MAGIC);
AN(re); AN(re);
*rep = re; *rep = re;
re->vre = vre;
re->erroffset = 0;
re->error = NULL;
re->vre = VRE_compile(pattern, 0, &re->error, &re->erroffset);
#if 0
if (re->vre == NULL)
VSLb(ctx->vsl, SLT_VCL_Error,
"vmod re: error compiling regex \"%s\" in VCL \"%s\": "
"%s (position %d)", pattern, vcl_name, error, erroffset);
#endif
}
VCL_BOOL
vmod_regex_failed(VRT_CTX, struct vmod_re_regex *re)
{
(void) ctx;
CHECK_OBJ_NOTNULL(re, VMOD_RE_REGEX_MAGIC);
return (re->error != NULL);
}
VCL_STRING
vmod_regex_error(VRT_CTX, struct vmod_re_regex *re)
{
VCL_STRING error;
CHECK_OBJ_NOTNULL(re, VMOD_RE_REGEX_MAGIC);
if (re->error == NULL)
return "";
error = (VCL_STRING) WS_Printf(ctx->ws, "%s (position %d)", re->error,
re->erroffset);
if (error == NULL) {
VSLb(ctx->vsl, SLT_VCL_Error,
"vmod re: insufficient workspace for error message");
return "insufficient workspace for error message";
}
return(error);
} }
VCL_VOID VCL_VOID
...@@ -253,15 +245,7 @@ vmod_regex_match(VRT_CTX, struct vmod_re_regex *re, VCL_STRING subject) ...@@ -253,15 +245,7 @@ vmod_regex_match(VRT_CTX, struct vmod_re_regex *re, VCL_STRING subject)
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(re, VMOD_RE_REGEX_MAGIC); CHECK_OBJ_NOTNULL(re, VMOD_RE_REGEX_MAGIC);
AN(re->vre);
/* compilation error at init time */
if (re->vre == NULL) {
AN(re->error);
VSLb(ctx->vsl, SLT_VCL_Error,
"vmod re: error compiling regex: %s (position %d)",
re->error, re->erroffset);
return 0;
}
task = VRT_priv_task(ctx, re); task = VRT_priv_task(ctx, re);
AN(task); AN(task);
......
...@@ -96,29 +96,11 @@ Description ...@@ -96,29 +96,11 @@ Description
should include any capturing parentheses that will be needed should include any capturing parentheses that will be needed
for extracting backreferences. for extracting backreferences.
Example If the regular expression fails to compile, then the VCL
``new myregex = re.regex("\bmax-age\s*=\s*(\d+)");`` load fails with an error message describing the problem.
$Method BOOL .failed()
Description
Returns true if regex compilation in the constructor failed.
NOTE: This method only pertains to compilation in the
constructor, not to compilation of a regex in ``match_dyn``.
Example
``if (myregex.failed()) { # ...``
$Method STRING .error()
Description
Returns an error message if regex compilation in the
constructor failed, or the empty string if compilation
succedded. Like ``failed`` this only pertains to failures of
compilation in the constructor, not in ``match_dyn``.
Example Example
``std.log("myregex failed to compile: " + myregex.error());`` ``new myregex = re.regex("\bmax-age\s*=\s*(\d+)");``
$Method BOOL .match(STRING) $Method BOOL .match(STRING)
...@@ -163,6 +145,11 @@ Description ...@@ -163,6 +145,11 @@ Description
and determines whether it matches the string in the second and determines whether it matches the string in the second
argument. argument.
If the regular expression fails to compile, then an error
message describing the problem is emitted to the Varnish log
with the tag ``VCL_Error``, and ``match_dyn`` returns
``false``.
Example Example
``if (re.match_dyn(req.http.Foo + "(\d+)", beresp.http.Bar)) { # ...`` ``if (re.match_dyn(req.http.Foo + "(\d+)", beresp.http.Bar)) { # ...``
......
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