]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: flt-http-comp: Enable implicit filters independently per direction
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 29 Sep 2026 13:51:49 +0000 (15:51 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 9 Oct 2026 14:17:35 +0000 (16:17 +0200)
Since the compression filter was split into comp-req and comp-res,
check_implicit_http_comp_flt() still treated either explicit declaration as
sufficient to suppress all implicit compression filters. Otherwise it always
added both filters, regardless of the configured directions.

Thus, explicitly placing the request filter could prevent response
compression from being enabled, and conversely. An explicit declaration must
only fix that filter's position, not disable the other direction selected by
compression directives.

Track the two filters separately and append each missing filter when its
direction is enabled. Preserve existing explicit positions and continue to
require explicit placement of missing filters when another filter makes
their ordering ambiguous. Only the response compression filter is forbidden
before a cache filter; request compression does not affect the cached
response.

Do not require a local algorithm when adding an implicit filter. Direction
flags are combined across the frontend and backend, and the algorithm may be
supplied by the opposite proxy. The runtime checks still prevent any
compression when no algorithm is available for the selected direction.

This patch relies on following commits:

  * MINOR: flt-http-comp: Use compression options as filter config
  * MEDIUM: flt-http-comp: Enable compression directions from algorithms

The series should be backported to 3.4.

src/flt_http_comp.c

index f5c6ca13425f257352697b3a98fe834cfd3867d5..c90c232064b629010faa142a99839124de3e5b63 100644 (file)
@@ -1140,18 +1140,19 @@ check_implicit_http_comp_flt(struct proxy *proxy)
        struct flt_conf *fconf_req = NULL;
        struct flt_conf *fconf_res = NULL;
        int explicit = 0;
-       int comp = 0;
        int err = 0;
 
        if (proxy->comp == NULL)
                goto end;
        if (!LIST_ISEMPTY(&proxy->filter_configs)) {
                list_for_each_entry(fconf, &proxy->filter_configs, list) {
-                       if (fconf->id == http_comp_req_flt_id || fconf->id == http_comp_res_flt_id)
-                               comp = 1;
+                       if (fconf->id == http_comp_req_flt_id)
+                               fconf_req = fconf;
+                       else if (fconf->id == http_comp_res_flt_id)
+                               fconf_res = fconf;
                        else if (fconf->id == cache_store_flt_id) {
-                               if (comp) {
-                                       ha_alert("config: %s '%s': unable to enable the compression filter "
+                               if (fconf_res) {
+                                       ha_alert("config: %s '%s': unable to enable the compression filter on response "
                                                 "before any cache filter.\n",
                                                 proxy_type_str(proxy), proxy->id);
                                        err++;
@@ -1168,38 +1169,47 @@ check_implicit_http_comp_flt(struct proxy *proxy)
                                explicit = 1;
                }
        }
-       if (comp)
-               goto end;
-       else if (explicit) {
-               ha_alert("config: %s '%s': require an explicit filter declaration to use "
-                        "HTTP compression\n", proxy_type_str(proxy), proxy->id);
-               err++;
-               goto end;
+       if ((proxy->comp->flags & COMP_FL_DIR_REQ) && !fconf_req) {
+               if (explicit) {
+                       ha_alert("config: %s '%s': require an explicit filter declaration to use "
+                                "HTTP request compression\n", proxy_type_str(proxy), proxy->id);
+                       err++;
+                       goto end;
+               }
+               /* Implicit declaration of the request compression filter is always the last
+                * one */
+               fconf_req = calloc(1, sizeof(*fconf));
+               if (!fconf_req)
+                       goto out_of_memory;
+               fconf_req->id   = http_comp_req_flt_id;
+               fconf_req->conf = proxy->comp;
+               fconf_req->ops  = &comp_req_ops;
+               LIST_APPEND(&proxy->filter_configs, &fconf_req->list);
        }
-
-       /* Implicit declaration of the compression filter is always the last
-        * one */
-       fconf_req = calloc(1, sizeof(*fconf));
-       fconf_res = calloc(1, sizeof(*fconf));
-       if (!fconf_req || !fconf_res) {
-               ha_alert("config: %s '%s': out of memory\n",
-                        proxy_type_str(proxy), proxy->id);
-               ha_free(&fconf_req);
-               ha_free(&fconf_res);
-               err++;
-               goto end;
+       if ((proxy->comp->flags & COMP_FL_DIR_RES) && !fconf_res) {
+               if (explicit) {
+                       ha_alert("config: %s '%s': require an explicit filter declaration to use "
+                                "HTTP response compression\n", proxy_type_str(proxy), proxy->id);
+                       err++;
+                       goto end;
+               }
+               /* Implicit declaration of the response compression filter is always the last
+                * one */
+               fconf_res = calloc(1, sizeof(*fconf));
+               if (!fconf_res)
+                       goto out_of_memory;
+               fconf_res->id   = http_comp_res_flt_id;
+               fconf_res->conf = proxy->comp;
+               fconf_res->ops  = &comp_res_ops;
+               LIST_APPEND(&proxy->filter_configs, &fconf_res->list);
        }
-       fconf_req->id   = http_comp_req_flt_id;
-       fconf_req->conf = proxy->comp;
-       fconf_req->ops  = &comp_req_ops;
-       LIST_APPEND(&proxy->filter_configs, &fconf_req->list);
-
-       fconf_res->id   = http_comp_res_flt_id;
-       fconf_res->conf = proxy->comp;
-       fconf_res->ops  = &comp_res_ops;
-       LIST_APPEND(&proxy->filter_configs, &fconf_res->list);
  end:
        return err;
+
+ out_of_memory:
+       ha_alert("config: %s '%s': out of memory\n", proxy_type_str(proxy), proxy->id);
+       err++;
+       goto end;
 }
 
 /*