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.
This commit is contained in:
Willy Tarreau 2013-07-25 14:36:01 +02:00
parent 6236d3abe4
commit 276fae9ab9
2 changed files with 51 additions and 0 deletions

View file

@ -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([<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 @@ date([<offset>]) : 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(<name>) : string
Returns a string containing the value of environment variable <name>. As a

View file

@ -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 <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);
}