int flt_copy_instances(struct proxy *px, const struct proxy *defpx);
void flt_free_instances(struct proxy *px);
int flt_init_class_refs(struct proxy *px);
+int flt_add_implicit_instance(struct proxy *px, struct filter_class *cls, const char *id,
+ char **args, const char *file, int line);
struct filter_instance *flt_find_instance(struct proxy *px, struct filter_class *cls, const char *id);
int flt_stream_start(struct stream *s);
static int parse_cache_rule(struct proxy *proxy, const char *name, struct act_rule *rule, char **err)
{
+ struct filter_class *cls;
struct flt_conf *fconf;
struct cache_flt_conf *cconf = NULL;
fconf->id = cache_store_flt_id;
fconf->conf = cconf;
fconf->ops = &cache_ops;
+
+ /* also create the corresponding implicit filter instance. The cache
+ * name is used as the instance id, there is no argument.
+ */
+ cls = filter_find_class(cache_store_filter_cls_name);
+ if (!cls || flt_add_implicit_instance(proxy, cls, name, NULL,
+ rule->conf.file ? rule->conf.file : proxy->conf.file,
+ rule->conf.file ? rule->conf.line : proxy->conf.line) < 0) {
+ memprintf(err, "out of memory\n");
+ free(fconf);
+ goto err;
+ }
+
LIST_APPEND(&proxy->filter_configs, &fconf->list);
rule->arg.act.p[0] = cconf;
if (f->id == http_comp_req_flt_id || f->id == http_comp_res_flt_id ||
f->id == cache_store_flt_id)
continue;
- else if ((f->id == fconf->id) && f->conf != fcgi_conf) {
+ else if ((f->id == fconf->id) && f->conf != fcgi_conf &&
+ strcmp(((struct fcgi_flt_conf *)f->conf)->name, fcgi_conf->name) != 0) {
+ /* another fcgi filter with a different app */
ha_alert("proxy '%s' : only one fcgi-app supported per backend.\n",
px->id);
goto err;
const struct proxy *defpx, const char *file, int line,
char **err)
{
+ struct filter_class *cls;
struct flt_conf *fconf = NULL;
struct fcgi_flt_conf *fcgi_conf = NULL;
int retval = 0;
fconf->id = fcgi_flt_id;
fconf->conf = fcgi_conf;
fconf->ops = &fcgi_flt_ops;
+
+ /* also create the corresponding implicit filter instance. The
+ * fcgi-app name is used as the instance id, there is no argument.
+ */
+ cls = filter_find_class(fcgi_filter_cls_name);
+ if (!cls || flt_add_implicit_instance(curpx, cls, args[1], NULL, file, line) < 0) {
+ free(fconf);
+ goto err;
+ }
+
LIST_APPEND(&curpx->filter_configs, &fconf->list);
end:
* proxy <px>, so that proxies inherit the filter instances of their
* defaults section. It must be called before any instance is added to <px>,
* so that locally defined ones can replace the inherited ones.
- * Returns 0 on success, -1 on error (out of memory).
+ * Returns 0 on success, -1 on error.
*/
static int flt_copy_instance(struct proxy *px, const struct filter_instance *inst)
{
return -1;
}
+/* Adds an implicit filter instance for the class <cls> to the proxy <px>,
+ * with the id <id> (may be NULL) and the arguments <args> (terminated by an
+ * empty string). It is used when a filter is implicitly configured by
+ * another directive (e.g. with the cache-store action). The instance is
+ * marked with FLT_INST_F_IMPLICIT and is enabled, since the directive
+ * implies the filter usage.
+ *
+ * If a instance with the same class and id already exists, nothing is
+ * done: an explicit declaration always wins over an implicit one, and the
+ * first implicit declaration wins. Returns 0 on success, -1 on error (out
+ * of memory).
+ */
+int flt_add_implicit_instance(struct proxy *px, struct filter_class *cls, const char *id,
+ char **args, const char *file, int line)
+{
+ struct filter_instance *inst;
+ int argc = 0;
+ int i;
+
+ /* a instance already exists for this class and id: explicit or
+ * implicit, it wins over a new implicit one.
+ */
+ if (flt_find_instance(px, cls, id))
+ return 0;
+
+ inst = calloc(1, sizeof(*inst));
+ if (!inst)
+ return -1;
+
+ inst->class = cls;
+ inst->enabled = 1; /* the directive implies the filter usage */
+ inst->flags = FLT_INST_F_IMPLICIT;
+
+ if (id) {
+ inst->id = strdup(id);
+ if (!inst->id)
+ goto error;
+ }
+ inst->conf.file = strdup(file);
+ if (!inst->conf.file)
+ goto error;
+ inst->conf.line = line;
+
+ for (argc = 0; args && *args[argc]; argc++)
+ ;
+ inst->conf.argc = argc;
+ inst->conf.argv = calloc(argc + 1, sizeof(*inst->conf.argv));
+ if (!inst->conf.argv)
+ goto error;
+ for (i = 0; i < argc; i++) {
+ inst->conf.argv[i] = strdup(args[i]);
+ if (!inst->conf.argv[i])
+ goto error;
+ }
+
+ if (flt_init_instance(inst, px) < 0)
+ goto error;
+ return 0;
+
+ error:
+ flt_free_instance(inst);
+ return -1;
+}
+
/*
* Parses the "filter-config" keyword. A filter instance is created for the
* given filter class and attached to the current proxy. The instance
goto end;
}
+ if (decomp->req.algos) {
+ struct filter_class *cls;
+
+ cls = filter_find_class(decomp_req_filter_cls_name);
+ if (!cls || flt_add_implicit_instance(proxy, cls, NULL, NULL, file, line) < 0) {
+ memprintf(err, "'%s' : out of memory.", args[0]);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ if (decomp->res.algos) {
+ struct filter_class *cls;
+
+ cls = filter_find_class(decomp_res_filter_cls_name);
+ if (!cls || flt_add_implicit_instance(proxy, cls, NULL, NULL, file, line) < 0) {
+ memprintf(err, "'%s' : out of memory.", args[0]);
+ ret = -1;
+ goto end;
+ }
+ }
+
end:
return ret;
}
int
check_implicit_decomp_flt(struct proxy *proxy)
{
+ struct filter_class *cls;
struct flt_conf *fconf;
struct flt_conf *fconf_req = NULL;
struct flt_conf *fconf_res = NULL;
goto end;
}
+ if (comp->flags & COMP_FL_DIR_REQ) {
+ struct filter_class *cls;
+
+ /* also create the corresponding implicit filter instance.
+ * There is no id nor argument.
+ */
+ cls = filter_find_class(http_comp_req_filter_cls_name);
+ if (!cls || flt_add_implicit_instance(proxy, cls, NULL, NULL, file, line) < 0) {
+ memprintf(err, "'%s' : out of memory.", args[0]);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ if (comp->flags & COMP_FL_DIR_RES) {
+ struct filter_class *cls;
+
+ /* also create the corresponding implicit filter instance.
+ * There is no id nor argument.
+ */
+ cls = filter_find_class(http_comp_res_filter_cls_name);
+ if (!cls || flt_add_implicit_instance(proxy, cls, NULL, NULL, file, line) < 0) {
+ memprintf(err, "'%s' : out of memory.", args[0]);
+ ret = -1;
+ goto end;
+ }
+ }
+
end:
return ret;
}