]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: http: unify acl and sample fetch functions
authorWilly Tarreau <w@1wt.eu>
Mon, 7 Jan 2013 23:31:00 +0000 (00:31 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 3 Apr 2013 00:12:57 +0000 (02:12 +0200)
The following sample fetch functions were only usable by ACLs but are now
usable by sample fetches too :

    cook, cook_cnt, cook_val, hdr_cnt, hdr_ip, hdr_val, http_auth,
    http_auth_group, http_first_req, method, req_proto_http, req_ver,
    resp_ver, scook, scook_cnt, scook_val, shdr, shdr_cnt, shdr_ip,
    shdr_val, status, urlp, urlp_val,

Most of them won't bring much benefit at the moment, or are even aliases of
existing ones, however they'll be needed for ACL->SMP convergence.

A new val_usr() function was added to resolve userlist names into pointers.

The http_auth_group ACL forgot to make its first argument mandatory, so
there was a check in cfgparse to report a vague error. Now that args are
correctly parsed, let's report something more precise.

All urlp* ACLs now support an optional 3rd argument like their sample
counter-part which is the optional delimiter.

The fetch functions have been renamed "smp_fetch_*".

Some args controls on the sample keywords have been relaxed so that we
can soon use them for ACLs :

  - cookie now accepts to have an optional name ; it will return the
    first matching cookie if the name is not set ;
  - same for set-cookie and hdr

doc/configuration.txt
src/proto_http.c

index aef2a2c846b83d4370b085d6070fa2cc6ee2d34b..8183daad6037984fa7772208e35954bbcc5544d5 100644 (file)
@@ -9612,17 +9612,35 @@ The list of currently supported pattern fetch functions is the following :
                queue size. This is only used with ACLs. See the ACL "connslots"
                keyword description for more information on possible caveats.
 
-  cookie(<name>)
+  cook([<name>])
+               This extracts the last occurrence of the cookie name <name> on a
+               "Cookie" header line from the request, and returns its value as
+               string. If no name is specified, the first cookie value is
+               returned.
+
+  cookie([<name>])
                This extracts the last occurrence of the cookie name <name> on a
                "Cookie" header line from the request, or a "Set-Cookie" header
-               from the response, and uses the corresponding value to match. A
-               typical use is to get multiple clients sharing a same profile
-               use the same server. This can be similar to what "appsession"
-               does with the "request-learn" statement, but with support for
-               multi-peer synchronization and state keeping across restarts.
+               from the response, and returns its value as a string. A typical
+               use is to get multiple clients sharing a same profile use the
+               same server. This can be similar to what "appsession" does with
+               the "request-learn" statement, but with support for multi-peer
+               synchronization and state keeping across restarts. If no name is
+               specified, the first cookie value is returned.
 
                See also : "appsession"
 
+  cook_cnt([<name>])
+               Returns an integer value representing the number of occurrences of
+               the cookie <name> in the request, or all cookies if <name> is not
+               specified.
+
+  cook_val([<name>])
+               This extracts the last occurrence of the cookie name <name> on a
+               "Cookie" header line from the request, and converts its value to
+               an integer which is returned. If no name is specified, the first
+               cookie value is returned.
+
   dst          This is the destination IPv4 address of the session on the
                client side, which is the address the client connected to.
                It can be useful when running in transparent mode. It is of
@@ -9673,6 +9691,49 @@ The list of currently supported pattern fetch functions is the following :
                last one. A typical use is with the X-Forwarded-For header once
                converted to IP, associated with an IP stick-table.
 
+  hdr_cnt([<name>])
+               Returns an integer value representing the number of occurrences
+               of request header field name <name>, or the total number of
+               header fields if <name> is not specified.
+
+  hdr_ip([<name>[,<occ>]])
+               This extracts the last occurrence of header <name> in an HTTP
+               request, converts it to an IPv4 or IPv6 address and returns this
+               address. 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.
+
+  hdr_val([<name>[,<occ>]])
+               This extracts the last occurrence of header <name> in an HTTP
+               request, and converts it to an integer value. 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.
+
+  http_auth(<userlist>)
+  http_auth_group(<userlist>)
+               Returns a boolean indicating whether the authentication data
+               received from the client match a username & password stored in
+               the specified userlist. These fetch functions are not really
+               useful outside of ACLs.
+
+  http_first_req
+               Returns true when the request being processed is the first one
+               of the connection. This can be used to add or remove headers
+               that may be missing from some requests when a request is not the
+               first one, or to help grouping requests in the logs.
+
+  method
+               Returns an integer value corresponding to the to the method in
+               the HTTP request. For example, "GET" equals 1 (check sources to
+               establish the matching). Value 9 means "other method" and may be
+               converted to a string extracted from the stream. This should not
+               be used directly, this is only meant to be used from ACLs.
+
   nbsrv([<backend>])
                Returns an integer value corresponding to the number of usable
                servers of either the current backend or the named backend. This
@@ -9758,6 +9819,13 @@ The list of currently supported pattern fetch functions is the following :
   req_len      Returns an integer value corresponding to the number of bytes
                present in the request buffer. This is mostly used in ACL.
 
+  req_proto_http
+               Returns true when data in the request buffer look like HTTP and
+               correctly parses as such. It is the same parser as the common
+               HTTP request parser which is used so there should be no
+               surprises. This test may be used to report the protocol in TCP
+               logs.
+
   req_ssl_hello_type
                Returns an integer value containing the type of the SSL hello
                message found in the request buffer. Note that this only applies
@@ -9781,6 +9849,29 @@ The list of currently supported pattern fetch functions is the following :
                data layer, so this will not work with "bind" lines having the
                "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.
+
+  resp_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.
+
+  scook([<name>])
+               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.
+
+  scook_cnt([<name>])
+               Returns an integer value representing the number of occurrences of
+               the cookie <name> in the response, or all cookies if <name> is not
+               specified.
+
+  scook_val([<name>])
+               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.
+
   set-cookie(<name>)
                This fetch function is deprecated and has been superseded by the
                "cookie" fetch which is capable of handling both requests and
@@ -9794,6 +9885,39 @@ The list of currently supported pattern fetch functions is the following :
 
                See also : "appsession"
 
+  shdr(<name>[,<occ>])
+               This extracts the last occurrence of header <name> in an HTTP
+               response. 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. This can be useful to learn some data into
+               a stick-table.
+
+  shdr_cnt([<name>])
+               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.
+
+  shdr_ip([<name>[,<occ>]])
+               This extracts the last occurrence of header <name> in an HTTP
+               response, convert it to an IPv4 or IPv6 address and returns this
+               address. 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. This can be useful to learn some data into a stick
+               table.
+
+  shdr_val([<name>[,<occ>]])
+               This extracts the last occurrence of header <name> in an HTTP
+               response, and converts it to an integer value. 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. This can
+               be useful to learn some data into a stick table.
+
   so_id        Returns an integer containing the listening socket's id.
 
   src          This is the source IPv4 address of the client of the session.
@@ -10006,11 +10130,27 @@ The list of currently supported pattern fetch functions is the following :
                Returns the symmetric cipher key size used in bits when the
                incoming connection was made over an SSL/TLS transport layer.
 
+  status       Returns an integer containing the HTTP status code in the HTTP
+               response, for example, 302. It is mostly used within ACLs.
+
   url          This extracts the request's URL as presented in the request. A
                typical use is with prefetch-capable caches, and with portals
                which need to aggregate multiple information from databases and
                keep them in caches. See also "path".
 
+  urlp(<name>[,<delim>])
+               Note: all "urlp*" sample fetch methods apply only to the first
+               occurrence of the parameter <name> in the query string, which
+               is delimited by character <delim> if specified, otherwise '&'.
+               The parameter name is case-sensitive. This one extracts a string
+               corresponding to the value of the parameter <name>. This can be
+               used for session stickiness.
+
+  urlp_val(<name>[,<delim>])
+               See "urlp" above. This one extracts the URL parameter <name> in
+               the request and converts it ao an integer value. This can be
+               used for session stickiness.
+
   url_ip       This extracts the IP address from the request's URL when the
                host part is presented as an IP address. Its use is very
                limited. For instance, a monitoring system might use this field
index 56d8dd6ddab24710b6bbea2a2ff3402289943fcf..e11d2a7cb954c209751dc22a7d3a7e618295c651 100644 (file)
@@ -8471,7 +8471,7 @@ static int acl_parse_meth(const char **text, struct acl_pattern *pattern, int *o
  * This is intended to be used with acl_match_meth() only.
  */
 static int
-acl_fetch_meth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_meth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                const struct arg *args, struct sample *smp)
 {
        int meth;
@@ -8537,7 +8537,7 @@ static int acl_parse_ver(const char **text, struct acl_pattern *pattern, int *op
 }
 
 static int
-acl_fetch_rqver(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_rqver(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                 const struct arg *args, struct sample *smp)
 {
        struct http_txn *txn = l7;
@@ -8562,7 +8562,7 @@ acl_fetch_rqver(struct proxy *px, struct session *l4, void *l7, unsigned int opt
 }
 
 static int
-acl_fetch_stver(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_stver(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                 const struct arg *args, struct sample *smp)
 {
        struct http_txn *txn = l7;
@@ -8591,7 +8591,7 @@ acl_fetch_stver(struct proxy *px, struct session *l4, void *l7, unsigned int opt
 
 /* 3. Check on Status Code. We manipulate integers here. */
 static int
-acl_fetch_stcode(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_stcode(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                  const struct arg *args, struct sample *smp)
 {
        struct http_txn *txn = l7;
@@ -8974,7 +8974,7 @@ smp_fetch_base32_src(struct proxy *px, struct session *l4, void *l7, unsigned in
 }
 
 static int
-acl_fetch_proto_http(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_proto_http(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                      const struct arg *args, struct sample *smp)
 {
        /* Note: hdr_idx.v cannot be NULL in this ACL because the ACL is tagged
@@ -8990,7 +8990,7 @@ acl_fetch_proto_http(struct proxy *px, struct session *l4, void *l7, unsigned in
 
 /* return a valid test if the current request is the first one on the connection */
 static int
-acl_fetch_http_first_req(struct proxy *px, struct session *s, void *l7, unsigned int opt,
+smp_fetch_http_first_req(struct proxy *px, struct session *s, void *l7, unsigned int opt,
                          const struct arg *args, struct sample *smp)
 {
        if (!s)
@@ -9003,7 +9003,7 @@ acl_fetch_http_first_req(struct proxy *px, struct session *s, void *l7, unsigned
 
 /* Accepts exactly 1 argument of type userlist */
 static int
-acl_fetch_http_auth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_http_auth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                     const struct arg *args, struct sample *smp)
 {
 
@@ -9022,7 +9022,7 @@ acl_fetch_http_auth(struct proxy *px, struct session *l4, void *l7, unsigned int
 
 /* Accepts exactly 1 argument of type userlist */
 static int
-acl_fetch_http_auth_grp(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_http_auth_grp(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                         const struct arg *args, struct sample *smp)
 {
 
@@ -9254,7 +9254,7 @@ smp_fetch_cookie(struct proxy *px, struct session *l4, void *l7, unsigned int op
  * Accepts exactly 1 argument of type string.
  */
 static int
-acl_fetch_cookie_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_cookie_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                      const struct arg *args, struct sample *smp)
 {
        struct http_txn *txn = l7;
@@ -9485,6 +9485,35 @@ static int val_hdr(struct arg *arg, char **err_msg)
        return 1;
 }
 
+/* This function is used to validate the arguments passed to any "http_auth" fetch
+ * keyword. These keywords support a mandatory userlist name which must be replaced
+ * by a pointer to the userlist. It is assumed that the types are already the correct
+ * ones. Returns 0 on error, non-zero if OK. If <err> is not NULL, it will be filled
+ * with a pointer to an error message in case of error, that the caller is responsible
+ * for freeing. The initial location must either be freeable or NULL.
+ */
+static int val_usr(struct arg *arg, char **err_msg)
+{
+       struct userlist *ul;
+
+       if (!arg || arg[0].type != ARGT_USR || !arg[0].data.str.len) {
+               memprintf(err_msg, "the name of a userlist is expected");
+               return 0;
+       }
+
+       ul = auth_find_userlist(arg[0].data.str.str);
+       if (!ul) {
+               memprintf(err_msg, "unable to find userlist <%s>", arg[0].data.str.str);
+               return 0;
+       }
+
+       free(arg[0].data.str.str);
+       arg[0].data.str.str = NULL;
+       arg[0].unresolved = 0;
+       arg[0].data.usr = ul;
+       return 1;
+}
+
 /************************************************************************/
 /*          All supported ACL keywords must be declared here.           */
 /************************************************************************/
@@ -9504,7 +9533,7 @@ static struct acl_kw_list acl_kws = {{ },{
 
        { "cook",            acl_parse_str,     smp_fetch_cookie,         acl_match_str,     ACL_USE_L7REQ_VOLATILE, ARG1(0,STR) },
        { "cook_beg",        acl_parse_str,     smp_fetch_cookie,         acl_match_beg,     ACL_USE_L7REQ_VOLATILE, ARG1(0,STR) },
-       { "cook_cnt",        acl_parse_int,     acl_fetch_cookie_cnt,     acl_match_int,     ACL_USE_L7REQ_VOLATILE, ARG1(0,STR) },
+       { "cook_cnt",        acl_parse_int,     smp_fetch_cookie_cnt,     acl_match_int,     ACL_USE_L7REQ_VOLATILE, ARG1(0,STR) },
        { "cook_dir",        acl_parse_str,     smp_fetch_cookie,         acl_match_dir,     ACL_USE_L7REQ_VOLATILE, ARG1(0,STR) },
        { "cook_dom",        acl_parse_str,     smp_fetch_cookie,         acl_match_dom,     ACL_USE_L7REQ_VOLATILE, ARG1(0,STR) },
        { "cook_end",        acl_parse_str,     smp_fetch_cookie,         acl_match_end,     ACL_USE_L7REQ_VOLATILE, ARG1(0,STR) },
@@ -9525,11 +9554,12 @@ static struct acl_kw_list acl_kws = {{ },{
        { "hdr_sub",         acl_parse_str,     smp_fetch_hdr,            acl_match_sub,     ACL_USE_L7REQ_VOLATILE, ARG2(0,STR,SINT), val_hdr },
        { "hdr_val",         acl_parse_int,     smp_fetch_hdr_val,        acl_match_int,     ACL_USE_L7REQ_VOLATILE, ARG2(0,STR,SINT), val_hdr },
 
-       { "http_auth",       acl_parse_nothing, acl_fetch_http_auth,      acl_match_nothing, ACL_USE_L7REQ_VOLATILE, ARG1(0,USR) },
-       { "http_auth_group", acl_parse_strcat,  acl_fetch_http_auth_grp,  acl_match_auth,    ACL_USE_L7REQ_VOLATILE, ARG1(0,USR) },
-       { "http_first_req",  acl_parse_nothing, acl_fetch_http_first_req, acl_match_nothing, ACL_USE_L7REQ_PERMANENT, 0 },
+       { "http_auth",       acl_parse_nothing, smp_fetch_http_auth,      acl_match_nothing, ACL_USE_L7REQ_VOLATILE, ARG1(0,USR) },
+       { "http_auth_group", acl_parse_strcat,  smp_fetch_http_auth_grp,  acl_match_auth,    ACL_USE_L7REQ_VOLATILE, ARG1(1,USR) },
 
-       { "method",          acl_parse_meth,    acl_fetch_meth,           acl_match_meth,    ACL_USE_L7REQ_PERMANENT, 0 },
+       { "http_first_req",  acl_parse_nothing, smp_fetch_http_first_req, acl_match_nothing, ACL_USE_L7REQ_PERMANENT, 0 },
+
+       { "method",          acl_parse_meth,    smp_fetch_meth,           acl_match_meth,    ACL_USE_L7REQ_PERMANENT, 0 },
 
        { "path",            acl_parse_str,     smp_fetch_path,           acl_match_str,     ACL_USE_L7REQ_VOLATILE, 0 },
        { "path_beg",        acl_parse_str,     smp_fetch_path,           acl_match_beg,     ACL_USE_L7REQ_VOLATILE, 0 },
@@ -9540,13 +9570,13 @@ static struct acl_kw_list acl_kws = {{ },{
        { "path_reg",        acl_parse_reg,     smp_fetch_path,           acl_match_reg,     ACL_USE_L7REQ_VOLATILE, 0 },
        { "path_sub",        acl_parse_str,     smp_fetch_path,           acl_match_sub,     ACL_USE_L7REQ_VOLATILE, 0 },
 
-       { "req_proto_http",  acl_parse_nothing, acl_fetch_proto_http,     acl_match_nothing, ACL_USE_L7REQ_PERMANENT, 0 },
-       { "req_ver",         acl_parse_ver,     acl_fetch_rqver,          acl_match_str,     ACL_USE_L7REQ_VOLATILE, 0 },
-       { "resp_ver",        acl_parse_ver,     acl_fetch_stver,          acl_match_str,     ACL_USE_L7RTR_VOLATILE, 0 },
+       { "req_proto_http",  acl_parse_nothing, smp_fetch_proto_http,     acl_match_nothing, ACL_USE_L7REQ_PERMANENT, 0 },
+       { "req_ver",         acl_parse_ver,     smp_fetch_rqver,          acl_match_str,     ACL_USE_L7REQ_VOLATILE,  0 },
+       { "resp_ver",        acl_parse_ver,     smp_fetch_stver,          acl_match_str,     ACL_USE_L7RTR_VOLATILE,  0 },
 
        { "scook",           acl_parse_str,     smp_fetch_cookie,         acl_match_str,     ACL_USE_L7RTR_VOLATILE, ARG1(0,STR) },
        { "scook_beg",       acl_parse_str,     smp_fetch_cookie,         acl_match_beg,     ACL_USE_L7RTR_VOLATILE, ARG1(0,STR) },
-       { "scook_cnt",       acl_parse_int,     acl_fetch_cookie_cnt,     acl_match_int,     ACL_USE_L7RTR_VOLATILE, ARG1(0,STR) },
+       { "scook_cnt",       acl_parse_int,     smp_fetch_cookie_cnt,     acl_match_int,     ACL_USE_L7RTR_VOLATILE, ARG1(0,STR) },
        { "scook_dir",       acl_parse_str,     smp_fetch_cookie,         acl_match_dir,     ACL_USE_L7RTR_VOLATILE, ARG1(0,STR) },
        { "scook_dom",       acl_parse_str,     smp_fetch_cookie,         acl_match_dom,     ACL_USE_L7RTR_VOLATILE, ARG1(0,STR) },
        { "scook_end",       acl_parse_str,     smp_fetch_cookie,         acl_match_end,     ACL_USE_L7RTR_VOLATILE, ARG1(0,STR) },
@@ -9567,7 +9597,7 @@ static struct acl_kw_list acl_kws = {{ },{
        { "shdr_sub",        acl_parse_str,     smp_fetch_hdr,            acl_match_sub,     ACL_USE_L7RTR_VOLATILE, ARG2(0,STR,SINT), val_hdr },
        { "shdr_val",        acl_parse_int,     smp_fetch_hdr_val,        acl_match_int,     ACL_USE_L7RTR_VOLATILE, ARG2(0,STR,SINT), val_hdr },
 
-       { "status",          acl_parse_int,     acl_fetch_stcode,         acl_match_int,     ACL_USE_L7RTR_PERMANENT, 0 },
+       { "status",          acl_parse_int,     smp_fetch_stcode,         acl_match_int,     ACL_USE_L7RTR_PERMANENT, 0 },
 
        { "url",             acl_parse_str,     smp_fetch_url,            acl_match_str,     ACL_USE_L7REQ_VOLATILE, 0 },
        { "url_beg",         acl_parse_str,     smp_fetch_url,            acl_match_beg,     ACL_USE_L7REQ_VOLATILE, 0 },
@@ -9580,16 +9610,16 @@ static struct acl_kw_list acl_kws = {{ },{
        { "url_reg",         acl_parse_reg,     smp_fetch_url,            acl_match_reg,     ACL_USE_L7REQ_VOLATILE, 0 },
        { "url_sub",         acl_parse_str,     smp_fetch_url,            acl_match_sub,     ACL_USE_L7REQ_VOLATILE, 0 },
 
-       { "urlp",            acl_parse_str,     smp_fetch_url_param,      acl_match_str,     ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
-       { "urlp_beg",        acl_parse_str,     smp_fetch_url_param,      acl_match_beg,     ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
-       { "urlp_dir",        acl_parse_str,     smp_fetch_url_param,      acl_match_dir,     ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
-       { "urlp_dom",        acl_parse_str,     smp_fetch_url_param,      acl_match_dom,     ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
-       { "urlp_end",        acl_parse_str,     smp_fetch_url_param,      acl_match_end,     ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
-       { "urlp_ip",         acl_parse_ip,      smp_fetch_url_param,      acl_match_ip,      ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
-       { "urlp_len",        acl_parse_int,     smp_fetch_url_param,      acl_match_len,     ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
-       { "urlp_reg",        acl_parse_reg,     smp_fetch_url_param,      acl_match_reg,     ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
-       { "urlp_sub",        acl_parse_str,     smp_fetch_url_param,      acl_match_sub,     ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
-       { "urlp_val",        acl_parse_int,     smp_fetch_url_param_val,  acl_match_int,     ACL_USE_L7REQ_VOLATILE, ARG1(1,STR) },
+       { "urlp",            acl_parse_str,     smp_fetch_url_param,      acl_match_str,     ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
+       { "urlp_beg",        acl_parse_str,     smp_fetch_url_param,      acl_match_beg,     ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
+       { "urlp_dir",        acl_parse_str,     smp_fetch_url_param,      acl_match_dir,     ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
+       { "urlp_dom",        acl_parse_str,     smp_fetch_url_param,      acl_match_dom,     ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
+       { "urlp_end",        acl_parse_str,     smp_fetch_url_param,      acl_match_end,     ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
+       { "urlp_ip",         acl_parse_ip,      smp_fetch_url_param,      acl_match_ip,      ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
+       { "urlp_len",        acl_parse_int,     smp_fetch_url_param,      acl_match_len,     ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
+       { "urlp_reg",        acl_parse_reg,     smp_fetch_url_param,      acl_match_reg,     ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
+       { "urlp_sub",        acl_parse_str,     smp_fetch_url_param,      acl_match_sub,     ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
+       { "urlp_val",        acl_parse_int,     smp_fetch_url_param_val,  acl_match_int,     ACL_USE_L7REQ_VOLATILE, ARG2(1,STR,STR) },
 
        { NULL, NULL, NULL, NULL },
 }};
@@ -9599,18 +9629,57 @@ static struct acl_kw_list acl_kws = {{ },{
 /************************************************************************/
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
-       { "hdr",        smp_fetch_hdr,            ARG2(1,STR,SINT), val_hdr, SMP_T_CSTR, SMP_USE_HRQHV|SMP_USE_HRSHV },
-       { "base",       smp_fetch_base,           0,                NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
-       { "base32",     smp_fetch_base32,         0,                NULL,    SMP_T_UINT, SMP_USE_HRQHV },
-       { "base32+src", smp_fetch_base32_src,     0,                NULL,    SMP_T_BIN,  SMP_USE_HRQHV },
-       { "path",       smp_fetch_path,           0,                NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
-       { "url",        smp_fetch_url,            0,                NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
-       { "url_ip",     smp_fetch_url_ip,         0,                NULL,    SMP_T_IPV4, SMP_USE_HRQHV },
-       { "url_port",   smp_fetch_url_port,       0,                NULL,    SMP_T_UINT, SMP_USE_HRQHV },
-       { "url_param",  smp_fetch_url_param,      ARG2(1,STR,STR),  NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
-       { "cookie",     smp_fetch_cookie,         ARG1(1,STR),      NULL,    SMP_T_CSTR, SMP_USE_HRQHV|SMP_USE_HRSHV },
-       { "set-cookie", smp_fetch_cookie,         ARG1(1,STR),      NULL,    SMP_T_CSTR, SMP_USE_HRSHV }, /* deprecated */
-       { NULL, NULL, 0, 0, 0 },
+       { "base",            smp_fetch_base,           0,                NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
+       { "base32",          smp_fetch_base32,         0,                NULL,    SMP_T_UINT, SMP_USE_HRQHV },
+       { "base32+src",      smp_fetch_base32_src,     0,                NULL,    SMP_T_BIN,  SMP_USE_HRQHV },
+
+       /* cookie is valid in both directions (eg: for "stick ...") but cook*
+        * are only here to match the ACL's name, are request-only and are used
+        * for ACL compatibility only.
+        */
+       { "cook",            smp_fetch_cookie,         ARG1(0,STR),      NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
+       { "cookie",          smp_fetch_cookie,         ARG1(0,STR),      NULL,    SMP_T_CSTR, SMP_USE_HRQHV|SMP_USE_HRSHV },
+       { "cook_cnt",        smp_fetch_cookie_cnt,     ARG1(0,STR),      NULL,    SMP_T_UINT, SMP_USE_HRQHV },
+       { "cook_val",        smp_fetch_cookie_val,     ARG1(0,STR),      NULL,    SMP_T_UINT, SMP_USE_HRQHV },
+
+       /* hdr is valid in both directions (eg: for "stick ...") but hdr_* are
+        * only here to match the ACL's name, are request-only and are used for
+        * ACL compatibility only.
+        */
+       { "hdr",             smp_fetch_hdr,            ARG2(0,STR,SINT), val_hdr, SMP_T_CSTR, SMP_USE_HRQHV|SMP_USE_HRSHV },
+       { "hdr_cnt",         smp_fetch_hdr_cnt,        ARG1(0,STR),      NULL,    SMP_T_UINT, SMP_USE_HRQHV },
+       { "hdr_ip",          smp_fetch_hdr_ip,         ARG2(0,STR,SINT), val_hdr, SMP_T_IPV4, SMP_USE_HRQHV },
+       { "hdr_val",         smp_fetch_hdr_val,        ARG2(0,STR,SINT), val_hdr, SMP_T_UINT, SMP_USE_HRQHV },
+
+       { "http_auth",       smp_fetch_http_auth,      ARG1(1,USR),      val_usr, SMP_T_BOOL, SMP_USE_HRQHV },
+       { "http_auth_group", smp_fetch_http_auth_grp,  ARG1(1,USR),      val_usr, SMP_T_BOOL, SMP_USE_HRQHV },
+       { "http_first_req",  smp_fetch_http_first_req, 0,                NULL,    SMP_T_BOOL, SMP_USE_HRQHP },
+       { "method",          smp_fetch_meth,           0,                NULL,    SMP_T_UINT, SMP_USE_HRQHP },
+       { "path",            smp_fetch_path,           0,                NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
+       { "req_proto_http",  smp_fetch_proto_http,     0,                NULL,    SMP_T_BOOL, SMP_USE_HRQHP },
+       { "req_ver",         smp_fetch_rqver,          0,                NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
+       { "resp_ver",        smp_fetch_stver,          0,                NULL,    SMP_T_CSTR, SMP_USE_HRSHV },
+
+       /* scook is valid only on the response and is used for ACL compatibility */
+       { "scook",           smp_fetch_cookie,         ARG1(0,STR),      NULL,    SMP_T_CSTR, SMP_USE_HRSHV },
+       { "scook_cnt",       smp_fetch_cookie_cnt,     ARG1(0,STR),      NULL,    SMP_T_UINT, SMP_USE_HRSHV },
+       { "scook_val",       smp_fetch_cookie_val,     ARG1(0,STR),      NULL,    SMP_T_UINT, SMP_USE_HRSHV },
+       { "set-cookie",      smp_fetch_cookie,         ARG1(0,STR),      NULL,    SMP_T_CSTR, SMP_USE_HRSHV }, /* deprecated */
+
+       /* shdr is valid only on the response and is used for ACL compatibility */
+       { "shdr",            smp_fetch_hdr,            ARG2(0,STR,SINT), val_hdr, SMP_T_CSTR, SMP_USE_HRSHV },
+       { "shdr_cnt",        smp_fetch_hdr_cnt,        ARG1(0,STR),      NULL,    SMP_T_UINT, SMP_USE_HRSHV },
+       { "shdr_ip",         smp_fetch_hdr_ip,         ARG2(0,STR,SINT), val_hdr, SMP_T_IPV4, SMP_USE_HRSHV },
+       { "shdr_val",        smp_fetch_hdr_val,        ARG2(0,STR,SINT), val_hdr, SMP_T_UINT, SMP_USE_HRSHV },
+
+       { "status",          smp_fetch_stcode,         0,                NULL,    SMP_T_UINT, SMP_USE_HRSHP },
+       { "url",             smp_fetch_url,            0,                NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
+       { "url_ip",          smp_fetch_url_ip,         0,                NULL,    SMP_T_IPV4, SMP_USE_HRQHV },
+       { "url_port",        smp_fetch_url_port,       0,                NULL,    SMP_T_UINT, SMP_USE_HRQHV },
+       { "url_param",       smp_fetch_url_param,      ARG2(1,STR,STR),  NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
+       { "urlp"     ,       smp_fetch_url_param,      ARG2(1,STR,STR),  NULL,    SMP_T_CSTR, SMP_USE_HRQHV },
+       { "urlp_val",        smp_fetch_url_param_val,  ARG2(1,STR,STR),  NULL,    SMP_T_UINT, SMP_USE_HRQHV },
+       { /* END */ },
 }};