This sample fetch returns a concatenation of the client's IP address
and the HTTP status code returned, separated by a single comma character.

Signed-off-by: Nenad Merdanovic <nmer...@anine.io>
---
 doc/configuration.txt |  6 ++++++
 src/proto_http.c      | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index b5e67fe..b8c8295 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -14180,6 +14180,12 @@ set-cookie([<name>]) : string (deprecated)
   This fetch function is deprecated and has been superseded by the "res.cook"
   fetch. This keyword will disappear soon.
 
+src_status : string
+  Returns a string containing the concatenation of the client's IP address and
+  the HTTP status code returned, separated by a single comma character. It is
+  mostly used to track the number of HTTP response codes returned per IP 
address
+  and acting based on that number.
+
 status : integer
   Returns an integer containing the HTTP status code in the HTTP response, for
   example, 302. It is mostly used within ACLs and integer ranges, for example,
diff --git a/src/proto_http.c b/src/proto_http.c
index 50e3d48..13c75ac 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -10146,6 +10146,44 @@ smp_fetch_stcode(const struct arg *args, struct sample 
*smp, const char *kw, voi
 }
 
 static int
+smp_fetch_src_status(const struct arg *args, struct sample *smp, const char 
*kw, void *private)
+{
+       struct chunk *temp;
+       struct connection *cli_conn = objt_conn(smp->sess->origin);
+       struct http_txn *txn;
+       char *ptr;
+       int statlen, len;
+
+       if (!cli_conn)
+               return 0;
+
+       CHECK_HTTP_MESSAGE_FIRST();
+
+       txn = smp->strm->txn;
+       if (txn->rsp.msg_state < HTTP_MSG_BODY)
+               return 0;
+
+       statlen = txn->rsp.sl.st.c_l;
+       ptr = txn->rsp.chn->buf->p + txn->rsp.sl.st.c;
+
+       temp = get_trash_chunk();
+
+       if (addr_to_str((struct sockaddr_storage *)&cli_conn->addr.from, 
temp->str, temp->size) <= 0)
+               return 0;
+
+       len = strlen(temp->str);
+       temp->str[len++] = ',';
+       memcpy(temp->str + len, ptr, statlen);
+       len += statlen;
+       temp->str[len++] = '\0';
+
+       smp->data.u.str = *temp;
+       smp->data.u.str.len = len;
+       smp->data.type = SMP_T_STR;
+       return 1;
+}
+
+static int
 smp_fetch_uniqueid(const struct arg *args, struct sample *smp, const char *kw, 
void *private)
 {
        if (LIST_ISEMPTY(&smp->sess->fe->format_unique_id))
@@ -12894,6 +12932,7 @@ static struct sample_fetch_kw_list 
sample_fetch_keywords = {ILH, {
        { "shdr_ip",         smp_fetch_hdr_ip,         ARG2(0,STR,SINT), 
val_hdr, SMP_T_IPV4, SMP_USE_HRSHV },
        { "shdr_val",        smp_fetch_hdr_val,        ARG2(0,STR,SINT), 
val_hdr, SMP_T_SINT, SMP_USE_HRSHV },
 
+       { "src_status",      smp_fetch_src_status,     0,                NULL,  
  SMP_T_STR,  SMP_USE_HRSHP },
        { "status",          smp_fetch_stcode,         0,                NULL,  
  SMP_T_SINT, SMP_USE_HRSHP },
        { "unique-id",       smp_fetch_uniqueid,       0,                NULL,  
  SMP_T_STR,  SMP_SRC_L4SRV },
        { "url",             smp_fetch_url,            0,                NULL,  
  SMP_T_STR,  SMP_USE_HRQHV },
-- 
2.8.1


Reply via email to