MINOR: samples: add the http_date([<offset>]) sample converter.

Converts an integer supposed to contain a date since epoch to
a string representing this date in a format suitable for use
in HTTP header fields. If an offset value is specified, then
it is a number of seconds that is added to the date before the
conversion is operated. This is particularly useful to emit
Date header fields, Expires values in responses when combined
with a positive offset, or Last-Modified values when the
offset is negative.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 58e4fa5..2c8fadf 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -8720,6 +8720,15 @@
                  the same server. The mask can be passed in dotted form (eg:
                  255.255.255.0) or in CIDR form (eg: 24).
 
+  http_date([<offset>])
+                 Converts an integer supposed to contain a date since epoch to
+                 a string representing this date in a format suitable for use
+                 in HTTP header fields. If an offset value is specified, then
+                 it is a number of seconds that is added to the date before the
+                 conversion is operated. This is particularly useful to emit
+                 Date header fields, Expires values in responses when combined
+                 with a positive offset, or Last-Modified values when the
+                 offset is negative.
 
 7.3.1. Fetching samples from internal states
 --------------------------------------------
@@ -8806,6 +8815,12 @@
   If an offset value is specified, then it is a number of seconds that is added
   to the current date before returning the value. This is particularly useful
   to compute relative dates, as both positive and negative offsets are allowed.
+  It is useful combined with the http_date converter.
+
+  Example :
+
+     # set an expires header to now+1 hour in every response
+     http-response set-header Expires %[date(3600),http_date]
 
 env(<name>) : string
   Returns a string containing the value of environment variable <name>. As a
diff --git a/src/proto_http.c b/src/proto_http.c
index 7e38b68..ebb7556 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -10117,6 +10117,35 @@
 	return 1;
 }
 
+/* takes an UINT value on input supposed to represent the time since EPOCH,
+ * adds an optional offset found in args[0] and emits a string representing
+ * the date in RFC-1123/5322 format.
+ */
+static int sample_conv_http_date(const struct arg *args, struct sample *smp)
+{
+	const char day[7][4] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+	const char mon[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+	struct chunk *temp;
+	struct tm *tm;
+	time_t curr_date = smp->data.uint;
+
+	/* add offset */
+	if (args && (args[0].type == ARGT_SINT || args[0].type == ARGT_UINT))
+		curr_date += args[0].data.sint;
+
+	tm = gmtime(&curr_date);
+
+	temp = get_trash_chunk();
+	temp->len = snprintf(temp->str, temp->size - temp->len,
+			     "%s, %02d %s %04d %02d:%02d:%02d GMT",
+			     day[tm->tm_wday], tm->tm_mday, mon[tm->tm_mon], 1900+tm->tm_year,
+			     tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	smp->data.str = *temp;
+	smp->type = SMP_T_STR;
+	return 1;
+}
+
 /************************************************************************/
 /*          All supported ACL keywords must be declared here.           */
 /************************************************************************/
@@ -10299,11 +10328,18 @@
 }};
 
 
+/* Note: must not be declared <const> as its list will be overwritten */
+static struct sample_conv_kw_list sample_conv_kws = {ILH, {
+	{ "http_date", sample_conv_http_date, ARG1(0,SINT), NULL, SMP_T_UINT, SMP_T_STR  },
+	{ NULL, NULL, 0, 0, 0 },
+}};
+
 __attribute__((constructor))
 static void __http_protocol_init(void)
 {
 	acl_register_keywords(&acl_kws);
 	sample_register_fetches(&sample_fetch_keywords);
+	sample_register_convs(&sample_conv_kws);
 }