]> git.kaiwu.me - haproxy.git/commitdiff
MEDIUM: filters: implicitly enable "decomp-req" and "decomp-res" when decompression...
authorAurelien DARRAGON <adarragon@haproxy.com>
Thu, 20 Aug 2026 17:49:58 +0000 (19:49 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 28 Aug 2026 15:26:38 +0000 (17:26 +0200)
If the "decomp-req" and/or "decomp-res" filters are not declared
explicitly but decompression options are set for them, then we
detect that the options relevant for one or the other were set and
we enable the filter automatically. This eases the configuration for
users who forget to declare the relevant decompression filters, as
we already do for compression ones.

However, when multiple filters are involved on a single proxy, it is
highly recommended to declare filters explicitly in order to avoid
surprises and this way it is easier to control in which order they
are executed. See also "filter-sequence" to help control executing
order.

doc/configuration.txt
include/haproxy/flt_decomp.h [new file with mode: 0644]
src/filters.c
src/flt_decomp.c
src/flt_http_comp.c

index 94e9ae506c8564ae1e9f50bef50c191aa5bdb191..ae5f44ccc93e8cc9c7a3599d43d39c537aa3565a 100644 (file)
@@ -7404,11 +7404,11 @@ declare capture [ request | response ] len <length>
 
 decompression algo-req <algorithms> ...
 decompression algo-res <algorithms> ...
-
-  Configures the decompression algorithms supported by the proxy.
-  It does not enable decompression filters ("decomp-req" and "decomp-res")
-  automatically, relevant decompression filters must be enabled explicitly
-  on the proxy, else decompression options will simply be ignored.
+  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. See also "filter-sequence".
 
   May be used in the following contexts: http, tcp
 
diff --git a/include/haproxy/flt_decomp.h b/include/haproxy/flt_decomp.h
new file mode 100644 (file)
index 0000000..8007819
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * include/haproxy/flt_decomp.h
+ * This file defines function prototypes for the decompression filters.
+ *
+ * Copyright 2026 HAProxy Technologies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef _HAPROXY_FLT_DECOMP_H
+#define _HAPROXY_FLT_DECOMP_H
+
+#include <haproxy/proxy-t.h>
+
+int check_implicit_decomp_flt(struct proxy *proxy);
+
+#endif // _HAPROXY_FLT_DECOMP_H
index bcb311c70ded4d8ca0f9c91b1ed7662f94f3c760..f118fd0cd803fa837f2a0ffb7dfc435afb3d8904 100644 (file)
@@ -16,6 +16,7 @@
 #include <haproxy/compression.h>
 #include <haproxy/errors.h>
 #include <haproxy/filters.h>
+#include <haproxy/flt_decomp.h>
 #include <haproxy/flt_http_comp.h>
 #include <haproxy/http_ana.h>
 #include <haproxy/http_htx.h>
@@ -515,6 +516,7 @@ flt_check(struct proxy *proxy)
        struct flt_conf *fconf;
        int err = 0;
 
+       err += check_implicit_decomp_flt(proxy);
        err += check_implicit_http_comp_flt(proxy);
        list_for_each_entry(fconf, &proxy->filter_configs, list) {
                if (fconf->ops->check)
index 11d02557b27bb3ea26a0d06bb8df0f7d3b929846..76e3f6bfb1475dfde6156652682641488b45e7dd 100644 (file)
@@ -1279,6 +1279,89 @@ parse_decomp_res_flt(char **args, int *cur_arg, struct proxy *px,
        return 0;
 }
 
+int
+check_implicit_decomp_flt(struct proxy *proxy)
+{
+       struct flt_conf *fconf;
+       struct flt_conf *fconf_req = NULL;
+       struct flt_conf *fconf_res = NULL;
+       int explicit = 0;
+       int err = 0;
+
+       if (proxy->decomp == NULL)
+               goto end;
+
+       if (!LIST_ISEMPTY(&proxy->filter_configs)) {
+               list_for_each_entry(fconf, &proxy->filter_configs, list) {
+                       if ((proxy->cap & PR_CAP_FE) && fconf->id == decomp_req_flt_id)
+                               fconf_req = fconf;
+                       else if ((proxy->cap & PR_CAP_BE) && fconf->id == decomp_res_flt_id)
+                               fconf_res = fconf;
+                       else if (fconf->id == cache_store_flt_id) {
+                               if (((proxy->cap & PR_CAP_FE) && !fconf_req) || ((proxy->cap & PR_CAP_BE) && !fconf_res)) {
+                                       ha_alert("config: %s '%s': cache filter declared before a decompression filter is invalid.\n",
+                                                proxy_type_str(proxy), proxy->id);
+                                       err++;
+                                       goto end;
+                               }
+                       }
+                       else if (fconf->id == http_comp_req_flt_id || fconf->id == http_comp_res_flt_id)
+                               continue;
+#if defined(USE_FCGI)
+                       else if (fconf->id == fcgi_flt_id)
+                               continue;
+#endif
+                       else
+                               explicit = 1;
+               }
+       }
+
+       if ((proxy->cap & PR_CAP_FE) && proxy->decomp->req.algos && !fconf_req) {
+               if (explicit) {
+                       ha_alert("config: %s '%s': require an explicit 'filter decomp-req' declaration to use "
+                                "decompression.\n", proxy_type_str(proxy), proxy->id);
+                       err++;
+                       goto end;
+               }
+               /* Implicit declaration of the decomp-req filter should be at
+                * the beginning of the filter list.
+                */
+               fconf_req = calloc(1, sizeof(*fconf));
+               if (!fconf_req)
+                       goto out_of_memory;
+               fconf_req->id   = decomp_req_flt_id;
+               fconf_req->conf = &proxy->decomp->req;
+               fconf_req->ops  = &decomp_req_ops;
+               LIST_INSERT(&proxy->filter_configs, &fconf_req->list);
+       }
+       if ((proxy->cap & PR_CAP_BE) && proxy->decomp->res.algos && !fconf_res) {
+               if (explicit) {
+                       ha_alert("config: %s '%s': require an explicit 'filter decomp-res' declaration to use "
+                                "decompression.\n", proxy_type_str(proxy), proxy->id);
+                       err++;
+                       goto end;
+               }
+               /* Implicit declaration of the decomp-res filter should be at
+                * the beginning of the filter list.
+                */
+               fconf_res = calloc(1, sizeof(*fconf));
+               if (!fconf_res)
+                       goto out_of_memory;
+               fconf_res->id   = decomp_res_flt_id;
+               fconf_res->conf = &proxy->decomp->res;
+               fconf_res->ops  = &decomp_res_ops;
+               LIST_INSERT(&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;
+}
+
+
 /* Declare the config parser for "decompression" keyword */
 static struct cfg_kw_list cfg_kws = {ILH, {
                { CFG_LISTEN, "decompression", parse_decompression_options },
index 42d934816565134b5da4088b6f251a33d8ee1180..ed0b83f24c72d400081d1390731afdab8272fc11 100644 (file)
@@ -1161,6 +1161,8 @@ check_implicit_http_comp_flt(struct proxy *proxy)
                                        goto end;
                                }
                        }
+                       else if (fconf->id == decomp_req_flt_id || fconf->id == decomp_res_flt_id)
+                               continue;
 #if defined(USE_FCGI)
                        else if (fconf->id == fcgi_flt_id)
                                continue;