]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: sample: date converter takes HTTP date and output an UNIX timestamp
authorWilliam Lallemand <wlallemand@haproxy.com>
Fri, 14 Jun 2024 07:38:14 +0000 (09:38 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 20 Jun 2024 14:38:48 +0000 (16:38 +0200)
The `date` converter takes an HTTP date in input, it could be either a
imf, rfc850 or asctime date. It will output an UNIX timestamp.

doc/configuration.txt
src/http_conv.c

index 9d701e0b51f10a08b75cc9e11a22b787b065355a..23218e5442303701597e2a18bea05afd13b52a02 100644 (file)
@@ -19126,6 +19126,7 @@ crc32([avalanche])                                 binary       integer
 crc32c([avalanche])                                binary       integer
 cut_crlf                                           string       string
 da-csv-conv(prop[,prop*])                          string       string
+date                                               string       integer
 debug([prefix][,destination])                       any          same
 -- keyword -------------------------------------+- input type + output type -
 digest(algorithm)                                  binary       binary
@@ -19486,6 +19487,13 @@ da-csv-conv(<prop>[,<prop>*])
       default_backend servers
       http-request set-header X-DeviceAtlas-Data %[req.fhdr(User-Agent),da-csv(primaryHardwareType,osName,osVersion,browserName,browserVersion,browserRenderingEngine)]
 
+date
+  This converter is used to convert a date from an HTTP header. It can be an IMF
+  date, an ASCTIME date or a RFC850 date. It will output an UNIX timestamp.
+
+  Example:
+     http-request return lf-string "%[str('Sun, 06 Nov 1994 08:49:37 GMT'),date]\n" content-type text/plain
+
 debug([<prefix][,<destination>])
   This converter is used as debug tool. It takes a capture of the input sample
   and sends it to event sink <destination>, which may designate a ring buffer
index cf515a877d765e440985b716aabcba9be57076ac..c2a3e281eb347e345a9d9c7f47579f74367c1708 100644 (file)
@@ -33,6 +33,23 @@ static int smp_check_http_date_unit(struct arg *args, struct sample_conv *conv,
     return smp_check_date_unit(args, err);
 }
 
+/* Take a string containing an HTTP date in IMF, RFC850 or ASCTIME
+ * and converts it into a integer epoch format
+ */
+static int sample_conv_http2epoch(const struct arg *args, struct sample *smp, void *private)
+{
+       int res = 0;
+       struct tm tm = {};
+
+       smp->data.type = SMP_T_SINT;
+       res = parse_http_date(smp->data.u.str.area, smp->data.u.str.data, &tm);
+       smp->data.u.sint = my_timegm(&tm);
+
+       return res;
+}
+
+
+
 /* 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. If optional unit param in args[1] is
@@ -435,6 +452,7 @@ static int smp_conv_res_capture(const struct arg *args, struct sample *smp, void
 /* 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,    ARG2(0,SINT,STR),     smp_check_http_date_unit,   SMP_T_SINT, SMP_T_STR},
+       { "date",           sample_conv_http2epoch,   0,             NULL,   SMP_T_STR,  SMP_T_SINT},
        { "language",       sample_conv_q_preferred,  ARG2(1,STR,STR),  NULL,   SMP_T_STR,  SMP_T_STR},
        { "capture-req",    smp_conv_req_capture,     ARG1(1,SINT),     NULL,   SMP_T_STR,  SMP_T_STR},
        { "capture-res",    smp_conv_res_capture,     ARG1(1,SINT),     NULL,   SMP_T_STR,  SMP_T_STR},