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
should include any capturing parentheses that will be needed
for extracting backreferences.
Example
``new myregex = re.regex("\bmax-age\s*=\s*(\d+)");``
.. _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``.
If the regular expression fails to compile, then the VCL
load fails with an error message describing the problem.
Example
``if (myregex.failed()) { # ...``
.. _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());``
``new myregex = re.regex("\bmax-age\s*=\s*(\d+)");``
.. _func_regex.match:
......@@ -228,6 +196,11 @@ Description
and determines whether it matches the string in the second
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
``if (re.match_dyn(req.http.Foo + "(\d+)", beresp.http.Bar)) { # ...``
......
......@@ -15,16 +15,6 @@ varnish v1 -vcl+backend {
}
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)) {
return(pass);
} else if (snafu.match(req.url)) {
......@@ -46,10 +36,6 @@ varnish v1 -vcl+backend {
} else {
set beresp.status = 999;
}
set beresp.http.foobarerr = foobar.error();
set beresp.http.snafuerr = snafu.error();
set beresp.http.barerr = bar.error();
}
} -start
......@@ -60,8 +46,4 @@ client c1 {
expect resp.status == "200"
expect resp.http.foo1 == "1"
expect resp.http.bar1 == "2"
expect resp.http.foobarerr == ""
expect resp.http.snafuerr == ""
expect resp.http.barerr == ""
} -run
varnishtest "regex compilation failure"
server s1 {
rxreq
txresp -hdr "Foo: bar" -hdr "Baz: quux" -body "foobar"
} -start
varnish v1 -vcl { backend b { .host = "${bad_ip}"; } } -start
varnish v1 -vcl+backend {
varnish v1 -errvcl {vmod re: error compiling regex} {
import re from "${vmod_topbuild}/src/.libs/libvmod_re.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
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 {
rxreq
......@@ -8,32 +8,7 @@ server s1 {
varnish v1 -vcl+backend {
import re from "${vmod_topbuild}/src/.libs/libvmod_re.so";
sub vcl_init {
new paren = re.regex("(");
new parend = re.regex("");
}
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)) {
set resp.status = 999;
return(deliver);
......@@ -63,22 +38,6 @@ client c1 {
txreq
rxresp
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.paren0d == "fallback0"
expect resp.http.paren1d == "fallback1"
......@@ -96,9 +55,6 @@ client c1 {
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
# from match()
expect * = VCL_Error "^vmod re: error compiling regex:"
# from match_dyn()
expect * = VCL_Error "^vmod re: error compiling regex"
......
......@@ -31,6 +31,7 @@
#include <stdlib.h>
#include "vcl.h"
#include "vre.h"
#include "cache/cache.h"
#include "vrt.h"
......@@ -59,8 +60,6 @@ struct vmod_re_regex {
unsigned magic;
#define VMOD_RE_REGEX_MAGIC 0x955706ee
vre_t *vre;
int erroffset;
const char *error;
};
typedef struct ov_s {
......@@ -70,58 +69,51 @@ typedef struct ov_s {
int ovector[MAX_OV_USED];
} 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
vmod_regex__init(VRT_CTX, struct vmod_re_regex **rep, const char *vcl_name,
VCL_STRING pattern)
{
struct vmod_re_regex *re;
vre_t *vre;
int erroffset;
const char *error;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(rep);
AZ(*rep);
AN(vcl_name);
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);
AN(re);
*rep = re;
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);
re->vre = vre;
}
VCL_VOID
......@@ -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(re, VMOD_RE_REGEX_MAGIC);
/* 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;
}
AN(re->vre);
task = VRT_priv_task(ctx, re);
AN(task);
......
......@@ -96,29 +96,11 @@ Description
should include any capturing parentheses that will be needed
for extracting backreferences.
Example
``new myregex = re.regex("\bmax-age\s*=\s*(\d+)");``
$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``.
If the regular expression fails to compile, then the VCL
load fails with an error message describing the problem.
Example
``std.log("myregex failed to compile: " + myregex.error());``
``new myregex = re.regex("\bmax-age\s*=\s*(\d+)");``
$Method BOOL .match(STRING)
......@@ -163,6 +145,11 @@ Description
and determines whether it matches the string in the second
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
``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