[master] f970f1756 Add std.strftime()

Nils Goroll nils.goroll at uplex.de
Tue Oct 26 13:38:06 UTC 2021


commit f970f175654b4471285b8dcb02e326835a3c7730
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Fri May 21 18:44:01 2021 +0200

    Add std.strftime()
    
    add a vmod function for strftime() formatting in UTC.

diff --git a/vmod/tests/std_b00011.vtc b/vmod/tests/std_b00011.vtc
index fd61e11fb..bd0735237 100644
--- a/vmod/tests/std_b00011.vtc
+++ b/vmod/tests/std_b00011.vtc
@@ -1,4 +1,4 @@
-varnishtest "Test std.time"
+varnishtest "Test std.time() and std.strftime()"
 
 server s1 {
 	rxreq
@@ -7,10 +7,17 @@ server s1 {
 
 varnish v1 -vcl+backend {
 	import std;
+	import vtc;
 
 	sub vcl_deliver {
 		set resp.http.x-date = std.time(
 		    regsub(req.http.x-date, "z", " "), now);
+		if (req.http.over) {
+			vtc.workspace_alloc(client, -1);
+		}
+		set resp.http.utc = std.strftime(
+		    std.time(req.http.x-date, now),
+		    "%Y%m%dT%H%M%SZ");
 		if (std.time(req.http.x-date, now) < now - 1y) {
 			set resp.http.x-past = 1;
 		}
@@ -40,6 +47,7 @@ client c1 {
 	expect resp.status == 200
 	expect resp.http.x-past == 1
 	expect resp.http.x-date == "Mon, 20 Dec 2010 00:00:00 GMT"
+	expect resp.http.utc == "20101220T000000Z"
 
 	# invalid date
 	txreq -hdr "X-Date: Monday, 20-Dec-30 00:00:00 GMT" \
@@ -63,12 +71,14 @@ client c1 {
 	expect resp.status == 200
 	expect resp.http.x-future == 1
 	expect resp.http.x-date == "Fri, 20 Dec 2030 00:00:00 GMT"
+	expect resp.http.utc == "20301220T000000Z"
 
 	txreq -hdr "X-Date: Mon Dec 20 00:00:00 2010"
 	rxresp
 	expect resp.status == 200
 	expect resp.http.x-past == 1
 	expect resp.http.x-date == "Mon, 20 Dec 2010 00:00:00 GMT"
+	expect resp.http.utc == "20101220T000000Z"
 
 	txreq -hdr "X-Date: 2030-12-20T00:00:00"
 	rxresp
@@ -76,11 +86,12 @@ client c1 {
 	expect resp.http.x-future == 1
 	expect resp.http.x-date == "Fri, 20 Dec 2030 00:00:00 GMT"
 
-	txreq -hdr "X-Date: 1292803200.00"
+	txreq -hdr "X-Date: 1055455200.00"
 	rxresp
 	expect resp.status == 200
 	expect resp.http.x-past == 1
-	expect resp.http.x-date == "Mon, 20 Dec 2010 00:00:00 GMT"
+	expect resp.http.x-date == "Thu, 12 Jun 2003 22:00:00 GMT"
+	expect resp.http.utc == "20030612T220000Z"
 
 	txreq -hdr "X-Date: 1923955200"
 	rxresp
@@ -88,6 +99,13 @@ client c1 {
 	expect resp.http.x-future == 1
 	expect resp.http.x-date == "Fri, 20 Dec 2030 00:00:00 GMT"
 
+	# overflow
+	txreq -hdr "X-Date: 1923955200" -hdr "Over: 1"
+	rxresp
+	expect resp.status == 500
+} -run
+
+client c1 {
 	delay .2
 
 	# Coverage tests of vtim.c
diff --git a/vmod/vmod_std.vcc b/vmod/vmod_std.vcc
index 733d41306..c01b29cc2 100644
--- a/vmod/vmod_std.vcc
+++ b/vmod/vmod_std.vcc
@@ -435,6 +435,20 @@ Examples::
 		...
 	}
 
+$Function STRING strftime(TIME time, STRING format)
+
+Format the *time* argument with the *format* argument using
+`strftime(3)` and return the result for the UTC (historically GMT)
+timezone.
+
+The empty string is returned if formatting fails, but may also be
+returned as a valid result.
+
+Example::
+
+	set req.http.iso = std.strftime(now, "%Y%m%dT%H%M%SZ");
+	# e.g. 20210521T175241Z
+
 LOGGING functions
 =================
 
@@ -719,3 +733,4 @@ SEE ALSO
 * :ref:`varnishd(1)`
 * :ref:`vsl(7)`
 * `fnmatch(3)`
+* `strftime(3)`
diff --git a/vmod/vmod_std_conversions.c b/vmod/vmod_std_conversions.c
index 662aec4b5..275e65622 100644
--- a/vmod/vmod_std_conversions.c
+++ b/vmod/vmod_std_conversions.c
@@ -326,6 +326,33 @@ vmod_time(VRT_CTX, struct VARGS(time)* a)
 	return (0);
 }
 
+VCL_STRING v_matchproto_(td_std_strftime)
+vmod_strftime(VRT_CTX, VCL_TIME t, VCL_STRING fmt)
+{
+	struct tm tm;
+	time_t tt;
+	size_t r;
+	unsigned spc;
+	char *s;
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+
+	tt = (time_t)(intmax_t)t;
+	if (gmtime_r(&tt, &tm) == NULL)
+		return ("");
+
+	spc = WS_ReserveAll(ctx->ws);
+	s = WS_Reservation(ctx->ws);
+	r = strftime(s, spc, fmt, &tm);
+	if (r == 0) {
+		WS_Release(ctx->ws, 0);
+		return ("");
+	}
+	r++;
+	WS_Release(ctx->ws, r);
+	return (s);
+}
+
 /* These functions are deprecated as of 2019-03-15 release */
 
 VCL_INT v_matchproto_(td_std_real2integer)


More information about the varnish-commit mailing list