[PATCH] Implement std.rfcdate

Federico G. Schwindt fgsch at lodoss.net
Thu Oct 11 04:59:12 CEST 2012


Hi,

The diff below does:

1. Implements std.rfcdate(), documentation and (brief) test included
2. Correctly treats TIME + DURATION as a TIME as per https://www.varnish-cache.org/docs/trunk/phk/vcl_expr.html
3. Changes now to return a TIME - the old form is available via std.rfcdate(now)

In particular my main motivation behind #3 is something scn mentioned on IRC:

> I had a 15min digression with (now + 0s) and all sorts of tricks to find unixtime in vcl a few weeks back

which I believe it's a bit inconsistent.

The current behaviour:

- `now' by itself will return a date in rfc 1123 format
- `now + duration' will return a time
- there is no way to convert a time other than now to a rfc 1123 format if it's not via inline C

With this diff:

- `now' and `now + duration' returns a time
- `std.rfcdate(now)' and `std.rfcdate(now + duration)' returns the date in rfc 1123 format.

Other possibilities could be:

- Return a date for `now' and `now + duration' and add a way to convert both cases to a time
- Return a date for `now' and `now + duration' and add a new variable to replace now that returns a time

Comments?

f.-

 bin/varnishtest/tests/m00009.vtc       |   20 ++++++++++++++++++++
 doc/sphinx/reference/vmod_std.rst      |   12 ++++++++++++
 lib/libvcl/vcc_expr.c                  |    6 ++++--
 lib/libvmod_std/vmod.vcc               |    1 +
 lib/libvmod_std/vmod_std_conversions.c |    6 ++++++
 5 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/bin/varnishtest/tests/m00009.vtc b/bin/varnishtest/tests/m00009.vtc
new file mode 100644
index 0000000..d0b12d0
--- /dev/null
+++ b/bin/varnishtest/tests/m00009.vtc
@@ -0,0 +1,20 @@
+varnishtest "test vmod_std.rfcdate conversion"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	import std from "${topbuild}/lib/libvmod_std/.libs/libvmod_std.so" ;
+	sub vcl_deliver {
+		set resp.http.now = std.rfcdate(now);
+		set resp.http.future = std.rfcdate(now + 30m);
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 200
+} -run
diff --git a/doc/sphinx/reference/vmod_std.rst b/doc/sphinx/reference/vmod_std.rst
index 984331e..814446d 100644
--- a/doc/sphinx/reference/vmod_std.rst
+++ b/doc/sphinx/reference/vmod_std.rst
@@ -138,6 +138,18 @@ Description
 Example
 	if (std.integer(beresp.http.x-foo, 0) > 5) { ... }
 
+rfcdate
+--------
+Prototype
+	rfcdate(TIME t)
+Return value
+	String
+Description
+	Converts the TIME *t* to a string representing the date in
+	RFC 1123 format.
+Example
+	set resp.http.Expire = std.rfcdate(now + 30m);
+
 collect
 -------
 Prototype
diff --git a/lib/libvcl/vcc_expr.c b/lib/libvcl/vcc_expr.c
index 72c26a9..2d9ebae 100644
--- a/lib/libvcl/vcc_expr.c
+++ b/lib/libvcl/vcc_expr.c
@@ -431,7 +431,7 @@ vcc_expr_tostring(struct expr **e, enum var_type fmt)
 	case IP:	p = "VRT_IP_string(req, \v1)"; break;
 	case BYTES:	p = "VRT_REAL_string(req, \v1)"; break; /* XXX */
 	case REAL:	p = "VRT_REAL_string(req, \v1)"; break;
-	case TIME:	p = "VRT_TIME_string(req, \v1)"; break;
+	case TIME:	p = "VRT_REAL_string(req, \v1)"; break;
 	default:	break;
 	}
 	if (p != NULL) {
@@ -856,7 +856,9 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
 			vcc_ErrWhere2(tl, tk, tl->t);
 			return;
 		}
-		if (tk->tok == '+')
+		if (tk->tok == '+' && (*e)->fmt == TIME)
+			*e = vcc_expr_edit(TIME, "(\v1+\v2)", *e, e2);
+		else if (tk->tok == '+')
 			*e = vcc_expr_edit(f2, "(\v1+\v2)", *e, e2);
 		else if (f2 == TIME && e2->fmt == TIME)
 			*e = vcc_expr_edit(DURATION, "(\v1-\v2)", *e, e2);
diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc
index 3238164..c2a018a 100644
--- a/lib/libvmod_std/vmod.vcc
+++ b/lib/libvmod_std/vmod.vcc
@@ -36,3 +36,4 @@ Function STRING fileread(PRIV_CALL, STRING)
 Function DURATION duration(STRING, DURATION)
 Function INT integer(STRING, INT)
 Function VOID collect(HEADER)
+Function STRING rfcdate(TIME)
diff --git a/lib/libvmod_std/vmod_std_conversions.c b/lib/libvmod_std/vmod_std_conversions.c
index e728611..956f80e 100644
--- a/lib/libvmod_std/vmod_std_conversions.c
+++ b/lib/libvmod_std/vmod_std_conversions.c
@@ -117,3 +117,9 @@ vmod_integer(struct req *req, const char *p, long i)
 
 	return (r);
 }
+
+const char * __match_proto__(td_std_rfcdate)
+vmod_rfcdate(struct req *req, double t)
+{
+	return (VRT_TIME_string(req, t));
+}



More information about the varnish-dev mailing list