From: Willy Tarreau Date: Thu, 25 Jul 2013 12:36:01 +0000 (+0200) Subject: MINOR: samples: add the http_date([]) sample converter. X-Git-Tag: v1.5-dev20~325 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=276fae9ab95a9addf6b867c78903d31ab4da8d3a;p=thirdparty%2Fhaproxy.git MINOR: samples: add the http_date([]) 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 58e4fa5711..2c8fadf40a 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -8720,6 +8720,15 @@ The currently available list of transformation keywords include : the same server. The mask can be passed in dotted form (eg: 255.255.255.0) or in CIDR form (eg: 24). + 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. 7.3.1. Fetching samples from internal states -------------------------------------------- @@ -8806,6 +8815,12 @@ date([]) : integer 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() : string Returns a string containing the value of environment variable . As a diff --git a/src/proto_http.c b/src/proto_http.c index 7e38b68e6b..ebb7556a98 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -10117,6 +10117,35 @@ static int val_hdr(struct arg *arg, char **err_msg) 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 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, { }}; +/* Note: must not be declared 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); }