Return-Path: Delivered-To: apmail-httpd-cvs-archive@www.apache.org Received: (qmail 70797 invoked from network); 31 Oct 2004 18:00:49 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 31 Oct 2004 18:00:49 -0000 Received: (qmail 71895 invoked by uid 500); 31 Oct 2004 18:00:47 -0000 Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 71872 invoked by uid 500); 31 Oct 2004 18:00:47 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 71858 invoked by uid 500); 31 Oct 2004 18:00:46 -0000 Delivered-To: apmail-httpd-2.0-cvs@apache.org Received: (qmail 71851 invoked by uid 99); 31 Oct 2004 18:00:46 -0000 X-ASF-Spam-Status: No, hits=-10.0 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Sun, 31 Oct 2004 10:00:44 -0800 Received: (qmail 70761 invoked by uid 1868); 31 Oct 2004 18:00:43 -0000 Date: 31 Oct 2004 18:00:43 -0000 Message-ID: <20041031180043.70760.qmail@minotaur.apache.org> From: niq@apache.org To: httpd-2.0-cvs@apache.org Subject: cvs commit: httpd-2.0/modules/experimental mod_filter.c X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N niq 2004/10/31 10:00:43 Modified: include util_filter.h modules/experimental mod_filter.c Log: Change FilterDeclare/FilterProvider semantics as discussed in http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=109899588616670&w=2 Revision Changes Path 1.92 +0 -12 httpd-2.0/include/util_filter.h Index: util_filter.h =================================================================== RCS file: /home/cvs/httpd-2.0/include/util_filter.h,v retrieving revision 1.91 retrieving revision 1.92 diff -u -r1.91 -r1.92 --- util_filter.h 28 Oct 2004 13:21:08 -0000 1.91 +++ util_filter.h 31 Oct 2004 18:00:43 -0000 1.92 @@ -236,18 +236,6 @@ /** The next filter_rec in the list */ struct ap_filter_rec_t *next; - /** Dispatch criteria for filter providers */ - enum { - HANDLER, - REQUEST_HEADERS, - RESPONSE_HEADERS, - SUBPROCESS_ENV, - CONTENT_TYPE - } dispatch; - - /** Match value for filter providers */ - const char* value; - /** Providers for this filter */ ap_filter_provider_t *providers; 1.23 +142 -110 httpd-2.0/modules/experimental/mod_filter.c Index: mod_filter.c =================================================================== RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_filter.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- mod_filter.c 28 Oct 2004 13:21:08 -0000 1.22 +++ mod_filter.c 31 Oct 2004 18:00:43 -0000 1.23 @@ -75,6 +75,18 @@ /** The next provider in the list */ ap_filter_provider_t *next; + + /** Dispatch criteria for filter providers */ + enum { + HANDLER, + REQUEST_HEADERS, + RESPONSE_HEADERS, + SUBPROCESS_ENV, + CONTENT_TYPE + } dispatch; + + /** Match value for filter providers */ + const char* value; }; /** we need provider_ctx to save ctx values set by providers in filter_init */ @@ -174,15 +186,15 @@ /* Check registered providers in order */ for (provider = filter->providers; provider; provider = provider->next) { match = 1; - switch (filter->dispatch) { + switch (provider->dispatch) { case REQUEST_HEADERS: - str = apr_table_get(r->headers_in, filter->value); + str = apr_table_get(r->headers_in, provider->value); break; case RESPONSE_HEADERS: - str = apr_table_get(r->headers_out, filter->value); + str = apr_table_get(r->headers_out, provider->value); break; case SUBPROCESS_ENV: - str = apr_table_get(r->subprocess_env, filter->value); + str = apr_table_get(r->subprocess_env, provider->value); break; case CONTENT_TYPE: str = r->content_type; @@ -269,7 +281,7 @@ * toes of filters which want to do it themselves. * */ - proto_flags = filter->proto_flags | provider->frec->proto_flags; + proto_flags = provider->frec->proto_flags; /* some specific things can't happen in a proxy */ if (r->proxyreq) { @@ -458,7 +470,7 @@ #endif static const char *filter_declare(cmd_parms *cmd, void *CFG, const char *fname, - const char *condition, const char *place) + const char *place) { const char *eq; char *tmpname = ""; @@ -474,40 +486,6 @@ filter->ftype = AP_FTYPE_RESOURCE; filter->next = NULL; - /* determine what this filter will dispatch on */ - eq = ap_strchr_c(condition, '='); - if (eq) { - tmpname = apr_pstrdup(cmd->pool, eq+1); - if (!strncasecmp(condition, "env=", 4)) { - filter->dispatch = SUBPROCESS_ENV; - } - else if (!strncasecmp(condition, "req=", 4)) { - filter->dispatch = REQUEST_HEADERS; - } - else if (!strncasecmp(condition, "resp=", 5)) { - filter->dispatch = RESPONSE_HEADERS; - } - else { - return "FilterCondition: unrecognized dispatch table"; - } - } - else { - if (!strcasecmp(condition, "handler")) { - filter->dispatch = HANDLER; - } - else { - filter->dispatch = RESPONSE_HEADERS; - } - tmpname = apr_pstrdup(cmd->pool, condition); - ap_str_tolower(tmpname); - } - - if ( (filter->dispatch == RESPONSE_HEADERS) - && !strcmp(tmpname, "content-type")) { - filter->dispatch = CONTENT_TYPE; - } - filter->value = tmpname; - if (place) { if (!strcasecmp(place, "CONTENT_SET")) { filter->ftype = AP_FTYPE_CONTENT_SET; @@ -526,14 +504,24 @@ return NULL; } -static const char *filter_provider(cmd_parms *cmd, void *CFG, const char *fname, - const char *pname, const char *match) +static const char *filter_provider(cmd_parms *cmd, void *CFG, const char *args) { int flags; ap_filter_provider_t *provider; const char *rxend; const char *c; char *str; + const char *eq; + + /* 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 */ mod_filter_cfg *cfg = CFG; @@ -543,6 +531,14 @@ ap_filter_rec_t *provider_frec = ap_get_output_filter_handle(pname); /* 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 (!provider_frec) { provider_frec = apr_hash_get(cfg->live_filters, pname, APR_HASH_KEY_STRING); @@ -554,79 +550,111 @@ else 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 = apr_palloc(cmd->pool, sizeof(ap_filter_provider_t)); + provider->not = 0; + } - if (*match == '!') { - provider->not = 1; + switch (*match++) { + case '<': + if (*match == '=') { + provider->match_type = INT_LE; ++match; } else { - provider->not = 0; + 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 = REG_NOSUB; /* we're not mod_rewrite:-) */ + for (c = rxend+1; *c; ++c) { + switch (*c) { + case 'i': flags |= 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; - 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 = REG_NOSUB; /* we're not mod_rewrite:-) */ - for (c = rxend+1; *c; ++c) { - switch (*c) { - case 'i': flags |= 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; + /* 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"; } - provider->frec = provider_frec; - provider->next = frec->providers; - frec->providers = provider; } + 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) + && !strcmp(str, "content-type")) { + provider->dispatch = CONTENT_TYPE; + } + provider->value = str; return NULL; } @@ -704,6 +732,9 @@ mod_filter_cfg *cfg = CFG; ap_filter_rec_t *frec = apr_hash_get(cfg->live_filters, fname, APR_HASH_KEY_STRING); + if (!frec) { + return apr_psprintf(cmd->pool, "Undeclared smart filter %s", fname); + } frec->debug = atoi(level); return NULL; @@ -791,10 +822,11 @@ } static const command_rec filter_cmds[] = { - AP_INIT_TAKE23("FilterDeclare", filter_declare, NULL, OR_OPTIONS, - "filter-name, dispatch-criterion [, filter-type]"), - AP_INIT_TAKE3("FilterProvider", filter_provider, NULL, OR_OPTIONS, - "filter-name, provider-name, dispatch-match"), + AP_INIT_TAKE12("FilterDeclare", filter_declare, NULL, OR_OPTIONS, + "filter-name [, filter-type]"), + /** we don't have a TAKE4, so we have to use RAW_ARGS */ + AP_INIT_RAW_ARGS("FilterProvider", filter_provider, NULL, OR_OPTIONS, + "filter-name, provider-name, dispatch--criterion, dispatch-match"), AP_INIT_ITERATE("FilterChain", filter_chain, NULL, OR_OPTIONS, "list of filter names with optional [+-=!@]"), AP_INIT_TAKE2("FilterTrace", filter_debug, NULL, RSRC_CONF | ACCESS_CONF,