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)); +} _______________________________________________ varnish-dev mailing list [email protected] https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
