static const char *add_filter(cmd_parms *cmd, void *CFG, const char *fname, const char *pname, const char *expr, const char **types) { mod_filter_cfg *cfg = CFG; ap_filter_provider_t *provider; const char *c; ap_filter_rec_t* frec; ap_filter_rec_t* provider_frec; ap_expr_info_t *node; const char *err = NULL; /* fname has been declared with DeclareFilter, so we can look it up */ frec = apr_hash_get(cfg->live_filters, fname, APR_HASH_KEY_STRING); /* or if provider is mod_filter itself, we can also look it up */ if (!frec) { c = filter_declare(cmd, CFG, fname, NULL); if ( c ) { return c; } frec = apr_hash_get(cfg->live_filters, fname, APR_HASH_KEY_STRING); } if (!frec) { return apr_psprintf(cmd->pool, "Undeclared smart filter %s", fname); } /* if provider has been registered, we can look it up */ provider_frec = ap_get_output_filter_handle(pname); if (!provider_frec) { return apr_psprintf(cmd->pool, "Unknown filter provider %s", pname); } provider = apr_palloc(cmd->pool, sizeof(ap_filter_provider_t)); if (expr) { node = ap_expr_parse_cmd(cmd, expr, 0, &err, NULL); if (err) { return apr_pstrcat(cmd->pool, "Error parsing FilterProvider expression:", err, NULL); } provider->expr = node; provider->types = NULL; } else { provider->types = types; provider->expr = NULL; } provider->frec = provider_frec; provider->next = frec->providers; frec->providers = provider; return NULL; }
static int lua_ap_add_output_filter(lua_State *L) { request_rec *r = CHECK_REQUEST_OBJECT(1); const char* filterName = luaL_checkstring(L, 2); ap_filter_rec_t *filter = ap_get_output_filter_handle(filterName); if (filter) { ap_add_output_filter_handle(filter, NULL, r, r->connection); lua_pushboolean(L, 1); } else { lua_pushboolean(L, 0); } return 1; }
static const char *filter_provider(cmd_parms *cmd, void *CFG, const char *args) { mod_filter_cfg *cfg = CFG; int flags; ap_filter_provider_t *provider; const char *rxend; const char *c; char *str; const char *eq; ap_filter_rec_t* frec; ap_filter_rec_t* provider_frec; /* insist on exactly four arguments */ const char *fname = ap_getword_conf(cmd->pool, &args) ; const char *pname = ap_getword_conf(cmd->pool, &args) ; const char *condition = ap_getword_conf(cmd->pool, &args) ; const char *match = ap_getword_conf(cmd->pool, &args) ; eq = ap_getword_conf(cmd->pool, &args) ; if ( !*fname || !*pname || !*match || !*condition || *eq ) { return "usage: FilterProvider filter provider condition match" ; } /* fname has been declared with DeclareFilter, so we can look it up */ frec = apr_hash_get(cfg->live_filters, fname, APR_HASH_KEY_STRING); /* or if provider is mod_filter itself, we can also look it up */ if (!frec) { c = filter_declare(cmd, CFG, fname, NULL); if ( c ) { return c; } frec = apr_hash_get(cfg->live_filters, fname, APR_HASH_KEY_STRING); } if (!frec) { return apr_psprintf(cmd->pool, "Undeclared smart filter %s", fname); } /* if provider has been registered, we can look it up */ provider_frec = ap_get_output_filter_handle(pname); if (!provider_frec) { provider_frec = apr_hash_get(cfg->live_filters, pname, APR_HASH_KEY_STRING); } if (!provider_frec) { return apr_psprintf(cmd->pool, "Unknown filter provider %s", pname); } provider = apr_palloc(cmd->pool, sizeof(ap_filter_provider_t)); if (*match == '!') { provider->not = 1; ++match; } else { provider->not = 0; } switch (*match++) { case '<': if (*match == '=') { provider->match_type = INT_LE; ++match; } else { provider->match_type = INT_LT; } provider->match.number = atoi(match); break; case '>': if (*match == '=') { provider->match_type = INT_GE; ++match; } else { provider->match_type = INT_GT; } provider->match.number = atoi(match); break; case '=': provider->match_type = INT_EQ; provider->match.number = atoi(match); break; case '/': provider->match_type = REGEX_MATCH; rxend = ap_strchr_c(match, '/'); if (!rxend) { return "Bad regexp syntax"; } flags = AP_REG_NOSUB; /* we're not mod_rewrite:-) */ for (c = rxend+1; *c; ++c) { switch (*c) { case 'i': flags |= AP_REG_ICASE; break; } } provider->match.regex = ap_pregcomp(cmd->pool, apr_pstrndup(cmd->pool, match, rxend-match), flags); break; case '*': provider->match_type = DEFINED; provider->match.number = -1; break; case '$': provider->match_type = STRING_CONTAINS; str = apr_pstrdup(cmd->pool, match); ap_str_tolower(str); provider->match.string = str; break; default: provider->match_type = STRING_MATCH; provider->match.string = apr_pstrdup(cmd->pool, match-1); break; } provider->frec = provider_frec; provider->next = frec->providers; frec->providers = provider; /* determine what a filter will dispatch this provider on */ eq = ap_strchr_c(condition, '='); if (eq) { str = apr_pstrdup(cmd->pool, eq+1); if (!strncasecmp(condition, "env=", 4)) { provider->dispatch = SUBPROCESS_ENV; } else if (!strncasecmp(condition, "req=", 4)) { provider->dispatch = REQUEST_HEADERS; } else if (!strncasecmp(condition, "resp=", 5)) { provider->dispatch = RESPONSE_HEADERS; } else { return "FilterProvider: unrecognized dispatch table"; } } else { if (!strcasecmp(condition, "handler")) { provider->dispatch = HANDLER; } else { provider->dispatch = RESPONSE_HEADERS; } str = apr_pstrdup(cmd->pool, condition); ap_str_tolower(str); } if ( (provider->dispatch == RESPONSE_HEADERS) && !strcasecmp(str, "content-type")) { provider->dispatch = CONTENT_TYPE; } provider->value = str; return NULL; }
static int modperl_filter_add_connection(conn_rec *c, int idx, const char *name, modperl_filter_add_t addfunc, const char *type) { modperl_config_dir_t *dcfg = modperl_config_dir_get_defaults(c->base_server); MpAV *av; if ((av = dcfg->handlers_per_dir[idx])) { modperl_handler_t **handlers = (modperl_handler_t **)av->elts; int i; for (i=0; i<av->nelts; i++) { modperl_filter_ctx_t *ctx; ap_filter_t *f; /* process non-mod_perl filter handlers */ if ((handlers[i]->attrs & MP_FILTER_HTTPD_HANDLER)) { /* non-mp2 filters below PROTOCOL level can't be added * at the connection level, so we need to go through * the pain of figuring out the type of the filter */ ap_filter_rec_t *frec; char *normalized_name = apr_pstrdup(c->pool, handlers[i]->name); ap_str_tolower(normalized_name); frec = idx == MP_INPUT_FILTER_HANDLER ? ap_get_input_filter_handle(normalized_name) : ap_get_output_filter_handle(normalized_name); if (frec && frec->ftype < AP_FTYPE_PROTOCOL) { MP_TRACE_f(MP_FUNC, "a non-mod_perl %s handler %s " "skipped (not a connection filter)", type, handlers[i]->name); continue; } addfunc(handlers[i]->name, NULL, NULL, c); MP_TRACE_f(MP_FUNC, "a non-mod_perl %s handler %s configured " "(connection)", type, handlers[i]->name); continue; } /* skip non-connection level filters, e.g. request filters * configured outside the resource container */ if (!(handlers[i]->attrs & MP_FILTER_CONNECTION_HANDLER)) { MP_TRACE_f(MP_FUNC, "%s is not a FilterConnection handler, skipping", handlers[i]->name); continue; } ctx = (modperl_filter_ctx_t *)apr_pcalloc(c->pool, sizeof(*ctx)); ctx->handler = handlers[i]; f = addfunc(name, (void*)ctx, NULL, c); /* ap_filter_t filter cleanup */ apr_pool_cleanup_register(c->pool, (void *)f, modperl_filter_f_cleanup, apr_pool_cleanup_null); if (handlers[i]->attrs & MP_FILTER_HAS_INIT_HANDLER && handlers[i]->next) { int status = modperl_run_filter_init( f, (idx == MP_INPUT_FILTER_HANDLER ? MP_INPUT_FILTER_MODE : MP_OUTPUT_FILTER_MODE), handlers[i]->next); if (status != OK) { return status; } } MP_TRACE_h(MP_FUNC, "%s handler %s configured (connection)", type, handlers[i]->name); } return OK; } MP_TRACE_h(MP_FUNC, "no %s handlers configured (connection)", type); return DECLINED; }