]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: checks: Add a sample fetch to extract a block from the input check buffer
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 1 Apr 2020 14:27:05 +0000 (16:27 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 27 Apr 2020 07:39:37 +0000 (09:39 +0200)
It is now possible to extract information from the check input buffer using the
check.payload sample fetch. As req.payload or res.payload, an offset and a
length must be specified.

A new section has been added in the configuration manual. Now check sample
fetches will have to be documented under the section 7.3.7 (Fetching
health-check samples).

doc/configuration.txt
src/checks.c

index 2c4e24ccadda2b78563b3db91937687cea720670..b253ca92f6579f83288354a895c9acf02cee8d49 100644 (file)
@@ -87,7 +87,8 @@ Summary
 7.3.4.        Fetching samples at Layer 5
 7.3.5.        Fetching samples from buffer contents (Layer 6)
 7.3.6.        Fetching HTTP samples (Layer 7)
-7.3.7.        Fetching samples for developers
+7.3.7.        Fetching health-check samples
+7.3.8.        Fetching samples for developers
 7.4.      Pre-defined ACLs
 
 8.    Logging
@@ -17164,7 +17165,25 @@ url32+src : binary
   the source address family. This can be used to track per-IP, per-URL counters.
 
 
-7.3.7. Fetching samples for developers
+7.3.7. Fetching health-check samples
+-------------------------------------
+
+This set of sample fetch methods may be called from an health-check execution
+context. It was introduced in the version 2.2. The following sample fetches are
+placed in the dedicated scope "check". Other sample fetches may also be called
+when an health-check is performed if it makes sense and if the sample fetch was
+adapted to be called in this context.
+
+check.payload(<offset>,<length>) : binary
+  This extracts a binary block of <length> bytes and starting at byte <offset>
+  in the check input buffer. As a special case, if the <length> argument is
+  zero, then the whole buffer from <offset> to the end is extracted. This can
+  be called from a tcp-check expect rule, or eventually from a set-var rule
+  after an expect rule and before a send rule (check input buffer is filled on
+  tcp-check expect rules and reset on tcp-check send rules).
+
+
+7.3.8. Fetching samples for developers
 ---------------------------------------
 
 This set of sample fetch methods is reserved to developers and must never be
index a603728f5ab40f5810dff8aa32eacfec14774723..3606aa083e2754cbfa3f2e10ca15b61b66d7bc83 100644 (file)
@@ -44,6 +44,7 @@
 #include <types/stats.h>
 
 #include <proto/action.h>
+#include <proto/arg.h>
 #include <proto/backend.h>
 #include <proto/checks.h>
 #include <proto/stats.h>
@@ -4122,6 +4123,44 @@ REGISTER_SERVER_DEINIT(deinit_srv_check);
 REGISTER_SERVER_DEINIT(deinit_srv_agent_check);
 REGISTER_POST_DEINIT(deinit_tcpchecks);
 
+/* extracts check payload at a fixed position and length */
+static int
+smp_fetch_chk_payload(const struct arg *arg_p, struct sample *smp, const char *kw, void *private)
+{
+       unsigned int buf_offset = ((arg_p[0].type == ARGT_SINT) ? arg_p[0].data.sint : 0);
+       unsigned int buf_size = ((arg_p[1].type == ARGT_SINT) ? arg_p[1].data.sint : 0);
+       struct server *srv = (smp->sess ? objt_server(smp->sess->origin) : NULL);
+       struct buffer *buf;
+
+       if (!srv || !srv->do_check)
+               return 0;
+
+       buf = &srv->check.bi;
+       if (buf_offset > b_data(buf))
+               goto no_match;
+       if (buf_offset + buf_size > b_data(buf))
+               buf_size = 0;
+
+       /* init chunk as read only */
+       smp->data.type = SMP_T_STR;
+       smp->flags = SMP_F_VOLATILE | SMP_F_CONST;
+       chunk_initlen(&smp->data.u.str, b_head(buf) + buf_offset, 0, (buf_size ? buf_size : (b_data(buf) - buf_offset)));
+
+       return 1;
+
+ no_match:
+       smp->flags = 0;
+       return 0;
+}
+
+static struct sample_fetch_kw_list smp_kws = {ILH, {
+       { "check.payload", smp_fetch_chk_payload,   ARG2(0,SINT,SINT), NULL, SMP_T_STR,  SMP_USE_INTRN },
+       { /* END */ },
+}};
+
+INITCALL1(STG_REGISTER, sample_register_fetches, &smp_kws);
+
+
 struct action_kw_list tcp_check_keywords = {
        .list = LIST_HEAD_INIT(tcp_check_keywords.list),
 };