7. Using ACLs and pattern extraction
------------------------------------

The use of Access Control Lists (ACL) provides a flexible solution to perform
content switching and generally to take decisions based on content extracted
from the request, the response or any environmental status. The principle is
simple :

  - define test criteria with sets of values
  - perform actions only if a set of tests is valid

The actions generally consist in blocking the request, or selecting a backend.

In order to define a test, the "acl" keyword is used. The syntax is :

   acl <aclname> <criterion> [flags] [operator] <value> ...

This creates a new ACL <aclname> or completes an existing one with new tests.
Those tests apply to the portion of request/response specified in <criterion>
and may be adjusted with optional flags [flags]. Some criteria also support
an operator which may be specified before the set of values. The values are
of the type supported by the criterion, and are separated by spaces.

ACL names must be formed from upper and lower case letters, digits, '-' (dash),
'_' (underscore) , '.' (dot) and ':' (colon). ACL names are case-sensitive,
which means that "my_acl" and "My_Acl" are two different ACLs.

There is no enforced limit to the number of ACLs. The unused ones do not affect
performance, they just consume a small amount of memory.

The following ACL flags are currently supported :

   -i : ignore case during matching of all subsequent patterns.
   -f : load patterns from a file.
   -- : force end of flags. Useful when a string looks like one of the flags.

The "-f" flag is special as it loads all of the lines it finds in the file
specified in argument and loads all of them before continuing. It is even
possible to pass multiple "-f" arguments if the patterns are to be loaded from
multiple files. Empty lines as well as lines beginning with a sharp ('#') will
be ignored. All leading spaces and tabs will be stripped. If it is absolutely
needed to insert a valid pattern beginning with a sharp, just prefix it with a
space so that it is not taken for a comment. Depending on the data type and
match method, haproxy may load the lines into a binary tree, allowing very fast
lookups. This is true for IPv4 and exact string matching. In this case,
duplicates will automatically be removed. Also, note that the "-i" flag applies
to subsequent entries and not to entries loaded from files preceeding it. For
instance :

    acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst  test

In this example, each line of "exact-ua.lst" will be exactly matched against
the "user-agent" header of the request. Then each line of "generic-ua" will be
case-insensitively matched. Then the word "test" will be insensitively matched
too.

Note that right now it is difficult for the ACL parsers to report errors, so if
a file is unreadable or unparsable, the most you'll get is a parse error in the
ACL. Thus, file-based ACLs should only be produced by reliable processes.

Supported types of values are :

  - integers or integer ranges
  - strings
  - regular expressions
  - IP addresses and networks



7.1. Matching integers
----------------------

Matching integers is special in that ranges and operators are permitted. Note
that integer matching only applies to positive values. A range is a value
expressed with a lower and an upper bound separated with a colon, both of which
may be omitted.

For instance, "1024:65535" is a valid range to represent a range of
unprivileged ports, and "1024:" would also work. "0:1023" is a valid
representation of privileged ports, and ":1023" would also work.

As a special case, some ACL functions support decimal numbers which are in fact
two integers separated by a dot. This is used with some version checks for
instance. All integer properties apply to those decimal numbers, including
ranges and operators.

For an easier usage, comparison operators are also supported. Note that using
operators with ranges does not make much sense and is strongly discouraged.
Similarly, it does not make much sense to perform order comparisons with a set
of values.

Available operators for integer matching are :

  eq : true if the tested value equals at least one value
  ge : true if the tested value is greater than or equal to at least one value
  gt : true if the tested value is greater than at least one value
  le : true if the tested value is less than or equal to at least one value
  lt : true if the tested value is less than at least one value

For instance, the following ACL matches any negative Content-Length header :

  acl negative-length hdr_val(content-length) lt 0

This one matches SSL versions between 3.0 and 3.1 (inclusive) :

  acl sslv3 req_ssl_ver 3:3.1



7.2. Matching strings
---------------------

String matching applies to verbatim strings as they are passed, with the
exception of the backslash ("\") which makes it possible to escape some
characters such as the space. If the "-i" flag is passed before the first
string, then the matching will be performed ignoring the case. In order
to match the string "-i", either set it second, or pass the "--" flag
before the first string. Same applies of course to match the string "--".



7.3. Matching regular expressions (regexes)
-------------------------------------------

Just like with string matching, regex matching applies to verbatim strings as
they are passed, with the exception of the backslash ("\") which makes it
possible to escape some characters such as the space. If the "-i" flag is
passed before the first regex, then the matching will be performed ignoring
the case. In order to match the string "-i", either set it second, or pass
the "--" flag before the first string. Same principle applies of course to
match the string "--".



7.4. Matching IPv4 addresses
----------------------------

IPv4 addresses values can be specified either as plain addresses or with a
netmask appended, in which case the IPv4 address matches whenever it is
within the network. Plain addresses may also be replaced with a resolvable
host name, but this practice is generally discouraged as it makes it more
difficult to read and debug configurations. If hostnames are used, you should
at least ensure that they are present in /etc/hosts so that the configuration
does not depend on any random DNS match at the moment the configuration is
parsed.



7.5. Available matching criteria
--------------------------------


7.5.1. Matching at Layer 4 and below
------------------------------------

A first set of criteria applies to information which does not require any
analysis of the request or response contents. Those generally include TCP/IP
addresses and ports, as well as internal values independant on the stream.

always_false
  This one never matches. All values and flags are ignored. It may be used as
  a temporary replacement for another one when adjusting configurations.

always_true
  This one always matches. All values and flags are ignored. It may be used as
  a temporary replacement for another one when adjusting configurations.

avg_queue <integer>
avg_queue(backend) <integer>
  Returns the total number of queued connections of the designated backend
  divided by the number of active servers. This is very similar to "queue"
  except that the size of the farm is considered, in order to give a more
  accurate measurement of the time it may take for a new connection to be
  processed. The main usage is to return a sorry page to new users when it
  becomes certain they will get a degraded service. Note that in the event
  there would not be any active server anymore, we would consider twice the
  number of queued connections as the measured value. This is a fair estimate,
  as we expect one server to get back soon anyway, but we still prefer to send
  new traffic to another backend if in better shape. See also the "queue",
  "be_conn", and "be_sess_rate" criteria.

be_conn <integer>
be_conn(backend) <integer>
  Applies to the number of currently established connections on the backend,
  possibly including the connection being evaluated. If no backend name is
  specified, the current one is used. But it is also possible to check another
  backend. It can be used to use a specific farm when the nominal one is full.
  See also the "fe_conn", "queue" and "be_sess_rate" criteria.

be_sess_rate <integer>
be_sess_rate(backend) <integer>
  Returns true when the sessions creation rate on the backend matches the
  specified values or ranges, in number of new sessions per second. This is
  used to switch to an alternate backend when an expensive or fragile one
  reaches too high a session rate, or to limit abuse of service (eg. prevent
  sucking of an online dictionary).

  Example :
        # Redirect to an error page if the dictionary is requested too often
        backend dynamic
            mode http
            acl being_scanned be_sess_rate gt 100
            redirect location /denied.html if being_scanned

connslots <integer>
connslots(backend) <integer>
  The basic idea here is to be able to measure the number of connection "slots"
  still available (connection + queue), so that anything beyond that (intended
  usage; see "use_backend" keyword) can be redirected to a different backend.

  'connslots' = number of available server connection slots, + number of
  available server queue slots.

  Note that while "fe_conn" may be used, "connslots" comes in especially
  useful when you have a case of traffic going to one single ip, splitting into
  multiple backends (perhaps using acls to do name-based load balancing) and
  you want to be able to differentiate between different backends, and their
  available "connslots".  Also, whereas "nbsrv" only measures servers that are
  actually *down*, this acl is more fine-grained and looks into the number of
  available connection slots as well. See also "queue" and "avg_queue".

  OTHER CAVEATS AND NOTES: at this point in time, the code does not take care
  of dynamic connections. Also, if any of the server maxconn, or maxqueue is 0,
  then this acl clearly does not make sense, in which case the value returned
  will be -1.

dst <ip_address>
  Applies to the local IPv4 address the client connected to. It can be used to
  switch to a different backend for some alternative addresses.

dst_conn <integer>
  Applies to the number of currently established connections on the same socket
  including the one being evaluated. It can be used to either return a sorry
  page before hard-blocking, or to use a specific backend to drain new requests
  when the socket is considered saturated. This offers the ability to assign
  different limits to different listening ports or addresses. See also the
  "fe_conn" and "be_conn" criteria.

dst_port <integer>
  Applies to the local port the client connected to. It can be used to switch
  to a different backend for some alternative ports.

fe_conn <integer>
fe_conn(frontend) <integer>
  Applies to the number of currently established connections on the frontend,
  possibly including the connection being evaluated. If no frontend name is
  specified, the current one is used. But it is also possible to check another
  frontend. It can be used to either return a sorry page before hard-blocking,
  or to use a specific backend to drain new requests when the farm is
  considered saturated. See also the "dst_conn", "be_conn" and "fe_sess_rate"
  criteria.

fe_id <integer>
  Applies to the frontend's id. Can be used in backends to check from which
  frontend it was called.

fe_sess_rate <integer>
fe_sess_rate(frontend) <integer>
  Returns true when the session creation rate on the current or the named
  frontend matches the specified values or ranges, expressed in new sessions
  per second. This is used to limit the connection rate to acceptable ranges in
  order to prevent abuse of service at the earliest moment. This can be
  combined with layer 4 ACLs in order to force the clients to wait a bit for
  the rate to go down below the limit.

  Example :
        # This frontend limits incoming mails to 10/s with a max of 100
        # concurrent connections. We accept any connection below 10/s, and
        # force excess clients to wait for 100 ms. Since clients are limited to
        # 100 max, there cannot be more than 10 incoming mails per second.
        frontend mail
            bind :25
            mode tcp
            maxconn 100
            acl too_fast fe_sess_rate ge 10
            tcp-request inspect-delay 100ms
            tcp-request content accept if ! too_fast
            tcp-request content accept if WAIT_END

nbsrv <integer>
nbsrv(backend) <integer>
  Returns true when the number of usable servers of either the current backend
  or the named backend matches the values or ranges specified. This is used to
  switch to an alternate backend when the number of servers is too low to
  to handle some load. It is useful to report a failure when combined with
  "monitor fail".

queue <integer>
queue(backend) <integer>
  Returns the total number of queued connections of the designated backend,
  including all the connections in server queues. If no backend name is
  specified, the current one is used, but it is also possible to check another
  one. This can be used to take actions when queuing goes above a known level,
  generally indicating a surge of traffic or a massive slowdown on the servers.
  One possible action could be to reject new users but still accept old ones.
  See also the "avg_queue", "be_conn", and "be_sess_rate" criteria.

so_id <integer>
  Applies to the socket's id. Useful in frontends with many bind keywords.

src <ip_address>
  Applies to the client's IPv4 address. It is usually used to limit access to
  certain resources such as statistics. Note that it is the TCP-level source
  address which is used, and not the address of a client behind a proxy.

src_port <integer>
  Applies to the client's TCP source port. This has a very limited usage.

srv_is_up(<server>)
srv_is_up(<backend>/<server>)
  Returns true when the designated server is UP, and false when it is either
  DOWN or in maintenance mode. If <backend> is omitted, then the server is
  looked up in the current backend. The function takes no arguments since it
  is used as a boolean. It is mainly used to take action based on an external
  status reported via a health check (eg: a geographical site's availability).
  Another possible use which is more of a hack consists in using dummy servers
  as boolean variables that can be enabled or disabled from the CLI, so that
  rules depending on those ACLs can be tweaked in realtime.



7.5.2. Matching contents at Layer 4
-----------------------------------

A second set of criteria depends on data found in buffers, but which can change
during analysis. This requires that some data has been buffered, for instance
through TCP request content inspection. Please see the "tcp-request" keyword
for more detailed information on the subject.

req_len <integer>
  Returns true when the length of the data in the request buffer matches the
  specified range. 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 request content inspection.

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 can be used for instance
  to direct HTTP traffic to a given port and HTTPS traffic to another one
  using TCP request content inspection rules.

req_rdp_cookie       <string>
req_rdp_cookie(name) <string>
  Returns true when data in the request buffer look like the RDP protocol, and
  a cookie is present and equal to <string>. By default, any cookie name is
  checked, but a specific cookie name can be specified in parenthesis. The
  parser only checks for the first cookie, as illustrated in the RDP protocol
  specification. The cookie name is case insensitive. This ACL can be useful
  with the "MSTS" cookie, as it can contain the user name of the client
  connecting to the server if properly configured on the client. This can be
  used to restrict access to certain servers to certain users.

req_rdp_cookie_cnt       <integer>
req_rdp_cookie_cnt(name) <integer>
  Returns true when the data in the request buffer look like the RDP protocol
  and the number of RDP cookies matches the specified range (typically zero or
  one). Optionally a specific cookie name can be checked. This is a simple way
  of detecting the RDP protocol, as clients generally send the MSTS or MSTSHASH
  cookies.

req_ssl_ver <decimal>
  Returns true when data in the request buffer look like SSL, with a protocol
  version matching the specified range. Both SSLv2 hello messages and SSLv3
  messages are supported. The test tries to be strict enough to avoid being
  easily fooled. In particular, it waits for as many bytes as announced in the
  message header if this header looks valid (bound to the buffer size). Note
  that TLSv1 is announced as SSL version 3.1. This test was designed to be used
  with TCP request content inspection.

wait_end
  Waits for the end of the analysis period to return true. This may be used in
  conjunction with content analysis to avoid returning a wrong verdict early.
  It may also be used to delay some actions, such as a delayed reject for some
  special addresses. Since it either stops the rules evaluation or immediately
  returns true, it is recommended to use this acl as the last one in a rule.
  Please note that the default ACL "WAIT_END" is always usable without prior
  declaration. This test was designed to be used with TCP request content
  inspection.

  Examples :
     # delay every incoming request by 2 seconds
     tcp-request inspect-delay 2s
     tcp-request content accept if WAIT_END

     # don't immediately tell bad guys they are rejected
     tcp-request inspect-delay 10s
     acl goodguys src 10.0.0.0/24
     acl badguys  src 10.0.1.0/24
     tcp-request content accept if goodguys
     tcp-request content reject if badguys WAIT_END
     tcp-request content reject



7.5.3. Matching at Layer 7
--------------------------

A third set of criteria applies to information which can be found at the
application layer (layer 7). Those require that a full HTTP request has been
read, and are only evaluated then. They may require slightly more CPU resources
than the layer 4 ones, but not much since the request and response are indexed.

hdr <string>
hdr(header) <string>
  Note: all the "hdr*" matching criteria either apply to all headers, or to a
  particular header whose name is passed between parenthesis and without any
  space. The header name is not case-sensitive. The header matching complies
  with RFC2616, and treats as separate headers all values delimited by commas.
  Use the shdr() variant for response headers sent by the server.

  The "hdr" criteria returns true if any of the headers matching the criteria
  match any of the strings. This can be used to check exact for values. For
  instance, checking that "connection: close" is set :

     hdr(Connection) -i close

hdr_beg <string>
hdr_beg(header) <string>
  Returns true when one of the headers begins with one of the strings. See
  "hdr" for more information on header matching. Use the shdr_beg() variant for
  response headers sent by the server.

hdr_cnt <integer>
hdr_cnt(header) <integer>
  Returns true when the number of occurrence of the specified header matches
  the values or ranges specified. It is important to remember that one header
  line may count as several headers if it has several values. This is used to
  detect presence, absence or abuse of a specific header, as well as to block
  request smuggling attacks by rejecting requests which contain more than one
  of certain headers. See "hdr" for more information on header matching. Use
  the shdr_cnt() variant for response headers sent by the server.

hdr_dir <string>
hdr_dir(header) <string>
  Returns true when one of the headers contains one of the strings either
  isolated or delimited by slashes. This is used to perform filename or
  directory name matching, and may be used with Referer. See "hdr" for more
  information on header matching. Use the shdr_dir() variant for response
  headers sent by the server.

hdr_dom <string>
hdr_dom(header) <string>
  Returns true when one of the headers contains one of the strings either
  isolated or delimited by dots. This is used to perform domain name matching,
  and may be used with the Host header. See "hdr" for more information on
  header matching. Use the shdr_dom() variant for response headers sent by the
  server.

hdr_end <string>
hdr_end(header) <string>
  Returns true when one of the headers ends with one of the strings. See "hdr"
  for more information on header matching. Use the shdr_end() variant for
  response headers sent by the server.

hdr_ip <ip_address>
hdr_ip(header) <ip_address>
  Returns true when one of the headers' values contains an IP address matching
  <ip_address>. This is mainly used with headers such as X-Forwarded-For or
  X-Client-IP. See "hdr" for more information on header matching. Use the
  shdr_ip() variant for response headers sent by the server.

hdr_reg <regex>
hdr_reg(header) <regex>
  Returns true when one of the headers matches of the regular expressions. It
  can be used at any time, but it is important to remember that regex matching
  is slower than other methods. See also other "hdr_" criteria, as well as
  "hdr" for more information on header matching. Use the shdr_reg() variant for
  response headers sent by the server.

hdr_sub <string>
hdr_sub(header) <string>
  Returns true when one of the headers contains one of the strings. See "hdr"
  for more information on header matching. Use the shdr_sub() variant for
  response headers sent by the server.

hdr_val <integer>
hdr_val(header) <integer>
  Returns true when one of the headers starts with a number which matches the
  values or ranges specified. This may be used to limit content-length to
  acceptable values for example. See "hdr" for more information on header
  matching. Use the shdr_val() variant for response headers sent by the server.

http_auth(userlist)
http_auth_group(userlist) <group> [<group>]*
  Returns true when authentication data received from the client matches
  username &password stored on the userlist. It is also possible to
  use http_auth_group to check if the user is assigned to at least one
  of specified groups.

  Currently only http basic auth is supported.

http_req_first
  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 even to perform
  some specific ACL checks only on the first request.

method <string>
  Applies to the method in the HTTP request, eg: "GET". Some predefined ACL
  already check for most common methods.

path <string>
  Returns true when the path part of the request, which starts at the first
  slash and ends before the question mark, equals one of the strings. It may be
  used to match known files, such as /favicon.ico.

path_beg <string>
  Returns true when the path begins with one of the strings. This can be used
  to send certain directory names to alternative backends.

path_dir <string>
  Returns true when one of the strings is found isolated or delimited with
  slashes in the path. This is used to perform filename or directory name
  matching without the risk of wrong match due to colliding prefixes. See also
  "url_dir" and "path_sub".

path_dom <string>
  Returns true when one of the strings is found isolated or delimited with dots
  in the path. This may be used to perform domain name matching in proxy
  requests. See also "path_sub" and "url_dom".

path_end <string>
  Returns true when the path ends with one of the strings. This may be used to
  control file name extension.

path_reg <regex>
  Returns true when the path matches one of the regular expressions. It can be
  used any time, but it is important to remember that regex matching is slower
  than other methods. See also "url_reg" and all "path_" criteria.

path_sub <string>
  Returns true when the path contains one of the strings. It can be used to
  detect particular patterns in paths, such as "../" for example. See also
  "path_dir".

req_ver <string>
  Applies to the version string in the HTTP request, eg: "1.0". Some predefined
  ACL already check for versions 1.0 and 1.1.

status <integer>
  Applies to the HTTP status code in the HTTP response, eg: "302". It can be
  used to act on responses depending on status ranges, for instance, remove
  any Location header if the response is not a 3xx.

url <string>
  Applies to the whole URL passed in the request. The only real use is to match
  "*", for which there already is a predefined ACL.

url_beg <string>
  Returns true when the URL begins with one of the strings. This can be used to
  check whether a URL begins with a slash or with a protocol scheme.

url_dir <string>
  Returns true when one of the strings is found isolated or delimited with
  slashes in the URL. This is used to perform filename or directory name
  matching without the risk of wrong match due to colliding prefixes. See also
  "path_dir" and "url_sub".

url_dom <string>
  Returns true when one of the strings is found isolated or delimited with dots
  in the URL. This is used to perform domain name matching without the risk of
  wrong match due to colliding prefixes. See also "url_sub".

url_end <string>
  Returns true when the URL ends with one of the strings. It has very limited
  use. "path_end" should be used instead for filename matching.

url_ip <ip_address>
  Applies to the IP address specified in the absolute URI in an HTTP request.
  It can be used to prevent access to certain resources such as local network.
  It is useful with option "http_proxy".

url_port <integer>
  Applies to the port specified in the absolute URI in an HTTP request. It can
  be used to prevent access to certain resources. It is useful with option
  "http_proxy". Note that if the port is not specified in the request, port 80
  is assumed.

url_reg <regex>
  Returns true when the URL matches one of the regular expressions. It can be
  used any time, but it is important to remember that regex matching is slower
  than other methods. See also "path_reg" and all "url_" criteria.

url_sub <string>
  Returns true when the URL contains one of the strings. It can be used to
  detect particular patterns in query strings for example. See also "path_sub".



7.6. Pre-defined ACLs
---------------------

Some predefined ACLs are hard-coded so that they do not have to be declared in
every frontend which needs them. They all have their names in upper case in
order to avoid confusion. Their equivalence is provided below.

ACL name          Equivalent to                Usage
---------------+-----------------------------+---------------------------------
FALSE            always_false                  never match
HTTP             req_proto_http                match if protocol is valid HTTP
HTTP_1.0         req_ver 1.0                   match HTTP version 1.0
HTTP_1.1         req_ver 1.1                   match HTTP version 1.1
HTTP_CONTENT     hdr_val(content-length) gt 0  match an existing content-length
HTTP_URL_ABS     url_reg ^[^/:]*://            match absolute URL with scheme
HTTP_URL_SLASH   url_beg /                     match URL beginning with "/"
HTTP_URL_STAR    url     *                     match URL equal to "*"
LOCALHOST        src 127.0.0.1/8               match connection from local host
METH_CONNECT     method  CONNECT               match HTTP CONNECT method
METH_GET         method  GET HEAD              match HTTP GET or HEAD method
METH_HEAD        method  HEAD                  match HTTP HEAD method
METH_OPTIONS     method  OPTIONS               match HTTP OPTIONS method
METH_POST        method  POST                  match HTTP POST method
METH_TRACE       method  TRACE                 match HTTP TRACE method
RDP_COOKIE       req_rdp_cookie_cnt gt 0       match presence of an RDP cookie
REQ_CONTENT      req_len gt 0                  match data in the request buffer
TRUE             always_true                   always match
WAIT_END         wait_end                      wait for end of content analysis
---------------+-----------------------------+---------------------------------



7.7. Using ACLs to form conditions
----------------------------------

Some actions are only performed upon a valid condition. A condition is a
combination of ACLs with operators. 3 operators are supported :

  - AND (implicit)
  - OR  (explicit with the "or" keyword or the "||" operator)
  - Negation with the exclamation mark ("!")

A condition is formed as a disjunctive form:

   [!]acl1 [!]acl2 ... [!]acln  { or [!]acl1 [!]acl2 ... [!]acln } ...

Such conditions are generally used after an "if" or "unless" statement,
indicating when the condition will trigger the action.

For instance, to block HTTP requests to the "*" URL with methods other than
"OPTIONS", as well as POST requests without content-length, and GET or HEAD
requests with a content-length greater than 0, and finally every request which
is not either GET/HEAD/POST/OPTIONS !

   acl missing_cl hdr_cnt(Content-length) eq 0
   block if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl
   block if METH_GET HTTP_CONTENT
   block unless METH_GET or METH_POST or METH_OPTIONS

To select a different backend for requests to static contents on the "www" site
and to every request on the "img", "video", "download" and "ftp" hosts :

   acl url_static  path_beg         /static /images /img /css
   acl url_static  path_end         .gif .png .jpg .css .js
   acl host_www    hdr_beg(host) -i www
   acl host_static hdr_beg(host) -i img. video. download. ftp.

   # now use backend "static" for all static-only hosts, and for static urls
   # of host "www". Use backend "www" for the rest.
   use_backend static if host_static or host_www url_static
   use_backend www    if host_www

It is also possible to form rules using "anonymous ACLs". Those are unnamed ACL
expressions that are built on the fly without needing to be declared. They must
be enclosed between braces, with a space before and after each brace (because
the braces must be seen as independant words). Example :

   The following rule :

       acl missing_cl hdr_cnt(Content-length) eq 0
       block if METH_POST missing_cl

   Can also be written that way :

       block if METH_POST { hdr_cnt(Content-length) eq 0 }

It is generally not recommended to use this construct because it's a lot easier
to leave errors in the configuration when written that way. However, for very
simple rules matching only one source IP address for instance, it can make more
sense to use them than to declare ACLs with random names. Another example of
good use is the following :

   With named ACLs :

        acl site_dead nbsrv(dynamic) lt 2
        acl site_dead nbsrv(static)  lt 2
        monitor fail  if site_dead

   With anonymous ACLs :

        monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }

See section 4.2 for detailed help on the "block" and "use_backend" keywords.



7.8. Pattern extraction
-----------------------

The stickiness features relies on pattern extraction in the request and
response. Sometimes the data needs to be converted first before being stored,
for instance converted from ASCII to IP or upper case to lower case.

All these operations of data extraction and conversion are defined as
"pattern extraction rules". A pattern rule always has the same format. It
begins with a single pattern fetch word, potentially followed by a list of
arguments within parenthesis then an optional list of transformations. As
much as possible, the pattern fetch functions use the same name as their
equivalent used in ACLs.

The list of currently supported pattern fetch functions is the following :

  src          This is the source IPv4 address of the client of the session.
               It is of type IP and only works with such tables.

  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
               typie IP and only works with such tables.

  dst_port     This is the destination TCP port of the session on the client
               side, which is the port the client connected to. This might be
               used when running in transparent mode or when assigning dynamic
               ports to some clients for a whole application session. It is of
               type integer and only works with such tables.

  hdr(name)    This extracts the last occurrence of header <name> in an HTTP
               request and converts it to an IP address. This IP address is
               then used to match the table. A typical use is with the
               x-forwarded-for header.


The currently available list of transformations include :

  lower        Convert a string pattern to lower case. This can only be placed
               after a string pattern fetch function or after a conversion
               function returning a string type. The result is of type string.

  upper        Convert a string pattern to upper case. This can only be placed
               after a string pattern fetch function or after a conversion
               function returning a string type. The result is of type string.

  ipmask(mask) Apply a mask to an IPv4 address, and use the result for lookups
               and storage. This can be used to make all hosts within a
               certain mask to share the same table entries and as such use
               the same server. The mask can be passed in dotted form (eg:
               255.255.255.0) or in CIDR form (eg: 24).