extern struct filter_class flt_fcgi_cls;
#endif
+/* Parsing functions of the internal filter classes, called to finalize a
+ * filter instance (see "filter-config" directive)
+ */
+int trace_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+int cache_store_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+int http_comp_req_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+int http_comp_res_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+int decomp_req_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+int decomp_res_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+#if defined(USE_LUA)
+int hlua_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+#endif
+#if defined(USE_SPOE)
+int spoe_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+#endif
+int bwlim_in_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+int bwlim_out_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+#if defined(USE_FCGI)
+int fcgi_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err);
+#endif
+
#define FLT_ID(flt) (flt)->config->id
#define FLT_CONF(flt) (flt)->config->conf
#define FLT_OPS(flt) (flt)->config->ops
struct filter_class *filter_find_class(const char *name);
+/* Helper function for filter classes: calls the legacy "filter" keyword
+ * parsing function <parse> on the arguments of the filter instance <inst>,
+ * as if the line "filter <kw> <inst args...>" was found in the configuration
+ * of the proxy <px>. <private> is passed as-is to the parsing function.
+ * Returns 0 on success, < 0 on error.
+ */
+int flt_parse_instance_legacy(struct proxy *px, struct filter_instance *inst, char **err,
+ const char *kw,
+ int (*parse)(char **args, int *cur_arg, struct proxy *px,
+ struct flt_conf *fconf, char **err, void *private),
+ void *private);
+
int filter_register_class(struct filter_class *cls, const char *name,
int (*parse)(char **args, struct proxy *px,
struct filter_instance *inst, char **err));
return -1;
}
+/* Parse the arguments of a "cache-store" filter instance. The cache name is the
+ * instance id (the id is mandatory for this class, several instances are
+ * allowed), no argument is expected.
+ * Returns 0 on success, < 0 on error.
+ */
+int cache_store_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ struct cache_flt_conf *cconf;
+
+ if (!inst->id) {
+ memprintf(err, "'filter-config %s' : missing filter instance id",
+ cache_store_filter_cls_name);
+ return -1;
+ }
+ if (*args) {
+ memprintf(err, "'filter-config %s' : unexpected argument '%s'",
+ cache_store_filter_cls_name, args[0]);
+ return -1;
+ }
+
+ cconf = calloc(1, sizeof(*cconf));
+ if (!cconf) {
+ memprintf(err, "out of memory");
+ return -1;
+ }
+ cconf->c.name = strdup(inst->id);
+ if (!cconf->c.name) {
+ free(cconf);
+ memprintf(err, "out of memory");
+ return -1;
+ }
+
+ inst->fconf->id = cache_store_flt_id;
+ inst->fconf->conf = cconf;
+ inst->fconf->ops = &cache_ops;
+ return 0;
+}
+
/* It reserves a struct show_cache_ctx for the local variables */
static int cli_parse_show_cache(char **args, char *payload, struct appctx *appctx, void *private)
{
return -1;
}
+/* Parse the arguments of a "fcgi" filter instance. The fcgi-app name is the
+ * instance id, it must be set, and no argument is expected.
+ * Returns 0 on success, < 0 on error.
+ */
+int fcgi_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ struct fcgi_flt_conf *fcgi_conf;
+
+ if (!inst->id) {
+ memprintf(err, "'filter-config %s' : missing filter instance id, the fcgi-app name is expected",
+ fcgi_filter_cls_name);
+ return -1;
+ }
+ if (*args) {
+ memprintf(err, "'filter-config %s' : unexpected argument '%s'",
+ fcgi_filter_cls_name, args[0]);
+ return -1;
+ }
+
+ fcgi_conf = calloc(1, sizeof(*fcgi_conf));
+ if (!fcgi_conf) {
+ memprintf(err, "out of memory");
+ return -1;
+ }
+ fcgi_conf->name = strdup(inst->id);
+ if (!fcgi_conf->name) {
+ free(fcgi_conf);
+ memprintf(err, "out of memory");
+ return -1;
+ }
+ LIST_INIT(&fcgi_conf->param_rules);
+ LIST_INIT(&fcgi_conf->hdr_rules);
+
+ inst->fconf->id = fcgi_flt_id;
+ inst->fconf->conf = fcgi_conf;
+ inst->fconf->ops = &fcgi_flt_ops;
+ return 0;
+}
+
/* Parses the "use-fcgi-app" proxy keyword */
static int proxy_parse_use_fcgi_app(char **args, int section, struct proxy *curpx,
const struct proxy *defpx, const char *file, int line,
return -1;
}
+/* Helper function for filter classes: calls the legacy "filter" keyword
+ * parsing function <parse> on the arguments of the filter instance <inst>,
+ * as if the line "filter <kw> <inst args...>" was found in the configuration
+ * of the proxy <px>. <private> is passed as-is to the parsing function.
+ * Returns 0 on success, < 0 on error.
+ */
+int flt_parse_instance_legacy(struct proxy *px, struct filter_instance *inst, char **err,
+ const char *kw,
+ int (*parse)(char **args, int *cur_arg, struct proxy *px,
+ struct flt_conf *fconf, char **err, void *private),
+ void *private)
+{
+ char *fargs[MAX_LINE_ARGS+1];
+ int i, ret, cur_arg;
+
+ /* the legacy parsing functions expect the keyword at args[*cur_arg],
+ * followed by the filter arguments. Like for the config parser, the
+ * arguments must be terminated by an empty string, not a NULL pointer.
+ */
+
+ fargs[0] = (char *)kw;
+ for (i = 0; inst->conf.argv[i] && *inst->conf.argv[i]; i++)
+ fargs[i+1] = inst->conf.argv[i];
+ fargs[i+1] = "";
+
+ cur_arg = 0;
+ ret = parse(fargs, &cur_arg, px, inst->fconf, err, private);
+ if (ret == 0 && *fargs[cur_arg]) {
+ /* some arguments were not consumed by the parsing function */
+ memprintf(err, "'filter-config %s' : unknown keyword '%s'",
+ inst->class->name, fargs[cur_arg]);
+ ret = -1;
+ }
+ return ret;
+}
+
/* Registers a new filter class, with the parsing function <parse> used to
* finalize the filter instances of this class (may be NULL if the class does
* not support the "filter-config" directive). The class is initialized and
static void filter_init_classes(void)
{
/* TODO: the filter names must come from the filters (the filter id most probably) */
- flt_init_class(&flt_trace_cls, trace_filter_cls_name, FLT_CLS_FL_MULTI, NULL);
- flt_init_class(&flt_cache_store_cls, cache_store_filter_cls_name, FLT_CLS_FL_MULTI, NULL);
- flt_init_class(&flt_http_comp_req_cls, http_comp_req_filter_cls_name, 0, NULL);
- flt_init_class(&flt_http_comp_res_cls, http_comp_res_filter_cls_name, 0, NULL);
- flt_init_class(&flt_decomp_req_cls, decomp_req_filter_cls_name, 0, NULL);
- flt_init_class(&flt_decomp_res_cls, decomp_res_filter_cls_name, 0, NULL);
+ flt_init_class(&flt_trace_cls, trace_filter_cls_name, FLT_CLS_FL_MULTI, trace_flt_parse_instance);
+ flt_init_class(&flt_cache_store_cls, cache_store_filter_cls_name, FLT_CLS_FL_MULTI, cache_store_flt_parse_instance);
+ flt_init_class(&flt_http_comp_req_cls, http_comp_req_filter_cls_name, 0, http_comp_req_flt_parse_instance);
+ flt_init_class(&flt_http_comp_res_cls, http_comp_res_filter_cls_name, 0, http_comp_res_flt_parse_instance);
+ flt_init_class(&flt_decomp_req_cls, decomp_req_filter_cls_name, 0, decomp_req_flt_parse_instance);
+ flt_init_class(&flt_decomp_res_cls, decomp_res_filter_cls_name, 0, decomp_res_flt_parse_instance);
#if defined(USE_SPOE)
- flt_init_class(&flt_spoe_cls, spoe_filter_cls_name, FLT_CLS_FL_MULTI, NULL);
+ flt_init_class(&flt_spoe_cls, spoe_filter_cls_name, FLT_CLS_FL_MULTI, spoe_flt_parse_instance);
#endif
#if defined(USE_LUA)
- flt_init_class(&flt_lua_cls, hlua_filter_cls_name, FLT_CLS_FL_MULTI, NULL);
+ flt_init_class(&flt_lua_cls, hlua_filter_cls_name, FLT_CLS_FL_MULTI, hlua_flt_parse_instance);
#endif
- flt_init_class(&flt_bwlim_in_cls, bwlim_in_filter_cls_name, FLT_CLS_FL_MULTI, NULL);
- flt_init_class(&flt_bwlim_out_cls, bwlim_out_filter_cls_name, FLT_CLS_FL_MULTI, NULL);
+ flt_init_class(&flt_bwlim_in_cls, bwlim_in_filter_cls_name, FLT_CLS_FL_MULTI, bwlim_in_flt_parse_instance);
+ flt_init_class(&flt_bwlim_out_cls, bwlim_out_filter_cls_name, FLT_CLS_FL_MULTI, bwlim_out_flt_parse_instance);
#if defined(USE_FCGI)
- flt_init_class(&flt_fcgi_cls, fcgi_filter_cls_name, 0, NULL);
+ flt_init_class(&flt_fcgi_cls, fcgi_filter_cls_name, 0, fcgi_flt_parse_instance);
#endif
LIST_APPEND(&filter_classes, &flt_trace_cls.list);
return parse_bwlim_flt(args, cur_arg, px, fconf, err, private);
}
+static int bwlim_flt_parse_instance(const char *kw, char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ char *fargs[MAX_LINE_ARGS+1];
+ int i, ret, cur_arg;
+
+ fargs[0] = (char *)kw;
+ fargs[1] = (char *)inst->id;
+ for (i = 0; args[i] && *args[i]; i++)
+ fargs[i+2] = args[i];
+ fargs[i+2] = "";
+
+ cur_arg = 0;
+ ret = parse_bwlim_flt(fargs, &cur_arg, px, inst->fconf, err, NULL);
+ if (ret == 0 && *fargs[cur_arg]) {
+ memprintf(err, "'filter-config %s' : unknown keyword '%s'", inst->class->name, fargs[cur_arg]);
+ ret = -1;
+ }
+ return ret;
+}
+
+/* Parse the arguments of a "bwlim-in" filter instance. the bandwith limitation
+ * name is the instance id. It relies on bwlim_flt_parse_instance().
+ * Returns 0 on success, < 0 on error.
+ */
+int bwlim_in_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ if (flt_find_instance(px, &flt_bwlim_out_cls, inst->id)) {
+ memprintf(err, "bwlim filter '%s' already declared for proxy '%s'\n", inst->id, px->id);
+ return -1;
+ }
+
+ inst->fconf->id = bwlim_in_flt_id;
+ return bwlim_flt_parse_instance("bwlim-in", args, px, inst, err);
+}
+
+/* Parse the arguments of a "bwlim-out" filter instance. the bandwith limitation
+ * name is the instance id. It relies on bwlim_flt_parse_instance().
+ * Returns 0 on success, < 0 on error.
+ */
+int bwlim_out_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ if (flt_find_instance(px, &flt_bwlim_in_cls, inst->id)) {
+ memprintf(err, "bwlim filter '%s' already declared for proxy '%s'\n", inst->id, px->id);
+ return -1;
+ }
+
+ inst->fconf->id = bwlim_out_flt_id;
+ return bwlim_flt_parse_instance("bwlim-out", args, px, inst, err);
+}
+
/* Declare the filter parser for "trace" keyword */
static struct flt_kw_list flt_kws = { "BWLIM", { }, {
{ "bwlim-in", parse_bwlim_in_flt, NULL },
return 0;
}
+/* Parse the arguments of a "decomp-req" filter instance. No argument is
+ * expected.
+ * Returns 0 on success, < 0 on error.
+ */
+int decomp_req_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ struct decomp *decomp;
+
+ if (!(px->cap & PR_CAP_FE)) {
+ memprintf(err, "'decomp-req' filter not allowed because %s '%s' has no frontend capability\n",
+ proxy_type_str(px), px->id);
+ return -1;
+ }
+ if (*args) {
+ memprintf(err, "'filter-config %s' : unexpected argument '%s'",
+ decomp_req_filter_cls_name, args[0]);
+ return -1;
+ }
+
+ decomp = proxy_get_decomp(px, 0);
+ if (decomp == NULL) {
+ memprintf(err, "out of memory");
+ return -1;
+ }
+ decomp->flags |= DECOMP_FL_DIR_REQ;
+
+ inst->fconf->id = decomp_req_flt_id;
+ inst->fconf->conf = &decomp->req;
+ inst->fconf->ops = &decomp_req_ops;
+ return 0;
+}
+
+/* Parse the arguments of a "decomp-res" filter instance. No argument is
+ * expected.
+ * Returns 0 on success, < 0 on error.
+ */
+int decomp_res_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ struct decomp *decomp;
+
+ if (!(px->cap & PR_CAP_BE)) {
+ memprintf(err, "'decomp-res' filter not allowed because %s '%s' has no backend capability\n",
+ proxy_type_str(px), px->id);
+ return -1;
+ }
+ if (*args) {
+ memprintf(err, "'filter-config %s' : unexpected argument '%s'",
+ decomp_res_filter_cls_name, args[0]);
+ return -1;
+ }
+
+ decomp = proxy_get_decomp(px, 0);
+ if (decomp == NULL) {
+ memprintf(err, "out of memory");
+ return -1;
+ }
+ decomp->flags |= DECOMP_FL_DIR_RES;
+
+ inst->fconf->id = decomp_res_flt_id;
+ inst->fconf->conf = &decomp->res;
+ inst->fconf->ops = &decomp_res_ops;
+ return 0;
+}
+
int
check_implicit_decomp_flt(struct proxy *proxy)
{
return 0;
}
+/* Parse the arguments of a "http-comp-req" filter instance. No argument is
+ * expected.
+ * Returns 0 on success, < 0 on error.
+ */
+int http_comp_req_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ struct comp *comp;
+
+ if (*args) {
+ memprintf(err, "'filter-config %s' : unexpected argument '%s'",
+ http_comp_req_filter_cls_name, args[0]);
+ return -1;
+ }
+
+ comp = proxy_get_comp(px, 0);
+ if (comp == NULL) {
+ memprintf(err, "out of memory");
+ return -1;
+ }
+ /* Implicit instances mirror options; they must not restore a direction
+ * removed by a later option or a local defaults override.
+ */
+ if (!(inst->flags & FLT_INST_F_IMPLICIT))
+ comp->flags |= COMP_FL_DIR_REQ;
+
+ inst->fconf->id = http_comp_req_flt_id;
+ inst->fconf->conf = px->comp;
+ inst->fconf->ops = &comp_req_ops;
+ return 0;
+}
+
+/* Parse the arguments of a "http-comp-res" filter instance. No argument is
+ * expected.
+ * Returns 0 on success, < 0 on error.
+ */
+int http_comp_res_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ struct comp *comp;
+
+ if (*args) {
+ memprintf(err, "'filter-config %s' : unexpected argument '%s'",
+ http_comp_res_filter_cls_name, args[0]);
+ return -1;
+ }
+
+ comp = proxy_get_comp(px, 0);
+ if (comp == NULL) {
+ memprintf(err, "out of memory");
+ return -1;
+ }
+ if (!(inst->flags & FLT_INST_F_IMPLICIT))
+ comp->flags |= COMP_FL_DIR_RES;
+
+ inst->fconf->id = http_comp_res_flt_id;
+ inst->fconf->conf = px->comp;
+ inst->fconf->ops = &comp_res_ops;
+ return 0;
+}
+
int
check_implicit_http_comp_flt(struct proxy *proxy)
{
return -1;
}
+/* Parse the arguments of a "spoe" filter instance, relying on the legacy
+ * "filter" keyword parser.
+ * Returns 0 on success, < 0 on error.
+ */
+int spoe_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ struct proxy *old_curproxy = curproxy;
+ int ret;
+
+ curproxy = px;
+ ret = flt_parse_instance_legacy(px, inst, err, "spoe", parse_spoe_flt, NULL);
+ curproxy = old_curproxy;
+ return ret;
+}
+
/* Send message of a SPOE group. This is the action_ptr callback of a rule
* associated to a "send-spoe-group" action.
*
return -1;
}
+/* Parse the arguments of a "trace" filter instance (see "filter-config"
+ * directive), relying on the legacy "filter" keyword parser.
+ * Returns 0 on success, < 0 on error.
+ */
+int trace_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ char *fargs[MAX_LINE_ARGS+1];
+ int i, ret, cur_arg;
+
+ fargs[0] = "trace";
+ fargs[1] = "name";
+ fargs[2] = (char *)inst->id;
+ for (i = 0; args[i] && *args[i]; i++)
+ fargs[i+3] = args[i];
+ fargs[i+3] = "";
+
+ cur_arg = 0;
+ ret = parse_trace_flt(fargs, &cur_arg, px, inst->fconf, err, NULL);
+ if (ret == 0 && *fargs[cur_arg]) {
+ memprintf(err, "'filter-config %s' : unknown keyword '%s'", inst->class->name, fargs[cur_arg]);
+ ret = -1;
+ }
+ return ret;
+}
+
/* Declare the filter parser for "trace" keyword */
static struct flt_kw_list flt_kws = { "TRACE", { }, {
{ "trace", parse_trace_flt, NULL },
return -1;
}
+/* Parse the arguments of a "lua" filter instance. The lua filter name is the
+ * instance id, as declared with core.register_filter() in a lua script (the id
+ * is mandatory for this class, several instances are allowed). The instance
+ * arguments are passed to the lua filter, relying on the legacy "filter"
+ * keyword parser.
+ * Returns 0 on success, < 0 on error.
+ */
+int hlua_flt_parse_instance(char **args, struct proxy *px, struct filter_instance *inst, char **err)
+{
+ struct flt_kw *kw;
+ char *kw_name = NULL;
+ int ret;
+
+ if (!inst->id) {
+ memprintf(err, "'%s' : missing filter instance id", hlua_filter_cls_name);
+ return -1;
+ }
+
+ kw_name = memprintf(&kw_name, "lua.%s", inst->id);
+ if (!kw_name) {
+ memprintf(err, "out of memory");
+ return -1;
+ }
+ kw = flt_find_kw(kw_name);
+ if (!kw || !kw->parse) {
+ memprintf(err, "unknown lua filter '%s'", inst->id);
+ free(kw_name);
+ return -1;
+ }
+
+ ret = flt_parse_instance_legacy(px, inst, err, kw_name, kw->parse, kw->private);
+
+ free(kw_name);
+ return ret;
+}
+
__LJMP static int hlua_register_data_filter(lua_State *L)
{
struct filter *filter;