Return-Path: X-Original-To: apmail-httpd-cvs-archive@www.apache.org Delivered-To: apmail-httpd-cvs-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B181B7669 for ; Thu, 10 Nov 2011 00:08:19 +0000 (UTC) Received: (qmail 60096 invoked by uid 500); 10 Nov 2011 00:08:19 -0000 Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 60029 invoked by uid 500); 10 Nov 2011 00:08:19 -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: List-Id: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 60022 invoked by uid 99); 10 Nov 2011 00:08:19 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 10 Nov 2011 00:08:19 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 10 Nov 2011 00:08:16 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id D67E223888E4; Thu, 10 Nov 2011 00:07:54 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1200055 - /httpd/httpd/trunk/modules/filters/mod_proxy_html.c Date: Thu, 10 Nov 2011 00:07:54 -0000 To: cvs@httpd.apache.org From: niq@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20111110000754.D67E223888E4@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: niq Date: Thu Nov 10 00:07:54 2011 New Revision: 1200055 URL: http://svn.apache.org/viewvc?rev=1200055&view=rev Log: mod_proxy_html: use ap_expr to evaluate conditional URLMaps Modified: httpd/httpd/trunk/modules/filters/mod_proxy_html.c Modified: httpd/httpd/trunk/modules/filters/mod_proxy_html.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_proxy_html.c?rev=1200055&r1=1200054&r2=1200055&view=diff ============================================================================== --- httpd/httpd/trunk/modules/filters/mod_proxy_html.c (original) +++ httpd/httpd/trunk/modules/filters/mod_proxy_html.c Thu Nov 10 00:07:54 2011 @@ -44,8 +44,10 @@ #include "apr_optional.h" #include "mod_xml2enc.h" #include "http_request.h" +#include "ap_expr.h" /* globals set once at startup */ +static ap_rxplus_t* old_expr; static ap_regex_t* seek_meta; static const apr_strmatch_pattern* seek_content; static apr_status_t (*xml2enc_charset)(request_rec*, xmlCharEncoding*, const char**) = NULL; @@ -71,11 +73,6 @@ typedef struct { unsigned int start; unsigned int end; } meta; -typedef struct { - const char* env; - const char* val; - int rel; -} rewritecond; typedef struct urlmap { struct urlmap* next; unsigned int flags; @@ -85,7 +82,7 @@ typedef struct urlmap { ap_regex_t* r; } from; const char* to; - rewritecond* cond; + ap_expr_info_t *cond; } urlmap; typedef struct { urlmap* map; @@ -743,34 +740,20 @@ static const char* interpolate_vars(requ } static void fixup_rules(saxctxt* ctx) { - const char* thisval; urlmap* newp; urlmap* p; urlmap* prev = NULL; request_rec* r = ctx->f->r; - int has_cond; for (p = ctx->cfg->map; p; p = p->next) { - has_cond = -1; if (p->cond != NULL) { - thisval = apr_table_get(r->subprocess_env, p->cond->env); - if (!p->cond->val) { - /* required to be "anything" */ - if (thisval) - has_cond = 1; /* satisfied */ - else - has_cond = 0; /* unsatisfied */ - } - else { - if (thisval && !strcasecmp(p->cond->val, thisval)) { - has_cond = 1; /* satisfied */ - } - else { - has_cond = 0; /* unsatisfied */ - } + const char *err; + int ok = ap_expr_exec(r, p->cond, &err); + if (err) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Error evaluating expr: %s", err); } - if (((has_cond == 0) && (p->cond->rel ==1)) - || ((has_cond == 1) && (p->cond->rel == -1))) { + if (ok == 0) { continue; /* condition is unsatisfied */ } } @@ -1027,10 +1010,11 @@ static void* proxy_html_merge(apr_pool_t } #define REGFLAG(n,s,c) ((s&&(ap_strchr_c((s),(c))!=NULL)) ? (n) : 0) #define XREGFLAG(n,s,c) ((!s||(ap_strchr_c((s),(c))==NULL)) ? (n) : 0) -static void comp_urlmap(apr_pool_t* pool, urlmap* newmap, const char* from, - const char* to, const char* flags, const char* cond) +static const char* comp_urlmap(cmd_parms *cmd, urlmap* newmap, + const char* from, const char* to, + const char* flags, const char* cond) { - char* eq; + const char *err = NULL; newmap->flags = XREGFLAG(M_HTML,flags,'h') | XREGFLAG(M_EVENTS,flags,'e') @@ -1053,28 +1037,40 @@ static void comp_urlmap(apr_pool_t* pool | REGFLAG(AP_REG_ICASE,flags,'i') | REGFLAG(AP_REG_NOSUB,flags,'n') | REGFLAG(AP_REG_NEWLINE,flags,'s'); - newmap->from.r = ap_pregcomp(pool, from, newmap->regflags); + newmap->from.r = ap_pregcomp(cmd->pool, from, newmap->regflags); newmap->to = to; } if (cond != NULL) { - char* cond_copy; - newmap->cond = apr_pcalloc(pool, sizeof(rewritecond)); - if (cond[0] == '!') { - newmap->cond->rel = -1; - newmap->cond->env = cond_copy = apr_pstrdup(pool, cond+1); - } else { - newmap->cond->rel = 1; - newmap->cond->env = cond_copy = apr_pstrdup(pool, cond); - } - eq = ap_strchr(++cond_copy, '='); - if (eq) { - *eq = 0; - newmap->cond->val = eq+1; + /* back-compatibility: support old-style ENV expressions + * by converting to ap_expr syntax. + * + * 1. var --> env(var) + * 2. var=val --> env(var)=val + * 3. !var --> !env(var) + * 4. !var=val --> env(var)!=val + */ + char *newcond = NULL; + if (ap_rxplus_exec(cmd->temp_pool, old_expr, cond, &newcond)) { + /* we got a substitution. Check for the case (3) above + * that the regexp gets wrong: a negation without a comparison. + */ + if ((cond[0] == '!') && !strchr(cond, '=')) { + memmove(newcond+1, newcond, strlen(newcond)-1); + newcond[0] = '!'; + } + cond = newcond; } +#if 0 + newmap->cond = apr_palloc(pool, sizeof(ap_expr_info_t)); + err = ap_expr_parse(pool, tpool, newmap->cond, cond, NULL); +#else + newmap->cond = ap_expr_parse_cmd(cmd, cond, 0, &err, NULL); +#endif } else { newmap->cond = NULL; } + return err; } static const char* set_urlmap(cmd_parms* cmd, void* CFG, const char* args) { @@ -1109,8 +1105,7 @@ static const char* set_urlmap(cmd_parms* else cfg->map = newmap; - comp_urlmap(cmd->pool, newmap, from, to, flags, cond); - return NULL; + return comp_urlmap(cmd, newmap, from, to, flags, cond); } static const char* set_doctype(cmd_parms* cmd, void* CFG, @@ -1219,8 +1214,7 @@ static const command_rec proxy_html_cmds "Enable proxy-html and xml2enc filters"), { NULL } }; -static int mod_proxy_html(apr_pool_t* p, apr_pool_t* p1, apr_pool_t* p2, - server_rec* s) +static int mod_proxy_html(apr_pool_t* p, apr_pool_t* p1, apr_pool_t* p2) { seek_meta = ap_pregcomp(p, "]*(http-equiv)[^>]*>", AP_REG_EXTENDED|AP_REG_ICASE); @@ -1239,6 +1233,9 @@ static int mod_proxy_html(apr_pool_t* p, "Without it, non-ASCII characters in proxied pages are " "likely to display incorrectly."); } + + /* old_expr only needs to last the life of the config phase */ + old_expr = ap_rxplus_compile(p1, "s/^(!)?(\\w+)((=)(.+))?$/reqenv('$2')$1$4'$5'/"); return OK; } static void proxy_html_insert(request_rec* r) @@ -1257,7 +1254,10 @@ static void proxy_html_hooks(apr_pool_t* ap_register_output_filter_protocol("proxy-html", proxy_html_filter, NULL, AP_FTYPE_RESOURCE, AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH); - ap_hook_post_config(mod_proxy_html, NULL, NULL, APR_HOOK_MIDDLE); + /* move this to pre_config so old_expr is available to interpret + * old-style conditions on URL maps. + */ + ap_hook_pre_config(mod_proxy_html, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_insert_filter(proxy_html_insert, NULL, aszSucc, APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA proxy_html_module = {