MEDIUM: checks: Remove dedicated sample fetches and use response ones instead

All sample fetches in the scope "check." have been removed. Response sample
fetches must be used instead. It avoids keyword duplication. So, for instance,
res.hdr() must be now used instead of check.hdr().

To do so, following sample fetches have been added on the response :

  * res.body, res.body_len and res.body_size
  * res.hdrs and res.hdrs_bin

Sample feches dealing with the response's body are only useful in the health
checks context. When called from a stream context, there is no warranty on the
body presence. There is no option to wait the response's body.
This commit is contained in:
Christopher Faulet 2020-05-05 17:46:34 +02:00
parent af4dc4ccaa
commit e596d184be
6 changed files with 117 additions and 231 deletions

View File

@ -87,8 +87,7 @@ 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 health-check samples
7.3.8. Fetching samples for developers
7.3.7. Fetching samples for developers
7.4. Pre-defined ACLs
8. Logging
@ -16959,20 +16958,21 @@ res.len : integer
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.
content inspection. But it may also be used in tcp-check based expect rules.
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,
the the whole buffer from <offset> to the end is extracted. This can be used
the whole buffer from <offset> to the end is extracted. This can be used
with ACLs in order to check for the presence of some content in a buffer at
any location.
any location. It may also be used in tcp-check based expect rules.
res.payload_lv(<offset1>,<length>[,<offset2>]) : binary
This extracts a binary block whose size is specified at <offset1> for <length>
bytes, and which starts at <offset2> if specified or just after the length in
the response buffer. The <offset2> parameter also supports relative offsets
if prepended with a '+' or '-' sign.
if prepended with a '+' or '-' sign. It may also be used in tcp-check based
expect rules.
Example : please consult the example from the "stick store-response" keyword.
@ -17342,6 +17342,26 @@ req_ver : string (deprecated)
ACL derivatives :
req_ver : exact string match
res.body : binary
This returns the HTTP response's available body as a block of data. Unlike
the request side, there is no directive to wait for the response's body. This
sample fetch is really useful (and usable) in the health-check context. It
may be used in tcp-check based expect rules.
res.body_len : integer
This returns the length of the HTTP response available body in bytes. Unlike
the request side, there is no directive to wait for the response's body. This
sample fetch is really useful (and usable) in the health-check context. It
may be used in tcp-check based expect rules.
res.body_size : integer
This returns the advertised length of the HTTP response body in bytes. It
will represent the advertised Content-Length header, or the size of the
available data in case of chunked encoding. Unlike the request side, there is
no directive to wait for the response body. This sample fetch is really
useful (and usable) in the health-check context. It may be used in tcp-check
based expect rules.
res.comp : boolean
Returns the boolean "true" value if the response has been compressed by
HAProxy, otherwise returns boolean "false". This may be used to add
@ -17356,7 +17376,8 @@ res.cook([<name>]) : string
scook([<name>]) : string (deprecated)
This extracts the last occurrence of the cookie name <name> on a "Set-Cookie"
header line from the response, and returns its value as string. If no name is
specified, the first cookie value is returned.
specified, the first cookie value is returned. It may be used in tcp-check
based expect rules.
ACL derivatives :
scook([<name>] : exact string match
@ -17365,13 +17386,15 @@ res.cook_cnt([<name>]) : integer
scook_cnt([<name>]) : integer (deprecated)
Returns an integer value representing the number of occurrences of the cookie
<name> in the response, or all cookies if <name> is not specified. This is
mostly useful when combined with ACLs to detect suspicious responses.
mostly useful when combined with ACLs to detect suspicious responses. It may
be used in tcp-check based expect rules.
res.cook_val([<name>]) : integer
scook_val([<name>]) : integer (deprecated)
This extracts the last occurrence of the cookie name <name> on a "Set-Cookie"
header line from the response, and converts its value to an integer which is
returned. If no name is specified, the first cookie value is returned.
returned. If no name is specified, the first cookie value is returned. It may
be used in tcp-check based expect rules.
res.fhdr([<name>[,<occ>]]) : string
This extracts the last occurrence of header <name> in an HTTP response, or of
@ -17382,14 +17405,15 @@ res.fhdr([<name>[,<occ>]]) : string
differs from res.hdr() in that any commas present in the value are returned
and are not used as delimiters. If this is not desired, the res.hdr() fetch
should be used instead. This is sometimes useful with headers such as Date or
Expires.
Expires. It may be used in tcp-check based expect rules.
res.fhdr_cnt([<name>]) : integer
Returns an integer value representing the number of occurrences of response
header field name <name>, or the total number of header fields if <name> is
not specified. Contrary to its res.hdr_cnt() cousin, this function returns
the number of full line headers and does not stop on commas. If this is not
desired, the res.hdr_cnt() fetch should be used instead.
desired, the res.hdr_cnt() fetch should be used instead. It may be used in
tcp-check based expect rules.
res.hdr([<name>[,<occ>]]) : string
shdr([<name>[,<occ>]]) : string (deprecated)
@ -17400,7 +17424,8 @@ shdr([<name>[,<occ>]]) : string (deprecated)
indicate positions relative to the last one, with -1 being the last one. This
can be useful to learn some data into a stick-table. The function considers
any comma as a delimiter for distinct values. If this is not desired, the
res.fhdr() fetch should be used instead.
res.fhdr() fetch should be used instead. It may be used in tcp-check based
expect rules.
ACL derivatives :
shdr([<name>[,<occ>]]) : exact string match
@ -17418,7 +17443,7 @@ shdr_cnt([<name>]) : integer (deprecated)
header field name <name>, or the total number of header fields if <name> is
not specified. The function considers any comma as a delimiter for distinct
values. If this is not desired, the res.fhdr_cnt() fetch should be used
instead.
instead. It may be used in tcp-check based expect rules.
res.hdr_ip([<name>[,<occ>]]) : ip
shdr_ip([<name>[,<occ>]]) : ip (deprecated)
@ -17427,13 +17452,15 @@ shdr_ip([<name>[,<occ>]]) : ip (deprecated)
specific occurrence might be specified as a position number. Positive values
indicate a position from the first occurrence, with 1 being the first one.
Negative values indicate positions relative to the last one, with -1 being
the last one. This can be useful to learn some data into a stick table.
the last one. This can be useful to learn some data into a stick table. It
may be used in tcp-check based expect rules.
res.hdr_names([<delim>]) : string
This builds a string made from the concatenation of all header names as they
appear in the response when the rule is evaluated. The default delimiter is
the comma (',') but it may be overridden as an optional argument <delim>. In
this case, only the first character of <delim> is considered.
this case, only the first character of <delim> is considered. It may be used
in tcp-check based expect rules.
res.hdr_val([<name>[,<occ>]]) : integer
shdr_val([<name>[,<occ>]]) : integer (deprecated)
@ -17442,12 +17469,35 @@ shdr_val([<name>[,<occ>]]) : integer (deprecated)
specified as a position number. Positive values indicate a position from the
first occurrence, with 1 being the first one. Negative values indicate
positions relative to the last one, with -1 being the last one. This can be
useful to learn some data into a stick table.
useful to learn some data into a stick table. It may be used in tcp-check
based expect rules.
res.hdrs : string
Returns the current response headers as string including the last empty line
separating headers from the request body. The last empty line can be used to
detect a truncated header block. This sample fetch is useful for some SPOE
headers analyzers and for advanced logging. It may also be used in tcp-check
based expect rules.
res.hdrs_bin : binary
Returns the current response headers contained in preparsed binary form. This
is useful for offloading some processing with SPOE. It may be used in
tcp-check based expect rules. Each string is described by a length followed
by the number of bytes indicated in the length. The length is represented
using the variable integer encoding detailed in the SPOE documentation. The
end of the list is marked by a couple of empty header names and values
(length of 0 for both).
*(<str:header-name><str:header-value>)<empty string><empty string>
int: refer to the SPOE documentation for the encoding
str: <int:length><bytes>
res.ver : string
resp_ver : string (deprecated)
Returns the version string from the HTTP response, for example "1.1". This
can be useful for logs, but is mostly there for ACL.
can be useful for logs, but is mostly there for ACL. It may be used in
tcp-check based expect rules.
ACL derivatives :
resp_ver : exact string match
@ -17464,7 +17514,8 @@ set-cookie([<name>]) : string (deprecated)
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,
to remove any Location header if the response is not a 3xx.
to remove any Location header if the response is not a 3xx. It may be used in
tcp-check based expect rules.
unique-id : string
Returns the unique-id attached to the request. The directive
@ -17556,160 +17607,7 @@ url32+src : binary
the source address family. This can be used to track per-IP, per-URL counters.
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.len : integer
Returns an integer value corresponding to the number of bytes present in the
check input buffer, containing the data received from the server. 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).
check.payload(<offset>,<length>) : binary
This extracts a binary block of <length> bytes and starting at byte <offset>
in the check input buffer, containing data received from the server. 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).
check.payload_lv(<offset1>,<length>[,<offset2>]) : binary
This extracts a binary block whose size is specified at <offset1> for
<length> bytes, and which starts at <offset2> if specified or just after the
length in the check input buffer, containing data received from the
server. The <offset2> parameter also supports relative offsets if prepended
with a '+' or '-' sign. 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).
check.body : binary
Returns the available body of the HTTP response in the context of a
http-check health check as a block of data.
check.body_param([<name>) : string
Assumes the body of the HTTP response in the context of a http-check health
check is url-encoded. This extracts the first occurrence of the parameter
<name> in the body, which ends before '&'. The parameter name is
case-sensitive. If no name is given, any parameter will match, and the first
one will be returned. The result is a string corresponding to the value of
the parameter <name> as presented in the request body (no URL decoding is
performed).
check.body_len : integer
Returns the length in bytes of the available body of the HTTP response in the
context of a http-check health check. It may be lower than the advertised
length if the body is larger than the buffer.
check.body_size : integer
Returns the advertised length of the HTTP response's body in bytes in the
context of a http-check health check. It will represent the advertised
Content-Length header, or the size of the available body in case of chunked
encoding.
check.cook([<name>]) : string
Extracts the last occurrence of the cookie name <name> on a "Set-Cookie"
header line from the HTTP response in the context of a http-check health
check, and returns its value as string. If no name is specified, the first
cookie value is returned.
check.cook_cnt([<name>]) : integer
Returns an integer value representing the number of occurrences of the cookie
<name> in the HTTP response in the context of a http-check health check, or
all cookies if <name> is not specified.
check.cook_val([<name>]) : integer
Extracts the last occurrence of the cookie name <name> on a "Set-Cookie"
header line from the HTTP response in the context of a http-check health
check, and converts its value to an integer which is returned. If no name is
specified, the first cookie value is returned.
check.fhdr(<name>[,<occ>]) : string
Extracts the last occurrence of header <name> in an HTTP response in the
context of a http-check health check. Optionally, a specific occurrence might
be specified as a position number. Positive values indicate a position from
the first occurrence, with 1 being the first one. Negative values indicate
positions relative to the last one, with -1 being the last one. It differs
from check.hdr() in that any commas present in the value are returned and are
not used as delimiters.
check.fhdr_cnt([<name>]) : integer
Returns an integer value representing the number of occurrences of response
header field name <name>, or the total number of header fields if <name> is
not specified, in the context of a http-check health check. Contrary to its
check.hdr_cnt() cousin, this function returns the number of full line headers
and does not stop on commas.
check.hdr([<name>[,<occ>]]) : string
Extracts the last occurrence of header <name> in an HTTP response in the
context of a http-check health check. Optionally, a specific occurrence might
be specified as a position number. Positive values indicate a position from
the first occurrence, with 1 being the first one. Negative values indicate
positions relative to the last one, with -1 being the last one. A typical use
is with the X-Forwarded-For header once converted to IP, associated with an
IP stick-table. The function considers any comma as a delimiter for distinct
values. If full-line headers are desired instead, use check.fhdr(). Please
carefully check RFC7231 to know how certain headers are supposed to be
parsed. Also, some of them are case insensitive (e.g. Connection).
check.hdr_cnt([<name>]) : integer
Returns an integer value representing the number of occurrences of response
header field name <name>, or the total number of header field values if
<name> is not specified, in the context of a http-check health check. It is
important to remember that one header line may count as several headers if it
has several values. The function considers any comma as a delimiter for
distinct values. If full-line headers are desired instead, check.fhdr_cnt()
should be used instead. See "check.hdr" for more information on header
matching.
check.hdr_ip([<name>[,<occ>]]) : ip
Extracts the last occurrence of header <name> in an HTTP response in the
context of a http-check health check, converts it to an IPv4 or IPv6 address
and returns this address. If <name> is omitted, every value of every header
is checked. Optionally, a specific occurrence might be specified as a
position number. Positive values indicate a position from the first
occurrence, with 1 being the first one. Negative values indicate positions
relative to the last one, with -1 being the last one. A typical use is with
the X-Forwarded-For and X-Client-IP headers.
check.hdr_val([<name>[,<occ>]]) : integer
Extracts the last occurrence of header <name> in an HTTP response in the
context of a http-check health check, and converts it to an integer value. If
<name> is omitted, every value of every header is checked. Optionally, a
specific occurrence might be specified as a position number. Positive values
indicate a position from the first occurrence, with 1 being the first
one. Negative values indicate positions relative to the last one, with -1
being the last one. A typical use is with the X-Forwarded-For header.
check.hdrs : string
Returns the headers in the HTTP response in the context of a http-check
health check as string including the last empty line separating headers from
the response body. The last empty line can be used to detect a truncated
header block.
check.hdrs_bin : binary
Returns the headers in the HTTP response in the context of a http-check
health check in preparsed binary form.
check.status : integer
Returns an integer containing the HTTP status code of the HTTP response in
the context of a http-check health check, for example, 302.
check.ver : string (deprecated)
Returns the version string from the HTTP response in the context of a
http-check health check, for example "1.1".
7.3.8. Fetching samples for developers
7.3.7. Fetching samples for developers
---------------------------------------
This set of sample fetch methods is reserved to developers and must never be

View File

@ -45,9 +45,9 @@ haproxy h1 -conf {
http-check expect header name -m end "-End"
http-check expect header name -m sub "-Sub-"
http-check expect header name -m reg "^[a-z]+-Reg-[a-z]+[0-9]\$"
http-check set-var(check.hdr_name) check.fhdr(x-hdr-name)
http-check set-var(check.hdr_name) res.fhdr(x-hdr-name)
http-check expect header name -m str "%[var(check.hdr_name)]" log-format
http-check expect header name -m str "%[check.fhdr(x-hdr-name)]" log-format
http-check expect header name -m str "%[res.fhdr(x-hdr-name)]" log-format
http-check expect header name "x-test1" value "true, next value" full
http-check expect header name "x-test2" value -m str "true"
@ -58,7 +58,7 @@ haproxy h1 -conf {
http-check expect header name -m beg "x-test" value -m reg "value-reg-[A-Z0-9]+" full
http-check set-var(check.hdr_value) str(x-test1)
http-check expect header name -m beg "x-" value -m str "%[var(check.hdr_value)]" log-format
http-check expect header name -m beg "x-" value -m str "%[check.fhdr(x-hdr-name)]" log-format full
http-check expect header name -m beg "x-" value -m str "%[res.fhdr(x-hdr-name)]" log-format full
server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1
} -start

View File

@ -6268,7 +6268,7 @@ int proxy_parse_redis_check_opt(char **args, int cur_arg, struct proxy *curpx, s
chk = parse_tcpcheck_expect((char *[]){"tcp-check", "expect", "string", redis_res,
"error-status", "L7STS",
"on-error", "%[check.payload(0,0),cut_crlf]",
"on-error", "%[res.payload(0,0),cut_crlf]",
"on-success", "Redis server is ok",
""},
1, curpx, &rs->rules, TCPCHK_RULES_REDIS_CHK, file, line, &errmsg);
@ -6470,7 +6470,7 @@ int proxy_parse_smtpchk_opt(char **args, int cur_arg, struct proxy *curpx, struc
chk = parse_tcpcheck_expect((char *[]){"tcp-check", "expect", "rstring", "^[0-9]{3}[ \r]",
"min-recv", "4",
"error-status", "L7RSP",
"on-error", "%[check.payload(0,0),cut_crlf]",
"on-error", "%[res.payload(0,0),cut_crlf]",
""},
1, curpx, &rs->rules, TCPCHK_RULES_SMTP_CHK, file, line, &errmsg);
if (!chk) {
@ -6483,8 +6483,8 @@ int proxy_parse_smtpchk_opt(char **args, int cur_arg, struct proxy *curpx, struc
chk = parse_tcpcheck_expect((char *[]){"tcp-check", "expect", "rstring", "^2[0-9]{2}[ \r]",
"min-recv", "4",
"error-status", "L7STS",
"on-error", "%[check.payload(4,0),ltrim(' '),cut_crlf]",
"status-code", "check.payload(0,3)",
"on-error", "%[res.payload(4,0),ltrim(' '),cut_crlf]",
"status-code", "res.payload(0,3)",
""},
1, curpx, &rs->rules, TCPCHK_RULES_SMTP_CHK, file, line, &errmsg);
if (!chk) {
@ -6506,9 +6506,9 @@ int proxy_parse_smtpchk_opt(char **args, int cur_arg, struct proxy *curpx, struc
chk = parse_tcpcheck_expect((char *[]){"tcp-check", "expect", "rstring", "^2[0-9]{2}[- \r]",
"min-recv", "4",
"error-status", "L7STS",
"on-error", "%[check.payload(4,0),ltrim(' '),cut_crlf]",
"on-success", "%[check.payload(4,0),ltrim(' '),cut_crlf]",
"status-code", "check.payload(0,3)",
"on-error", "%[res.payload(4,0),ltrim(' '),cut_crlf]",
"on-success", "%[res.payload(4,0),ltrim(' '),cut_crlf]",
"status-code", "res.payload(0,3)",
""},
1, curpx, &rs->rules, TCPCHK_RULES_SMTP_CHK, file, line, &errmsg);
if (!chk) {
@ -6641,7 +6641,7 @@ int proxy_parse_pgsql_check_opt(char **args, int cur_arg, struct proxy *curpx, s
chk = parse_tcpcheck_expect((char *[]){"tcp-check", "expect", "!rstring", "^E",
"min-recv", "5",
"error-status", "L7RSP",
"on-error", "%[check.payload(6,0)]",
"on-error", "%[res.payload(6,0)]",
""},
1, curpx, &rs->rules, TCPCHK_RULES_PGSQL_CHK, file, line, &errmsg);
if (!chk) {

View File

@ -386,7 +386,7 @@ static int smp_fetch_rqver(const struct arg *args, struct sample *smp, const cha
static int smp_fetch_stver(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_RES_CHN(smp);
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct check *check = (smp->sess ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct htx_sl *sl;
char *ptr;
@ -415,7 +415,7 @@ static int smp_fetch_stver(const struct arg *args, struct sample *smp, const cha
static int smp_fetch_stcode(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_RES_CHN(smp);
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct check *check = (smp->sess ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct htx_sl *sl;
char *ptr;
@ -461,8 +461,9 @@ static int smp_fetch_uniqueid(const struct arg *args, struct sample *smp, const
*/
static int smp_fetch_hdrs(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
/* possible keywords: req.hdrs, res.hdrs */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[2] == 's' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct buffer *temp;
int32_t pos;
@ -507,8 +508,9 @@ static int smp_fetch_hdrs(const struct arg *args, struct sample *smp, const char
*/
static int smp_fetch_hdrs_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
/* possible keywords: req.hdrs_bin, res.hdrs_bin */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[2] == 's' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct buffer *temp;
char *p, *end;
@ -575,8 +577,9 @@ static int smp_fetch_hdrs_bin(const struct arg *args, struct sample *smp, const
*/
static int smp_fetch_body(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
/* possible keywords: req.body, res.body */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[2] == 's' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct buffer *temp;
int32_t pos;
@ -609,8 +612,9 @@ static int smp_fetch_body(const struct arg *args, struct sample *smp, const char
*/
static int smp_fetch_body_len(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
/* possible keywords: req.body_len, res.body_len */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[2] == 's' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
int32_t pos;
unsigned long long len = 0;
@ -641,8 +645,9 @@ static int smp_fetch_body_len(const struct arg *args, struct sample *smp, const
*/
static int smp_fetch_body_size(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
/* possible keywords: req.body_size, res.body_size */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[2] == 's' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
int32_t pos;
unsigned long long len = 0;
@ -739,7 +744,7 @@ static int smp_fetch_fhdr(const struct arg *args, struct sample *smp, const char
{
/* possible keywords: req.fhdr, res.fhdr */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct check *check = ((kw[2] == 's' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct http_hdr_ctx *ctx = smp->ctx.a[0];
struct ist name;
@ -793,7 +798,7 @@ static int smp_fetch_fhdr_cnt(const struct arg *args, struct sample *smp, const
{
/* possible keywords: req.fhdr_cnt, res.fhdr_cnt */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct check *check = ((kw[2] == 's' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct http_hdr_ctx ctx;
struct ist name;
@ -824,7 +829,7 @@ static int smp_fetch_hdr_names(const struct arg *args, struct sample *smp, const
{
/* possible keywords: req.hdr_names, res.hdr_names */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct check *check = ((kw[2] == 's' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct buffer *temp;
char del = ',';
@ -870,7 +875,7 @@ static int smp_fetch_hdr(const struct arg *args, struct sample *smp, const char
{
/* possible keywords: req.hdr / hdr, res.hdr / shdr */
struct channel *chn = ((kw[0] == 'h' || kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct check *check = (((kw[0] == 's' || kw[2] == 's') && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct http_hdr_ctx *ctx = smp->ctx.a[0];
struct ist name;
@ -934,7 +939,7 @@ static int smp_fetch_hdr_cnt(const struct arg *args, struct sample *smp, const c
{
/* possible keywords: req.hdr_cnt / hdr_cnt, res.hdr_cnt / shdr_cnt */
struct channel *chn = ((kw[0] == 'h' || kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct check *check = (((kw[0] == 's' || kw[2] == 's') && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct http_hdr_ctx ctx;
struct ist name;
@ -1558,7 +1563,7 @@ static int smp_fetch_cookie(const struct arg *args, struct sample *smp, const ch
{
/* possible keywords: req.cookie / cookie / cook, res.cookie / scook / set-cookie */
struct channel *chn = ((kw[0] == 'c' || kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct check *check = (((kw[0] == 's' || kw[2] == 's') && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct http_hdr_ctx *ctx = smp->ctx.a[2];
struct ist hdr;
@ -1656,7 +1661,7 @@ static int smp_fetch_cookie_cnt(const struct arg *args, struct sample *smp, cons
{
/* possible keywords: req.cook_cnt / cook_cnt, res.cook_cnt / scook_cnt */
struct channel *chn = ((kw[0] == 'c' || kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct check *check = (((kw[0] == 's' || kw[2] == 's') && smp->sess) ? objt_check(smp->sess->origin) : NULL);
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct http_hdr_ctx ctx;
struct ist hdr;
@ -1836,7 +1841,6 @@ static int smp_fetch_url_param(const struct arg *args, struct sample *smp, const
static int smp_fetch_body_param(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
struct check *check = ((kw[0] == 'c' && smp->sess) ? objt_check(smp->sess->origin) : NULL);
const char *name;
int name_len;
@ -1851,7 +1855,7 @@ static int smp_fetch_body_param(const struct arg *args, struct sample *smp, cons
}
if (!smp->ctx.a[0]) { // first call, find the query string
struct htx *htx = smp_prefetch_htx(smp, chn, check, 1);
struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct buffer *temp;
int32_t pos;
@ -2081,6 +2085,13 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
{ "res.ver", smp_fetch_stver, 0, NULL, SMP_T_STR, SMP_USE_HRSHV },
{ "resp_ver", smp_fetch_stver, 0, NULL, SMP_T_STR, SMP_USE_HRSHV },
{ "res.body", smp_fetch_body, 0, NULL, SMP_T_BIN, SMP_USE_HRSHV },
{ "res.body_len", smp_fetch_body_len, 0, NULL, SMP_T_SINT, SMP_USE_HRSHV },
{ "res.body_size", smp_fetch_body_size, 0, NULL, SMP_T_SINT, SMP_USE_HRSHV },
{ "res.hdrs", smp_fetch_hdrs, 0, NULL, SMP_T_BIN, SMP_USE_HRSHV },
{ "res.hdrs_bin", smp_fetch_hdrs_bin, 0, NULL, SMP_T_BIN, SMP_USE_HRSHV },
/* explicit req.{cook,hdr} are used to force the fetch direction to be request-only */
{ "req.cook", smp_fetch_cookie, ARG1(0,STR), NULL, SMP_T_STR, SMP_USE_HRQHV },
{ "req.cook_cnt", smp_fetch_cookie_cnt, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_HRQHV },
@ -2130,25 +2141,6 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
{ "urlp" , smp_fetch_url_param, ARG2(0,STR,STR), NULL, SMP_T_STR, SMP_USE_HRQHV },
{ "urlp_val", smp_fetch_url_param_val, ARG2(0,STR,STR), NULL, SMP_T_SINT, SMP_USE_HRQHV },
{ "check.ver", smp_fetch_stver, 0, NULL, SMP_T_STR, SMP_USE_INTRN },
{ "check.status", smp_fetch_stcode, 0, NULL, SMP_T_SINT, SMP_USE_INTRN },
{ "check.hdrs", smp_fetch_hdrs, 0, NULL, SMP_T_BIN, SMP_USE_INTRN },
{ "check.hdrs_bin", smp_fetch_hdrs_bin, 0, NULL, SMP_T_BIN, SMP_USE_INTRN },
{ "check.body", smp_fetch_body, 0, NULL, SMP_T_BIN, SMP_USE_INTRN },
{ "check.body_len", smp_fetch_body_len, 0, NULL, SMP_T_SINT, SMP_USE_INTRN },
{ "check.body_size", smp_fetch_body_size, 0, NULL, SMP_T_SINT, SMP_USE_INTRN },
{ "check.body_param", smp_fetch_body_param, ARG1(0,STR), NULL, SMP_T_BIN, SMP_USE_INTRN },
{ "check.fhdr", smp_fetch_fhdr, ARG2(0,STR,SINT), val_hdr, SMP_T_STR, SMP_USE_INTRN },
{ "check.fhdr_cnt", smp_fetch_fhdr_cnt, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_INTRN },
{ "check.hdr", smp_fetch_hdr, ARG2(0,STR,SINT), val_hdr, SMP_T_STR, SMP_USE_INTRN },
{ "check.hdr_cnt", smp_fetch_hdr_cnt, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_INTRN },
{ "check.hdr_ip", smp_fetch_hdr_ip, ARG2(0,STR,SINT), val_hdr, SMP_T_IPV4, SMP_USE_INTRN },
{ "check.hdr_names", smp_fetch_hdr_names, ARG1(0,STR), NULL, SMP_T_STR, SMP_USE_INTRN },
{ "check.hdr_val", smp_fetch_hdr_val, ARG2(0,STR,SINT), val_hdr, SMP_T_SINT, SMP_USE_INTRN },
{ "check.cook", smp_fetch_cookie, ARG1(0,STR), NULL, SMP_T_STR, SMP_USE_INTRN },
{ "check.cook_cnt", smp_fetch_cookie_cnt, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_INTRN },
{ "check.cook_val", smp_fetch_cookie_val, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_INTRN },
{ /* END */ },
}};

View File

@ -1359,10 +1359,6 @@ static struct sample_fetch_kw_list smp_kws = {ILH, {
{ "res.payload_lv", smp_fetch_payload_lv, ARG3(2,SINT,SINT,STR), val_payload_lv, SMP_T_BIN, SMP_USE_L6RES },
{ "res.ssl_hello_type", smp_fetch_ssl_hello_type, 0, NULL, SMP_T_SINT, SMP_USE_L6RES },
{ "wait_end", smp_fetch_wait_end, 0, NULL, SMP_T_BOOL, SMP_USE_INTRN },
{ "check.len", smp_fetch_len, 0, NULL, SMP_T_SINT, SMP_USE_INTRN },
{ "check.payload", smp_fetch_payload, ARG2(2,SINT,SINT), NULL, SMP_T_BIN, SMP_USE_INTRN },
{ "check.payload_lv", smp_fetch_payload_lv, ARG3(2,SINT,SINT,STR), val_payload_lv, SMP_T_BIN, SMP_USE_INTRN },
{ /* END */ },
}};

View File

@ -185,7 +185,7 @@ const unsigned int fetch_cap[SMP_SRC_ENTRIES] = {
SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
SMP_VAL___________ | SMP_VAL___________),
SMP_VAL___________ | SMP_VAL_BE_CHK_RUL),
[SMP_SRC_HRSHV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
@ -193,7 +193,7 @@ const unsigned int fetch_cap[SMP_SRC_ENTRIES] = {
SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
SMP_VAL___________ | SMP_VAL___________),
SMP_VAL___________ | SMP_VAL_BE_CHK_RUL),
[SMP_SRC_HRSHP] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
@ -201,7 +201,7 @@ const unsigned int fetch_cap[SMP_SRC_ENTRIES] = {
SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
SMP_VAL_FE_LOG_END | SMP_VAL___________),
SMP_VAL_FE_LOG_END | SMP_VAL_BE_CHK_RUL),
[SMP_SRC_HRSBO] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
@ -209,7 +209,7 @@ const unsigned int fetch_cap[SMP_SRC_ENTRIES] = {
SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
SMP_VAL___________ | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
SMP_VAL___________ | SMP_VAL___________),
SMP_VAL___________ | SMP_VAL_BE_CHK_RUL),
[SMP_SRC_RQFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |