From: Christopher Faulet Date: Tue, 29 Sep 2026 13:51:49 +0000 (+0200) Subject: BUG/MINOR: flt-http-comp: Enable implicit filters independently per direction X-Git-Tag: v3.5-dev9~98 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=878fe6dd86eddae5a578f845e1a92ffdf10fbf23;p=haproxy.git BUG/MINOR: flt-http-comp: Enable implicit filters independently per direction 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. --- diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c index f5c6ca134..c90c23206 100644 --- a/src/flt_http_comp.c +++ b/src/flt_http_comp.c @@ -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; } /*