MINOR: checks: Add a sample fetch to extract a block from the input check buffer

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).
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 2c4e24c..b253ca9 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -87,7 +87,8 @@
 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 @@
   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
diff --git a/src/checks.c b/src/checks.c
index a603728..3606aa0 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -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_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),
 };