Re: [PATCH V4] MINOR: sample: add us/ms support to date/http_date

2019-10-31 Thread Willy Tarreau
On Wed, Oct 30, 2019 at 03:57:28PM +, Damien Claisse wrote:
> It can be sometimes interesting to have a timestamp with a
> resolution of less than a second.
> It is currently painful to obtain this, because concatenation
> of date and date_us lead to a shorter timestamp during first
> 100ms of a second, which is not parseable and needs ugly ACLs
> in configuration to prepend 0s when needed.
> To improve this, add an optional  parameter to date sample
> to report an integer with desired unit.
> Also support this unit in http_date converter to report
> a date string with sub-second precision.
(...)

Looks good, now merged. Thank you Damien!

Willy



[PATCH V4] MINOR: sample: add us/ms support to date/http_date

2019-10-30 Thread Damien Claisse
It can be sometimes interesting to have a timestamp with a
resolution of less than a second.
It is currently painful to obtain this, because concatenation
of date and date_us lead to a shorter timestamp during first
100ms of a second, which is not parseable and needs ugly ACLs
in configuration to prepend 0s when needed.
To improve this, add an optional  parameter to date sample
to report an integer with desired unit.
Also support this unit in http_date converter to report
a date string with sub-second precision.
---
 Changed in V2: add a verification function to check date unit argument

 Changed in V3:
 - fix a comment typo (s/milli/micro/)
 - Talk about "seconds" unit in doc

 Changed in V4:
 - offset is now considered to have the same unit than optional
   unit param.
 - set args[1].data.str.area to NULL after freeing it.
 - also support unit in http_date converter.
 - improve documentation

 doc/configuration.txt  | 33 +++
 include/proto/sample.h |  1 +
 src/http_conv.c| 49 +++
 src/sample.c   | 52 +++---
 4 files changed, 113 insertions(+), 22 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 77f95572..1c49dde3 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -13233,13 +13233,17 @@ hex2i
   Converts a hex string containing two hex digits per input byte to an
   integer. If the input value cannot be converted, then zero is returned.
 
-http_date([])
+http_date([])
   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.
+  an offset value is specified, then it 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.
+  If a unit value is specified, then consider the timestamp as either
+  "s" for seconds (default behavior), "ms" for milliseconds, or "us" for
+  microseconds since epoch. Offset is assumed to have the same unit as
+  input timestamp.
 
 in_table()
   Uses the string representation of the input sample to perform a look up in
@@ -14050,18 +14054,29 @@ cpu_ns_tot : integer
   high cpu_calls count, for example when processing many HTTP chunks, and for
   this reason it is often preferred to log cpu_ns_avg instead.
 
-date([]) : integer
+date([, ]) : integer
   Returns the current date as the epoch (number of seconds since 01/01/1970).
-  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.
+
+  If an offset value is specified, then it 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.
 
+   is facultative, and can be set to "s" for seconds (default behavior),
+  "ms" for  milliseconds or "us" for microseconds.
+  If unit is set, return value is an integer reflecting either seconds,
+  milliseconds or microseconds since epoch, plus offset.
+  It is useful when a time resolution of less than a second is needed.
+
   Example :
 
  # set an expires header to now+1 hour in every response
  http-response set-header Expires %[date(3600),http_date]
 
+ # set an expires header to now+1 hour in every response, with
+ # millisecond granularity
+ http-response set-header Expires %[date(360,ms),http_date(0,ms)]
+
 date_us : integer
   Return the microseconds part of the date (the "second" part is returned by
   date sample). This sample is coherent with the date sample as it is comes
diff --git a/include/proto/sample.h b/include/proto/sample.h
index 606dcb62..f0be3fd2 100644
--- a/include/proto/sample.h
+++ b/include/proto/sample.h
@@ -45,6 +45,7 @@ struct sample_fetch *find_sample_fetch(const char *kw, int 
len);
 struct sample_fetch *sample_fetch_getnext(struct sample_fetch *current, int 
*idx);
 struct sample_conv *sample_conv_getnext(struct sample_conv *current, int *idx);
 int smp_resolve_args(struct proxy *p);
+int smp_check_date_unit(struct arg *args, char **err);
 int smp_expr_output_type(struct sample_expr *expr);
 int c_none(struct sample *smp);
 int smp_dup(struct sample *smp);
diff --git a/src/http_conv.c b/src/http_conv.c
index 93b748c2..cd93aa96 100644
--- a/src/http_conv.c
+++ b/s