BUG/MINOR: payload/htx: Ingore L6 sample fetches for HTX streams/checks

Use a L6 sample fetch on an HTX streams or a HTX health-check is meaningless
because data are not raw but structured. So now, these sample fetches fail
when called from an HTTP proxy. In addition, a warning has been added in the
configuration manual, at the begining of the L6 sample fetches section.

Note that req.len and res.len samples return the HTX data size instead of
failing. It is not accurate because it does not reflect the buffer size nor
the raw data length. But we keep it for backward compatibility purpose.
However it remains a bit strange to use it on an HTTP proxy.

This patch may be backported to all versions supporting the HTX, i.e as far
as 2.0. But the part about the health-checks is only valid for the 2.2 and
upper.
This commit is contained in:
Christopher Faulet 2021-03-25 11:58:51 +01:00
parent e1b9e1bb1e
commit a434a00864
2 changed files with 71 additions and 7 deletions

View File

@ -18404,6 +18404,14 @@ sample fetch methods to ensure that the expected data are complete and usable,
for example through TCP request content inspection. Please see the "tcp-request
content" keyword for more detailed information on the subject.
Warning : Following sample fetches are ignored if used from HTTP proxies. They
only deal with raw contents found in the buffers. On their side,
HTTTP proxies use structured content. Thus raw representation of
these data are meaningless. A warning is emitted if an ACL relies on
one of the following sample fetches. But it is not possible to detect
all invalid usage (for instance inside a log-format string or a
sample expression). So be careful.
payload(<offset>,<length>) : binary (deprecated)
This is an alias for "req.payload" when used in the context of a request (e.g.
"stick on", "stick match"), and for "res.payload" when used in the context of

View File

@ -50,6 +50,8 @@ smp_fetch_len(const struct arg *args, struct sample *smp, const char *kw, void *
{
if (smp->strm) {
struct channel *chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
/* Not accurate but kept for backward compatibility purpose */
if (IS_HTX_STRM(smp->strm)) {
struct htx *htx = htxbuf(&chn->buf);
smp->data.u.sint = htx->data - co_data(chn);
@ -59,6 +61,8 @@ smp_fetch_len(const struct arg *args, struct sample *smp, const char *kw, void *
}
else if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK) {
struct check *check = __objt_check(smp->sess->origin);
/* Not accurate but kept for backward compatibility purpose */
smp->data.u.sint = ((check->cs && IS_HTX_CS(check->cs)) ? (htxbuf(&check->bi))->data: b_data(&check->bi));
}
else
@ -84,7 +88,13 @@ smp_fetch_req_ssl_st_ext(const struct arg *args, struct sample *smp, const char
if (!smp->strm)
goto not_ssl_hello;
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
goto not_ssl_hello;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
bleft = ci_data(chn);
data = (unsigned char *)ci_head(chn);
@ -214,6 +224,10 @@ smp_fetch_req_ssl_ec_ext(const struct arg *args, struct sample *smp, const char
if (!smp->strm)
goto not_ssl_hello;
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
goto not_ssl_hello;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
bleft = ci_data(chn);
data = (unsigned char *)ci_head(chn);
@ -335,6 +349,10 @@ smp_fetch_ssl_hello_type(const struct arg *args, struct sample *smp, const char
if (!smp->strm)
goto not_ssl_hello;
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
goto not_ssl_hello;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
bleft = ci_data(chn);
data = (const unsigned char *)ci_head(chn);
@ -399,7 +417,11 @@ smp_fetch_req_ssl_ver(const struct arg *args, struct sample *smp, const char *kw
struct channel *req;
if (!smp->strm)
return 0;
goto not_ssl;
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
goto not_ssl;
req = &smp->strm->req;
msg_len = 0;
@ -541,6 +563,10 @@ smp_fetch_ssl_hello_sni(const struct arg *args, struct sample *smp, const char *
if (!smp->strm)
goto not_ssl_hello;
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
goto not_ssl_hello;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
bleft = ci_data(chn);
data = (unsigned char *)ci_head(chn);
@ -707,6 +733,10 @@ smp_fetch_ssl_hello_alpn(const struct arg *args, struct sample *smp, const char
if (!smp->strm)
goto not_ssl_hello;
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
goto not_ssl_hello;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
bleft = ci_data(chn);
data = (unsigned char *)ci_head(chn);
@ -933,6 +963,10 @@ smp_fetch_rdp_cookie(const struct arg *args, struct sample *smp, const char *kw,
if (!smp->strm)
return 0;
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
return 0;
return fetch_rdp_cookie_name(smp->strm, smp,
args ? args->data.str.area : NULL,
args ? args->data.str.data : 0);
@ -973,14 +1007,21 @@ smp_fetch_payload_lv(const struct arg *arg_p, struct sample *smp, const char *kw
/* buf offset could be absolute or relative to len offset + len size if prefixed by + or - */
if (smp->strm) {
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
head = ci_head(chn);
data = ci_data(chn);
}
else if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK) {
struct buffer *buf = &(__objt_check(smp->sess->origin)->bi);
head = b_head(buf);
data = b_data(buf);
struct check *check = __objt_check(smp->sess->origin);
/* meaningless for HTX buffers */
if (check->cs && IS_HTX_CS(check->cs))
return 0;
head = b_head(&check->bi);
data = b_data(&check->bi);
}
max = global.tune.bufsize;
if (!head)
@ -1035,14 +1076,21 @@ smp_fetch_payload(const struct arg *arg_p, struct sample *smp, const char *kw, v
size_t max, data;
if (smp->strm) {
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
head = ci_head(chn);
data = ci_data(chn);
}
else if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK) {
struct buffer *buf = &(__objt_check(smp->sess->origin)->bi);
head = b_head(buf);
data = b_data(buf);
struct check *check = __objt_check(smp->sess->origin);
/* meaningless for HTX buffers */
if (check->cs && IS_HTX_CS(check->cs))
return 0;
head = b_head(&check->bi);
data = b_data(&check->bi);
}
max = global.tune.bufsize;
if (!head)
@ -1143,6 +1191,10 @@ smp_fetch_distcc_param(const struct arg *arg_p, struct sample *smp, const char *
if (!smp->strm)
return 0;
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
ofs = 0; occ = 0;
@ -1220,6 +1272,10 @@ smp_fetch_distcc_body(const struct arg *arg_p, struct sample *smp, const char *k
if (!smp->strm)
return 0;
/* meaningless for HTX buffers */
if (IS_HTX_STRM(smp->strm))
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
ofs = 0; occ = 0;