MINOR: payload: add new direction-explicit sample fetches

Similarly to previous commit fixing "hdr" and "cookie" in HTTP, we have to deal
with "payload" and "payload_lv" which are request-only for ACLs and req/resp for
sample fetches depending on the context, and to a less extent with other req_*
and rep_*/rep_* fetches. So let's add explicit "req." and "res." variants and
make the ACLs rely on that instead.
This commit is contained in:
Willy Tarreau 2013-01-14 16:07:52 +01:00
parent 18ed2569f5
commit fa95734840
2 changed files with 126 additions and 72 deletions

View File

@ -9721,20 +9721,16 @@ The list of currently supported pattern fetch functions is the following :
wiser to use "url" instead. wiser to use "url" instead.
payload(<offset>,<length>) payload(<offset>,<length>)
This extracts a binary block of <length> bytes, and starting This is an alias for "req.payload" when used in the context of a
at bytes <offset> in the buffer of request or response (request request (eg: "stick on", "stick match"), and for "res.payload"
on "stick on" or "stick match" or response in on "stick store when used in the context of a response such as in
response"). "stick store response".
payload_lv(<offset1>,<length>[,<offset2>]) payload_lv(<offset1>,<length>[,<offset2>])
This extracts a binary block. In a first step the size of the This is an alias for "req.payload_lv" when used in the context
block is read from response or request buffer at <offset> of a request (eg: "stick on" or "stick match"), and for
bytes and considered coded on <length> bytes. In a second step "res.payload_lv" when used in the context of a response such as
data of the block are read from buffer at <offset2> bytes in "stick store response".
(by default <lengthoffset> + <lengthsize>).
If <offset2> is prefixed by '+' or '-', it is relative to
<lengthoffset> + <lengthsize> else it is absolute.
Ex: see SSL session id example in "stick table" chapter.
queue([<backend>]) queue([<backend>])
Returns the total number of queued connections of the designated Returns the total number of queued connections of the designated
@ -9744,51 +9740,13 @@ The list of currently supported pattern fetch functions is the following :
or to pass statistics to backend servers. or to pass statistics to backend servers.
rdp_cookie(<name>) rdp_cookie(<name>)
This extracts the value of the rdp cookie <name> as a string This is an alias for "req.rdp_cookie".
and uses this value to match. This enables implementation of
persistence based on the mstshash cookie. This is typically
done if there is no msts cookie present.
This differs from "balance rdp-cookie" in that any balancing
algorithm may be used and thus the distribution of clients
to backend servers is not linked to a hash of the RDP
cookie. It is envisaged that using a balancing algorithm
such as "balance roundrobin" or "balance leastconnect" will
lead to a more even distribution of clients to backend
servers than the hash used by "balance rdp-cookie".
Example :
listen tse-farm
bind 0.0.0.0:3389
# wait up to 5s for an RDP cookie in the request
tcp-request inspect-delay 5s
tcp-request content accept if RDP_COOKIE
# apply RDP cookie persistence
persist rdp-cookie
# Persist based on the mstshash cookie
# This is only useful makes sense if
# balance rdp-cookie is not used
stick-table type string size 204800
stick on rdp_cookie(mstshash)
server srv1 1.1.1.1:3389
server srv1 1.1.1.2:3389
See also : "balance rdp-cookie", "persist rdp-cookie",
"tcp-request" and the "req_rdp_cookie" ACL.
rdp_cookie_cnt([name]) rdp_cookie_cnt([name])
Tries to parse the request buffer as RDP protocol, then returns This is an alias for "req.rdp_cookie_cnt".
an integer corresponding to the number of RDP cookies found. If
an optional cookie name is passed, only cookies matching this
name are considered. This is mostly used in ACL.
rep_ssl_hello_type rep_ssl_hello_type
Returns an integer value containing the type of the SSL hello This is an alias for "res.ssl_hello_type".
message found in the response buffer. Note that this only
applies to raw contents found in the response buffer and not to
contents deciphered via an SSL data layer, so this will not work
with "server" lines having the "ssl" option. This is mostly used
in ACL.
req.cook([<name>]) req.cook([<name>])
This extracts the last occurrence of the cookie name <name> on a This extracts the last occurrence of the cookie name <name> on a
@ -9839,6 +9797,23 @@ The list of currently supported pattern fetch functions is the following :
relative to the last one, with -1 being the last one. A typical relative to the last one, with -1 being the last one. A typical
use is with the X-Forwarded-For header. use is with the X-Forwarded-For header.
req.len Returns an integer value corresponding to the number of bytes
present in the request buffer. This is mostly used in ACL.
req.payload(<offset>,<length>)
This extracts a binary block of <length> bytes and starting at
bytes <offset> in the request buffer.
req.payload_lv(<offset1>,<length>[,<offset2>])
This extracts a binary block. In a first step the size of the
block is read from the request request buffer at <offset> bytes
and considered coded on <length> bytes. In a second step data of
the block are read from buffer at <offset2> bytes (by default
<lengthoffset> + <lengthsize>). If <offset2> is prefixed by '+'
or '-', it is relative to <lengthoffset> + <lengthsize> else it
is absolute. Ex: see SSL session id example in "stick table"
chapter.
req.proto_http req.proto_http
Returns true when data in the request buffer look like HTTP and Returns true when data in the request buffer look like HTTP and
correctly parses as such. It is the same parser as the common correctly parses as such. It is the same parser as the common
@ -9846,16 +9821,46 @@ The list of currently supported pattern fetch functions is the following :
surprises. This test may be used to report the protocol in TCP surprises. This test may be used to report the protocol in TCP
logs. logs.
req.ver Returns the version string from the HTTP request, for example req.rdp_cookie(<name>)
"1.1". This can be useful for logs, but is mostly there for ACL. This extracts the value of the rdp cookie <name> as a string
and uses this value to match. This enables implementation of
persistence based on the mstshash cookie. This is typically
done if there is no msts cookie present.
req_len Returns an integer value corresponding to the number of bytes This differs from "balance rdp-cookie" in that any balancing
present in the request buffer. This is mostly used in ACL. algorithm may be used and thus the distribution of clients
to backend servers is not linked to a hash of the RDP
cookie. It is envisaged that using a balancing algorithm
such as "balance roundrobin" or "balance leastconn" will
lead to a more even distribution of clients to backend
servers than the hash used by "balance rdp-cookie".
req_proto_http Example :
This is an alias for "req_proto_http". listen tse-farm
bind 0.0.0.0:3389
# wait up to 5s for an RDP cookie in the request
tcp-request inspect-delay 5s
tcp-request content accept if RDP_COOKIE
# apply RDP cookie persistence
persist rdp-cookie
# Persist based on the mstshash cookie
# This is only useful makes sense if
# balance rdp-cookie is not used
stick-table type string size 204800
stick on req.rdp_cookie(mstshash)
server srv1 1.1.1.1:3389
server srv1 1.1.1.2:3389
req_ssl_hello_type See also : "balance rdp-cookie", "persist rdp-cookie",
"tcp-request" and the "req_rdp_cookie" ACL.
req.rdp_cookie_cnt([name])
Tries to parse the request buffer as RDP protocol, then returns
an integer corresponding to the number of RDP cookies found. If
an optional cookie name is passed, only cookies matching this
name are considered. This is mostly used in ACL.
req.ssl_hello_type
Returns an integer value containing the type of the SSL hello Returns an integer value containing the type of the SSL hello
message found in the request buffer. Note that this only applies message found in the request buffer. Note that this only applies
to raw contents found in the request buffer and not to contents to raw contents found in the request buffer and not to contents
@ -9863,14 +9868,14 @@ The list of currently supported pattern fetch functions is the following :
"bind" lines having the "ssl" option. This is mostly used in "bind" lines having the "ssl" option. This is mostly used in
ACL. ACL.
req_ssl_sni Returns a string containing the value of the Server Name TLS req.ssl_sni Returns a string containing the value of the Server Name TLS
extension sent by a client in a TLS stream passing through the extension sent by a client in a TLS stream passing through the
request buffer. Note that this only applies to raw contents request buffer. Note that this only applies to raw contents
found in the request buffer and not to contents deciphered via found in the request buffer and not to contents deciphered via
an SSL data layer, so this will not work with "bind" lines an SSL data layer, so this will not work with "bind" lines
having the "ssl" option. This is mostly used in ACL. having the "ssl" option. This is mostly used in ACL.
req_ssl_ver Returns an integer value containing the version of the SSL/TLS req.ssl_ver Returns an integer value containing the version of the SSL/TLS
protocol of a stream present in the request buffer. The value is protocol of a stream present in the request buffer. The value is
composed of the major version multiplied by 65536, added to the composed of the major version multiplied by 65536, added to the
minor version. Note that this only applies to raw contents found minor version. Note that this only applies to raw contents found
@ -9878,6 +9883,21 @@ The list of currently supported pattern fetch functions is the following :
data layer, so this will not work with "bind" lines having the data layer, so this will not work with "bind" lines having the
"ssl" option. This is mostly used in ACL. "ssl" option. This is mostly used in ACL.
req.ver Returns the version string from the HTTP request, for example
"1.1". This can be useful for logs, but is mostly there for ACL.
req_len This is an alias for "req.len".
req_proto_http
This is an alias for "req_proto_http".
req_ssl_hello_type
This is an alias for "req.ssl_hello_type".
req_ssl_sni This is an alias for "req.ssl_sni".
req_ssl_ver This is an alias for "req.ssl_ver".
req_ver This is an alias for "req.ver". req_ver This is an alias for "req.ver".
res.cook([<name>]) res.cook([<name>])
@ -9930,6 +9950,28 @@ The list of currently supported pattern fetch functions is the following :
relative to the last one, with -1 being the last one. This can relative to the last one, with -1 being the last one. This can
be useful to learn some data into a stick table. be useful to learn some data into a stick table.
res.payload(<offset>,<length>)
This extracts a binary block of <length> bytes and starting at
bytes <offset> in the response buffer.
res.payload_lv(<offset1>,<length>[,<offset2>])
This extracts a binary block. In a first step the size of the
block is read from the response request buffer at <offset> bytes
and considered coded on <length> bytes. In a second step data of
the block are read from buffer at <offset2> bytes (by default
<lengthoffset> + <lengthsize>). If <offset2> is prefixed by '+'
or '-', it is relative to <lengthoffset> + <lengthsize> else it
is absolute. Ex: see SSL session id example in "stick table"
chapter.
res.ssl_hello_type
Returns an integer value containing the type of the SSL hello
message found in the response buffer. Note that this only
applies to raw contents found in the response buffer and not to
contents deciphered via an SSL data layer, so this will not work
with "server" lines having the "ssl" option. This is mostly used
in ACL.
res.ver Returns the version string from the HTTP response, for example res.ver Returns the version string from the HTTP response, for example
"1.1". This can be useful for logs, but is mostly there for ACL. "1.1". This can be useful for logs, but is mostly there for ACL.

View File

@ -660,6 +660,18 @@ static struct sample_fetch_kw_list smp_kws = {{ },{
{ "req_ssl_hello_type", smp_fetch_ssl_hello_type, 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_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_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.payload", smp_fetch_payload, ARG2(2,UINT,UINT), val_payload, 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 },
{ "req.rdp_cookie_cnt", smp_fetch_rdp_cookie_cnt, ARG1(0,STR), 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 },
{ "res.payload", smp_fetch_payload, ARG2(2,UINT,UINT), val_payload, 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 },
{ "wait_end", smp_fetch_wait_end, 0, NULL, SMP_T_BOOL, SMP_USE_INTRN }, { "wait_end", smp_fetch_wait_end, 0, NULL, SMP_T_BOOL, SMP_USE_INTRN },
{ /* END */ }, { /* END */ },
}}; }};
@ -669,16 +681,16 @@ static struct sample_fetch_kw_list smp_kws = {{ },{
* Please take care of keeping this list alphabetically sorted. * Please take care of keeping this list alphabetically sorted.
*/ */
static struct acl_kw_list acl_kws = {{ },{ static struct acl_kw_list acl_kws = {{ },{
{ "payload", NULL, acl_parse_str, acl_match_str, ACL_USE_L6REQ_VOLATILE }, { "payload", "req.payload", acl_parse_str, acl_match_str, ACL_USE_L6REQ_VOLATILE },
{ "payload_lv", NULL, acl_parse_str, acl_match_str, ACL_USE_L6REQ_VOLATILE }, { "payload_lv", "req.payload_lv", acl_parse_str, acl_match_str, ACL_USE_L6REQ_VOLATILE },
{ "rep_ssl_hello_type", NULL, acl_parse_int, acl_match_int, ACL_USE_L6RTR_VOLATILE }, { "rep_ssl_hello_type", "res.ssl_hello_type", acl_parse_int, acl_match_int, ACL_USE_L6RTR_VOLATILE },
{ "req_len", NULL, acl_parse_int, acl_match_int, ACL_USE_L6REQ_VOLATILE }, { "req_len", "req.len", acl_parse_int, acl_match_int, ACL_USE_L6REQ_VOLATILE },
{ "req_rdp_cookie", "rdp_cookie", acl_parse_str, acl_match_str, ACL_USE_L6REQ_VOLATILE }, { "req_rdp_cookie", "req.rdp_cookie", acl_parse_str, acl_match_str, ACL_USE_L6REQ_VOLATILE },
{ "req_rdp_cookie_cnt", "rdp_cookie_cnt", acl_parse_int, acl_match_int, ACL_USE_L6REQ_VOLATILE }, { "req_rdp_cookie_cnt", "req.rdp_cookie_cnt", acl_parse_int, acl_match_int, ACL_USE_L6REQ_VOLATILE },
{ "req_ssl_hello_type", NULL, acl_parse_int, acl_match_int, ACL_USE_L6REQ_VOLATILE }, { "req_ssl_hello_type", "req.ssl_hello_type", acl_parse_int, acl_match_int, ACL_USE_L6REQ_VOLATILE },
{ "req_ssl_sni", NULL, acl_parse_str, acl_match_str, ACL_USE_L6REQ_VOLATILE }, { "req_ssl_sni", "req.ssl_sni", acl_parse_str, acl_match_str, ACL_USE_L6REQ_VOLATILE },
{ "req_ssl_ver", NULL, acl_parse_dotted_ver, acl_match_int, ACL_USE_L6REQ_VOLATILE }, { "req_ssl_ver", "req.ssl_ver", acl_parse_dotted_ver, acl_match_int, ACL_USE_L6REQ_VOLATILE },
{ "wait_end", NULL, acl_parse_nothing, acl_match_nothing, ACL_USE_NOTHING }, { "wait_end", NULL, acl_parse_nothing, acl_match_nothing, ACL_USE_NOTHING },
{ /* END */ }, { /* END */ },
}}; }};