MINOR: http: add the new sample fetches req.hdr_names and res.hdr_names

These new sample fetches retrieve the list of header names as they appear
in the request or response. This can be used for debugging, for statistics
as well as an aid to better detect the presence of proxies or plugins on
some browsers, which alter the request compared to a regular browser by
adding or reordering headers.
This commit is contained in:
Willy Tarreau 2015-02-20 13:55:29 +01:00
parent c90dc23e99
commit eb27ec7569
2 changed files with 47 additions and 0 deletions

View File

@ -12218,6 +12218,12 @@ query : string
using the "found" matching method. This fetch is the completemnt of "path"
which stops before the question mark.
req.hdr_names([<delim>]) : string
This builds a string made from the concatenation of all header names as they
appear in the request when the rule is evaluated. The default delimiter is
the comma (',') but it may be overridden as an optional argument <delim>. In
this case, only the first character of <delim> is considered.
req.ver : string
req_ver : string (deprecated)
Returns the version string from the HTTP request, for example "1.1". This can
@ -12314,6 +12320,12 @@ shdr_ip([<name>[,<occ>]]) : ip (deprecated)
Negative values indicate positions relative to the last one, with -1 being
the last one. This can be useful to learn some data into a stick table.
res.hdr_names([<delim>]) : string
This builds a string made from the concatenation of all header names as they
appear in the response when the rule is evaluated. The default delimiter is
the comma (',') but it may be overridden as an optional argument <delim>. In
this case, only the first character of <delim> is considered.
res.hdr_val([<name>[,<occ>]]) : integer
shdr_val([<name>[,<occ>]]) : integer (deprecated)
This extracts the last occurrence of header <name> in an HTTP response, and

View File

@ -10232,6 +10232,39 @@ smp_fetch_fhdr_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int
return 1;
}
static int
smp_fetch_hdr_names(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp, const char *kw)
{
struct http_txn *txn = l7;
struct hdr_idx *idx = &txn->hdr_idx;
struct hdr_ctx ctx;
const struct http_msg *msg = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) ? &txn->req : &txn->rsp;
struct chunk *temp;
char del = ',';
if (args && args->type == ARGT_STR)
del = *args[0].data.str.str;
CHECK_HTTP_MESSAGE_FIRST();
temp = get_trash_chunk();
ctx.idx = 0;
while (http_find_next_header(msg->chn->buf->p, idx, &ctx)) {
if (temp->len)
temp->str[temp->len++] = del;
memcpy(temp->str + temp->len, ctx.line, ctx.del);
temp->len += ctx.del;
}
smp->type = SMP_T_STR;
smp->data.str.str = temp->str;
smp->data.str.len = temp->len;
smp->flags = SMP_F_VOL_HDR;
return 1;
}
/* Fetch an HTTP header. A pointer to the beginning of the value is returned.
* Accepts an optional argument of type string containing the header field name,
* and an optional argument of type signed or unsigned integer to request an
@ -11884,6 +11917,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
{ "req.hdr", smp_fetch_hdr, ARG2(0,STR,SINT), val_hdr, SMP_T_STR, SMP_USE_HRQHV },
{ "req.hdr_cnt", smp_fetch_hdr_cnt, ARG1(0,STR), NULL, SMP_T_UINT, SMP_USE_HRQHV },
{ "req.hdr_ip", smp_fetch_hdr_ip, ARG2(0,STR,SINT), val_hdr, SMP_T_IPV4, SMP_USE_HRQHV },
{ "req.hdr_names", smp_fetch_hdr_names, ARG1(0,STR), NULL, SMP_T_STR, SMP_USE_HRQHV },
{ "req.hdr_val", smp_fetch_hdr_val, ARG2(0,STR,SINT), val_hdr, SMP_T_UINT, SMP_USE_HRQHV },
/* explicit req.{cook,hdr} are used to force the fetch direction to be response-only */
@ -11896,6 +11930,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
{ "res.hdr", smp_fetch_hdr, ARG2(0,STR,SINT), val_hdr, SMP_T_STR, SMP_USE_HRSHV },
{ "res.hdr_cnt", smp_fetch_hdr_cnt, ARG1(0,STR), NULL, SMP_T_UINT, SMP_USE_HRSHV },
{ "res.hdr_ip", smp_fetch_hdr_ip, ARG2(0,STR,SINT), val_hdr, SMP_T_IPV4, SMP_USE_HRSHV },
{ "res.hdr_names", smp_fetch_hdr_names, ARG1(0,STR), NULL, SMP_T_STR, SMP_USE_HRSHV },
{ "res.hdr_val", smp_fetch_hdr_val, ARG2(0,STR,SINT), val_hdr, SMP_T_UINT, SMP_USE_HRSHV },
/* scook is valid only on the response and is used for ACL compatibility */