MINOR: payload: provide the "res.len" fetch method

This fetch method returns the response buffer len, similarly
to req.len for the request. Previously it was only possible
to rely on "res.payload(0,size) -m found" to find if at least
that amount of data was available, which was a bit tricky.
This commit is contained in:
Willy Tarreau 2013-09-11 23:28:46 +02:00
parent cc1e04b1e8
commit 47e8eba9a7
2 changed files with 18 additions and 5 deletions

View File

@ -9825,6 +9825,16 @@ req_ssl_ver : integer (deprecated)
ACL derivatives :
req_ssl_ver : decimal match
res.len : integer
Returns an integer value corresponding to the number of bytes present in the
response buffer. This is mostly used in ACL. It is important to understand
that this test does not return false as long as the buffer is changing. This
means that a check with equality to zero will almost always immediately match
at the beginning of the session, while a test for more data will wait for
that data to come in and return false only when haproxy is certain that no
more data will come in. This test was designed to be used with TCP response
content inspection.
res.payload(<offset>,<length>) : binary
This extracts a binary block of <length> bytes and starting at byte <offset>
in the response buffer. As a special case, if the <length> argument is zero,

View File

@ -42,14 +42,16 @@ smp_fetch_wait_end(struct proxy *px, struct session *s, void *l7, unsigned int o
/* return the number of bytes in the request buffer */
static int
smp_fetch_req_len(struct proxy *px, struct session *s, void *l7, unsigned int opt,
smp_fetch_len(struct proxy *px, struct session *s, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp, const char *kw)
{
if (!s || !s->req)
struct channel *chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? s->rep : s->req;
if (!s || !chn)
return 0;
smp->type = SMP_T_UINT;
smp->data.uint = s->req->buf->i;
smp->data.uint = chn->buf->i;
smp->flags = SMP_F_VOLATILE | SMP_F_MAY_CHANGE;
return 1;
}
@ -651,12 +653,12 @@ static struct sample_fetch_kw_list smp_kws = {ILH, {
{ "rdp_cookie", smp_fetch_rdp_cookie, ARG1(0,STR), NULL, SMP_T_CSTR, SMP_USE_L6REQ },
{ "rdp_cookie_cnt", smp_fetch_rdp_cookie_cnt, ARG1(0,STR), NULL, SMP_T_UINT, SMP_USE_L6REQ },
{ "rep_ssl_hello_type", smp_fetch_ssl_hello_type, 0, NULL, SMP_T_UINT, SMP_USE_L6RES },
{ "req_len", smp_fetch_req_len, 0, NULL, SMP_T_UINT, SMP_USE_L6REQ },
{ "req_len", smp_fetch_len, 0, NULL, SMP_T_UINT, SMP_USE_L6REQ },
{ "req_ssl_hello_type", smp_fetch_ssl_hello_type, 0, NULL, SMP_T_UINT, SMP_USE_L6REQ },
{ "req_ssl_sni", smp_fetch_ssl_hello_sni, 0, NULL, SMP_T_CSTR, SMP_USE_L6REQ },
{ "req_ssl_ver", smp_fetch_req_ssl_ver, 0, NULL, SMP_T_UINT, SMP_USE_L6REQ },
{ "req.len", smp_fetch_req_len, 0, NULL, SMP_T_UINT, SMP_USE_L6REQ },
{ "req.len", smp_fetch_len, 0, NULL, SMP_T_UINT, SMP_USE_L6REQ },
{ "req.payload", smp_fetch_payload, ARG2(2,UINT,UINT), NULL, SMP_T_CBIN, SMP_USE_L6REQ },
{ "req.payload_lv", smp_fetch_payload_lv, ARG3(2,UINT,UINT,SINT), val_payload_lv, SMP_T_CBIN, SMP_USE_L6REQ },
{ "req.rdp_cookie", smp_fetch_rdp_cookie, ARG1(0,STR), NULL, SMP_T_CSTR, SMP_USE_L6REQ },
@ -664,6 +666,7 @@ static struct sample_fetch_kw_list smp_kws = {ILH, {
{ "req.ssl_hello_type", smp_fetch_ssl_hello_type, 0, NULL, SMP_T_UINT, SMP_USE_L6REQ },
{ "req.ssl_sni", smp_fetch_ssl_hello_sni, 0, NULL, SMP_T_CSTR, SMP_USE_L6REQ },
{ "req.ssl_ver", smp_fetch_req_ssl_ver, 0, NULL, SMP_T_UINT, SMP_USE_L6REQ },
{ "res.len", smp_fetch_len, 0, NULL, SMP_T_UINT, SMP_USE_L6RES },
{ "res.payload", smp_fetch_payload, ARG2(2,UINT,UINT), NULL, SMP_T_CBIN, SMP_USE_L6RES },
{ "res.payload_lv", smp_fetch_payload_lv, ARG3(2,UINT,UINT,SINT), val_payload_lv, SMP_T_CBIN, SMP_USE_L6RES },
{ "res.ssl_hello_type", smp_fetch_ssl_hello_type, 0, NULL, SMP_T_UINT, SMP_USE_L6RES },