]> git.kaiwu.me - haproxy.git/commitdiff
DOC: filters: document the automatic ordering of the legacy core filters
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 19 Oct 2026 12:57:53 +0000 (14:57 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 20 Oct 2026 09:13:30 +0000 (11:13 +0200)
The default evaluation orders of the filters are now documented in the
configuration manual, next to the "filter-config" documentation, for both
filter modes: the default placement of the built-in classes in the new
mode, and the automatic placement of the implicitly declared core filters
in the legacy mode, as introduced by the automatic ordering. For each
mode, the three orders are given: the global one, used for the
side-independent operations, and the request and response ones, used for
the evaluation order of the filters on the corresponding channel.

The "decompression" directives no longer recommend declaring the
decompression filters explicitly to prevent misconfigurations: when
implicitly enabled in the legacy filter mode, the decompression filter is
automatically placed at the beginning of the filter list, before the
cache and compression filters.

Both modes' orders are explicitly informational only: they describe the
current placement and they may be changed by the build options or by a
future version. Only the placements explicitly requested by a filter, and
the position of an implicitly declared legacy filter relative to the
explicitly declared ones, should be relied upon.

The filter API internals documentation explains the structural part of
the automatic ordering in legacy mode (the filter config links and the
proxy lists holding the three orders, the segment boundaries of the
explicitly declared filters) and refers to the configuration manual for
the resulting orders, as it already does for the class orders of the new
mode.

doc/configuration.txt
doc/internals/api/filters.txt

index e79376453c5ba215267a9738489ca4227b58738d..a2f0e56fdc574ddba3177e4ddbfaa12dade7e714 100644 (file)
@@ -7571,10 +7571,10 @@ decompression algo-req <algorithms> ...
 decompression algo-res <algorithms> ...
   Configures the decompression algorithms supported by the proxy.  It will
   implicitly enable decompression filter ("decomp-req" or "decomp-res" whether
-  the decompression option targets request, response) automatically. However to
-  prevent misconfiguration, it is recommended to explicitly declare filters
-  when multiple filters are involved on the proxy, because filters are
-  evaluated in their declaration order.
+  the decompression option targets request, response) automatically. When
+  implicitly enabled in the legacy filter mode, the decompression filter is
+  automatically placed at the beginning of the filter list, before the cache
+  and compression filters.
 
   May be used in the following contexts: http, tcp
 
@@ -7679,9 +7679,9 @@ decompression mode-res { none | auto | always }
   When decompression is set to a mode other than "none" in a direction, the
   associated decompression filter is automatically enabled. For requests, the
   filter is called "decomp-req", and for responses, the filter is "decomp-res".
-  In order to prevent misconfigurations, particularly when combining multiple
-  filters, it is highly recommended to explicitly declare the filters, because
-  they are evaluated in their declaration order.
+  When implicitly enabled in the legacy filter mode, the decompression filter
+  is automatically placed at the beginning of the filter list, before the
+  cache and compression filters.
 
   Mode "auto", which is only available for HTTP, means haproxy will try to find
   a compatible algorithms in algo-req or algo-res list to be able to decompress
@@ -31521,8 +31521,13 @@ A filter is declared on a proxy in one of two modes:
 
   * The legacy mode relies on the "filter" directive. Each "filter" line
     declares an independent filter configuration and the declaration order
-    defines the evaluation order. This mode is kept for backward
-    compatibility.
+    defines the evaluation order. However, the filters implicitly declared
+    by other directives (the decompression options, the compression options,
+    the "cache-store" rules and "use-fcgi-app") are automatically ordered,
+    independently on each direction, and an explicitly declared filter is
+    never moved: it keeps its declared position and the implicitly declared
+    ones are ordered inside the segments it delimits (see the default orders
+    below). This mode is kept for backward compatibility.
 
   * The new mode relies on the "filter-config" directive. Each declaration is
     a filter instance, attached to its filter class. The evaluation order is
@@ -31530,16 +31535,50 @@ A filter is declared on a proxy in one of two modes:
     "filter-sequence" directive. The instances are disabled by default and
     are activated with the "enabled" token or the "filter-enable" directive.
 
-Each filter class is placed in three independent orders: a global one, used
-for the side-independent operations (configuration checks, initialization and
+For each mode, three orders exist: a global one, used for the
+side-independent operations (configuration checks, initialization and
 destruction), and a request and a response one, used for the evaluation order
-of the instances on the corresponding channel. The request and the response
-orders are independent, so a class may be evaluated at a different position
+of the filters on the corresponding channel. The request and the response
+orders are independent, so a filter may be evaluated at a different position
 depending on the direction, and the global order may be changed without
 affecting them. The resulting orders of a proxy may be inspected with the
 "show filter classes" CLI command, and the "show filter instances" one reports
 the resulting order of the instances.
 
+The default orders are informational only: they describe the current placement
+of the classes and of the implicitly declared filters, and they may be changed
+by the build options or by a future version. Only the placements explicitly
+requested by a filter, and the position of an implicitly declared legacy filter
+relative to the explicitly declared ones, should be relied upon.
+
+In the new mode, the orders follow the class placement, which can be adjusted
+per proxy with the "filter-sequence" directive. The built-in classes are
+placed, when no explicit placement is requested, as follows:
+
+  * global order: trace > decomp-req > decomp-res > cache-store > spoe >
+    lua > http-comp-req > http-comp-res > bwlim-in > bwlim-out > fcgi
+
+  * request order: trace > decomp-req > lua > spoe > http-comp-res >
+    decomp-res > http-comp-req > bwlim-in > fcgi
+
+  * response order: fcgi > trace > decomp-res > cache-store > spoe > lua >
+    http-comp-res > decomp-req > bwlim-out
+
+In the legacy mode, the automatically ordered filters are the implicit core
+filters: the decompression filters, the cache filters, the compression
+filters and the fcgi filter. They are placed, when implicitly declared, as
+follows, where "any other filter" stands for the explicitly declared filters
+and the other legacy filters in their declaration order:
+
+  * global order: decomp-req > decomp-res > cache-store > any other filter >
+    http-comp-req > http-comp-res > fcgi
+
+  * request order: decomp-req > any other filter > http-comp-res > decomp-res >
+    http-comp-req > fcgi
+
+  * response order: fcgi > decomp-res > cache-store > any other filter >
+    decomp-req > http-comp-res
+
 The mode is selected by the configuration itself: as soon as a legacy "filter"
 directive is used in a proxy, the proxy works in legacy mode and the
 "filter-*" directives must not be used in the same proxy, including when they
index 55522b7e42fb984e5ccc532855b4ed5448b1614a..e9592cd1135484675229f016ef0b29e17b965e7a 100644 (file)
@@ -370,6 +370,22 @@ the field 'filter_configs' of the 'proxy' structure, each one of type
 separately and the core builds the evaluation orders from them, but a filter
 still only deals with 'struct flt_conf' once its filter instance is finalized.
 
+In legacy mode, the implicitly declared core filters (the decompression,
+compression, cache and fcgi filters) are automatically ordered by the core,
+instead of relying on the user to declare them in a valid position. Three
+independent orders are maintained with the 'list', 'by_req' and 'by_res' links
+of the filter configurations, respectively stored in 'px->filter_configs',
+'px->filters_req_configs' and 'px->filters_res_configs'. Explicitly declared
+core filters are never moved and act as segment boundaries: implicitly
+declared filters are sorted inside the segment they appear in, so they never
+cross an explicitly declared one. The stream's request and response filter
+lists are filled with the request and response orders respectively. The
+resulting default orders, for both the legacy and the new mode, are documented
+in the configuration manual, next to the "filter-config" documentation. Like
+any default order, they are informational only: only the position of an
+implicitly declared filter relative to the explicitly declared ones is
+guaranteed.
+
     /*
      * Structure representing the filter configuration, attached to a proxy and
      * accessible from a filter when instantiated in a stream
@@ -1603,7 +1619,8 @@ The following helpers work in both modes and must be used for that purpose :
     configurations of the proxy, in the evaluation order of the given side
     (FLT_SIDE_GLOBAL, FLT_SIDE_REQ or FLT_SIDE_RES). The '<fct>' callback is
     called with each 'struct flt_conf *' and must return 0 to continue. In
-    legacy mode, the declaration order is used.
+    legacy mode, the global order is the reordered declaration order and the
+    request and response orders are filled from it (see below).
 
   * 'flt_find_conf(px, flt_id, side, match, data)' returns the first filter
     configuration matching the id '<flt_id>' (any id if NULL) and the optional
@@ -1969,7 +1986,16 @@ enabled by another directive, or is referenced by other directives.
     not assume a fixed order relative to other filters unless it owns the
     corresponding placements or sequences.
 
-    In legacy mode, the declaration order of the "filter" directives is used.
+    In legacy mode, the declaration order of the "filter" directives is used
+    for the explicitly declared filters, and the implicitly declared core
+    filters are automatically ordered (see section 3.1).
+
+    For both modes, the default orders of the built-in filters are
+    informational only and may be changed by the build options or by a future
+    version: only the placements explicitly requested by a filter, and the
+    position of an implicitly declared legacy filter relative to the
+    explicitly declared ones, should be relied upon. They are listed in the
+    configuration manual, next to the "filter-config" documentation.
 
 5.6. Can a filter instance be shared between proxies?