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