]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: fcgi-app: allow explicit filter declaration with non-cache/non-compression...
authorAustin Kauffman <akauffman@ne4u.com>
Sat, 15 Aug 2026 01:34:39 +0000 (18:34 -0700)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 26 Aug 2026 12:26:56 +0000 (14:26 +0200)
fcgi_flt_check() in src/fcgi-app.c unconditionally rejects any filter that
isn't compression, cache, or fcgi-app from coexisting with use-fcgi-app in
the same backend section, regardless of whether an explicit
`filter fcgi-app <name>` declaration is present. This contradicts the
documentation (section 9.5 of configuration.txt), which states that an
explicit `filter fcgi-app` declaration should allow other filters to
coexist.

The cache filter's equivalent check (cache_store_check in src/cache.c)
correctly uses a CACHE_FLT_F_IMPLICIT_DECL flag to only reject implicit
declarations when other filters are present. The fcgi-app check was missing
this flag, which appears to be an oversight.

This patch adds a FCGI_FLT_F_IMPLICIT_DECL flag to fcgi_flt_conf, mirroring
the cache filter's pattern:

  - The flag is set when use-fcgi-app creates an implicit filter
    (proxy_parse_use_fcgi_app).
  - The flag is cleared when filter fcgi-app explicitly declares the filter
    (parse_fcgi_flt), whether reusing an existing implicit config or
    creating a new one.
  - fcgi_flt_check only errors when the flag is set (i.e., the filter is
    implicit), matching cache_store_check's behavior.

This allows Lua-based filters (lua.resp_transform, lua.compress for
brotli/zstd) and other third-party filters to coexist with FastCGI backends
when an explicit `filter fcgi-app` declaration is present, as documented.

This should be backported to all versions that have the fcgi-app filter.

include/haproxy/fcgi-app-t.h
src/fcgi-app.c

index 56b95091d33bb955a1bb0780a89f3fbd5cf041ca..aaf218fe3078cd7b092edce3c136f820ba1c374d 100644 (file)
@@ -103,6 +103,7 @@ struct fcgi_app {
 struct fcgi_flt_conf {
        char *name;                  /* fcgi-app name used during config parsing */
        struct fcgi_app *app;        /* configuration of the fcgi application */
+       unsigned int flags;          /* FCGI_FLT_F_* */
 
        struct list param_rules;     /* list of set/unset rules */
        struct list hdr_rules;       /* list of pass/add rules  */
index efcfd98d834c7f678aa6471ed9d02045d105a79e..217594cd02190f6ffd91993bdf5c2d5a63353bad 100644 (file)
@@ -35,6 +35,11 @@ static struct fcgi_app *fcgi_apps = NULL;
 struct flt_ops fcgi_flt_ops;
 const char *fcgi_flt_id = "FCGI filter";
 
+/* The fcgi-app filter was implicitly declared (ie without the filter keyword,
+ * via use-fcgi-app).
+ */
+#define FCGI_FLT_F_IMPLICIT_DECL 0x00000001
+
 DECLARE_STATIC_TYPED_POOL(pool_head_fcgi_flt_ctx, "fcgi_flt_ctx", struct fcgi_flt_ctx);
 DECLARE_STATIC_TYPED_POOL(pool_head_fcgi_param_rule, "fcgi_param_rule", struct fcgi_param_rule);
 DECLARE_STATIC_TYPED_POOL(pool_head_fcgi_hdr_rule, "fcgi_hdr_rule", struct fcgi_hdr_rule);
@@ -229,9 +234,9 @@ static int fcgi_flt_check(struct proxy *px, struct flt_conf *fconf)
                                 px->id);
                        goto err;
                }
-               else if (f->id != fconf->id) {
+               else if ((f->id != fconf->id) && (fcgi_conf->flags & FCGI_FLT_F_IMPLICIT_DECL)) {
                        /* Implicit declaration is only allowed with the
-                        * compression and cache. For other filters, an implicit
+                        * compression and cache. For other filters, an explicit
                         * declaration is required. */
                        ha_alert("config: proxy '%s': require an explicit filter declaration "
                                 "to use the fcgi-app '%s'.\n", px->id, fcgi_conf->name);
@@ -542,6 +547,8 @@ parse_fcgi_flt(char **args, int *cur_arg, struct proxy *px,
                LIST_INIT(&fcgi_conf->hdr_rules);
        }
 
+       /* Explicit declaration: clear the implicit flag. */
+       fcgi_conf->flags &= ~FCGI_FLT_F_IMPLICIT_DECL;
        fconf->id   = fcgi_flt_id;
        fconf->conf = fcgi_conf;
        fconf->ops  = &fcgi_flt_ops;
@@ -596,6 +603,7 @@ static int proxy_parse_use_fcgi_app(char **args, int section, struct proxy *curp
                goto err;
        LIST_INIT(&fcgi_conf->param_rules);
        LIST_INIT(&fcgi_conf->hdr_rules);
+       fcgi_conf->flags = FCGI_FLT_F_IMPLICIT_DECL; /* implicit declaration */
 
        /* Register the filter */
        fconf = calloc(1, sizeof(*fconf));