]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http: add the new sample fetches req.hdr_names and res.hdr_names
authorWilly Tarreau <w@1wt.eu>
Fri, 20 Feb 2015 12:55:29 +0000 (13:55 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 20 Feb 2015 13:00:44 +0000 (14:00 +0100)
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.

doc/configuration.txt
src/proto_http.c

index 971c26e8ff6c58983e247ce80260e6efdd226c36..bb7d56794a1e3a8a37aa5c6426ba230ee024bc84 100644 (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
index 0a6ef9f7d7aedf833877dbb684dd230e2a2796da..4484bcf48765bbe83fa3417003371b00d8228369 100644 (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 */