[master] 8e5c7a0 Add fallback on std conversion functions.
Lasse Karstensen
lkarsten at varnish-software.com
Thu Sep 10 14:29:03 CEST 2015
commit 8e5c7a0a610200089d7aca5edbde6e25de5e804d
Author: Lasse Karstensen <lkarsten at varnish-software.com>
Date: Thu Sep 10 14:21:04 2015 +0200
Add fallback on std conversion functions.
Handle that conversion between VCL data type can fail,
and return a user-specificed fallback in those cases.
Mostly identical to patch from Arianna Aondio.
diff --git a/bin/varnishtest/tests/m00016.vtc b/bin/varnishtest/tests/m00016.vtc
index ef51f93..261f840 100644
--- a/bin/varnishtest/tests/m00016.vtc
+++ b/bin/varnishtest/tests/m00016.vtc
@@ -1,4 +1,4 @@
-varnishtest "Test std.real2time, std.time2integer and std.time2real"
+varnishtest "Test real2integer, real2time, time2integer and time2real in std"
server s1 {
rxreq
@@ -10,8 +10,18 @@ varnish v1 -vcl+backend {
sub vcl_deliver {
set resp.http.x-foo = std.integer(req.http.foo, 0);
- set resp.http.x-bar = std.time2integer(std.real2time(std.real(resp.http.x-foo, 0.0)));
- set resp.http.x-baz = std.time2real(std.real2time(std.real(resp.http.x-foo, 0.0)));
+ set resp.http.x-bar = std.time2integer(std.real2time(
+ std.real(resp.http.x-foo, 0.0), now), 1);
+
+ set resp.http.x-baz = std.time2real(std.real2time(
+ std.real(resp.http.x-foo, 0.0), now), 1.0);
+
+ set resp.http.x-qux = std.real2integer(
+ std.real(req.http.foo, 2.0), 2);
+
+ # Representation of 9e99, which is larger than what fits in the
+ # 128bit integers on $exotic_platform.
+ set resp.http.x-int-fallback = std.real2integer(9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000, 2);
}
} -start
@@ -20,4 +30,15 @@ client c1 {
rxresp
expect resp.http.x-foo == resp.http.x-bar
expect resp.http.x-baz == 1140618699.000
+ expect resp.http.x-qux == 1140618699
+ expect resp.http.x-int-fallback == 2
+} -run
+
+# check we get the fallback if the conversion fails
+client c2 {
+ txreq -hdr "foo: -9e99+1"
+ rxresp
+ expect resp.http.x-bar == 0
+ expect resp.http.x-baz == 0.000
+ expect resp.http.x-qux == 2
} -run
diff --git a/bin/varnishtest/tests/r01532.vtc b/bin/varnishtest/tests/r01532.vtc
index c189f55..b1ff007 100644
--- a/bin/varnishtest/tests/r01532.vtc
+++ b/bin/varnishtest/tests/r01532.vtc
@@ -9,7 +9,7 @@ varnish v1 -vcl+backend {
import ${vmod_std};
sub vcl_deliver {
- set resp.http.x-foo = std.real2time(1140618699.00);
+ set resp.http.x-foo = std.real2time(1140618699.00, now);
}
} -start
diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc
index 0ad385f..b082da3 100644
--- a/lib/libvmod_std/vmod.vcc
+++ b/lib/libvmod_std/vmod.vcc
@@ -128,7 +128,7 @@ Example
$Function INT integer(STRING s, INT fallback)
Description
- Converts the string *s* to an integer. If conversion fails,
+ Converts the string *s* to an integer. If conversion fails,
*fallback* will be returned.
Example
| if (std.integer(req.http.foo, 0) > 5) {
@@ -139,7 +139,7 @@ $Function IP ip(STRING s, IP fallback)
Description
Converts the string *s* to the first IP number returned by
- the system library function getaddrinfo(3). If conversion
+ the system library function getaddrinfo(3). If conversion
fails, *fallback* will be returned.
Example
| if (std.ip(req.http.X-forwarded-for, "0.0.0.0") ~ my_acl) {
@@ -149,33 +149,44 @@ Example
$Function REAL real(STRING s, REAL fallback)
Description
- Converts the string *s* to a real. If conversion fails,
+ Converts the string *s* to a real. If conversion fails,
*fallback* will be returned.
Example
| if (std.real(req.http.foo, 0.0) > 5.5) {
| ...
| }
-$Function TIME real2time(REAL r)
+$Function INT real2integer(REAL r, INT fallback)
Description
- Converts the real *r* to a time.
+ Converts the real *r* to an integer. If conversion fails,
+ *fallback* will be returned.
+Example
+ set req.http.integer = std.real2integer(1140618699.00, 0);
+
+$Function TIME real2time(REAL r, TIME fallback)
+
+Description
+ Converts the real *r* to a time. If conversion fails,
+ *fallback* will be returned.
Example
- set req.http.time = std.real2time(1140618699.00);
+ set req.http.time = std.real2time(1140618699.00, now);
-$Function INT time2integer(TIME t)
+$Function INT time2integer(TIME t, INT fallback)
Description
- Converts the time *t* to a integer.
+ Converts the time *t* to a integer. If conversion fails,
+ *fallback* will be returned.
Example
- set req.http.int = std.time2integer(now);
+ set req.http.int = std.time2integer(now, 0);
-$Function REAL time2real(TIME t)
+$Function REAL time2real(TIME t, REAL fallback)
Description
- Converts the time *t* to a real.
+ Converts the time *t* to a real. If conversion fails,
+ *fallback* will be returned.
Example
- set req.http.real = std.time2real(now);
+ set req.http.real = std.time2real(now, 1.0);
$Function BOOL healthy(BACKEND be)
@@ -241,7 +252,7 @@ Example
$Function TIME time(STRING s, TIME fallback)
Description
- Converts the string *s* to a time. If conversion fails,
+ Converts the string *s* to a time. If conversion fails,
*fallback* will be returned.
Supported formats:
diff --git a/lib/libvmod_std/vmod_std_conversions.c b/lib/libvmod_std/vmod_std_conversions.c
index 95bb003..131c3c1 100644
--- a/lib/libvmod_std/vmod_std_conversions.c
+++ b/lib/libvmod_std/vmod_std_conversions.c
@@ -187,27 +187,51 @@ vmod_real(VRT_CTX, VCL_STRING p, VCL_REAL d)
return (r);
}
+VCL_INT __match_proto__(td_std_real2integer)
+vmod_real2integer(VRT_CTX, VCL_REAL r, VCL_INT i)
+{
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+
+ if (!isfinite(r))
+ return (i);
+ r = round(r);
+ if (r > LONG_MAX || r < LONG_MIN)
+ return(i);
+ return ((long)r);
+}
+
VCL_TIME __match_proto__(td_std_real2time)
-vmod_real2time(VRT_CTX, VCL_REAL r)
+vmod_real2time(VRT_CTX, VCL_REAL r, VCL_TIME t)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ if (!isfinite(r))
+ return (t);
+
return (r);
}
VCL_INT __match_proto__(td_std_time2integer)
-vmod_time2integer(VRT_CTX, VCL_TIME t)
+vmod_time2integer(VRT_CTX, VCL_TIME t, VCL_INT i)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
- return ((long)floor(t));
+ if (!isfinite(t))
+ return (i);
+ t = round(t);
+ if (t > LONG_MAX || t < LONG_MIN)
+ return(i);
+ return ((long)t);
}
VCL_REAL __match_proto__(td_std_time2real)
-vmod_time2real(VRT_CTX, VCL_TIME t)
+vmod_time2real(VRT_CTX, VCL_TIME t, VCL_REAL r)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ if (!isfinite(t))
+ return (r);
+
return (t);
}
More information about the varnish-commit
mailing list