diff options
author | Stefan Fritsch <sf@apache.org> | 2010-12-29 22:48:35 +0100 |
---|---|---|
committer | Stefan Fritsch <sf@apache.org> | 2010-12-29 22:48:35 +0100 |
commit | 95216d39186a3de764c740a7b2069d363f96f0e1 (patch) | |
tree | 3a966017d69b845093002c7dd9b1b103f0324ca5 | |
parent | in struct backrefinfo: remove nsub member which is never read, (diff) | |
download | apache2-95216d39186a3de764c740a7b2069d363f96f0e1.tar.xz apache2-95216d39186a3de764c740a7b2069d363f96f0e1.zip |
Allow to use arbitrary boolean expressions (ap_expr) in RewriteCond.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1053750 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | docs/manual/mod/mod_rewrite.xml | 10 | ||||
-rw-r--r-- | modules/mappers/mod_rewrite.c | 54 |
3 files changed, 58 insertions, 9 deletions
@@ -2,6 +2,9 @@ Changes with Apache 2.3.11 + *) mod_rewrite: Allow to use arbitrary boolean expressions (ap_expr) in + RewriteCond. [Stefan Fritsch] + *) mod_rewrite: Allow to unset environment variables using E=!VAR. PR 49512. [Mark Drayton <mark markdrayton info>, Stefan Fritsch] diff --git a/docs/manual/mod/mod_rewrite.xml b/docs/manual/mod/mod_rewrite.xml index d219cda527..ba0060a4c6 100644 --- a/docs/manual/mod/mod_rewrite.xml +++ b/docs/manual/mod/mod_rewrite.xml @@ -503,6 +503,10 @@ RewriteRule ^index\.html$ newsite.html </li> </ul> + <p>If the <em>TestString</em> has the special value <code>expr</code>, the + <em>CondPattern</em> will be treated as a + <a href="../expr.html">ap_expr</a>.</p> + <p>Other things you should be aware of:</p> <ol> @@ -756,6 +760,12 @@ RewriteRule ^index\.html$ newsite.html </note> </li> + <li> + <p>If the <em>TestString</em> has the special value <code>expr</code>, the + <em>CondPattern</em> will be treated as a + <a href="../expr.html">ap_expr</a>.</p> + </li> + <li>You can also set special flags for <em>CondPattern</em> by appending <strong><code>[</code><em>flags</em><code>]</code></strong> diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 9a784e1cef..1b38a6c148 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -99,6 +99,7 @@ #include "mod_ssl.h" #include "mod_rewrite.h" +#include "ap_expr.h" static ap_dbd_t *(*dbd_acquire)(request_rec*) = NULL; static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL; @@ -272,16 +273,18 @@ typedef enum { CONDPAT_INT_LE, CONDPAT_INT_EQ, CONDPAT_INT_GT, - CONDPAT_INT_GE + CONDPAT_INT_GE, + CONDPAT_AP_EXPR } pattern_type; typedef struct { - char *input; /* Input string of RewriteCond */ - char *pattern; /* the RegExp pattern string */ - ap_regex_t *regexp; /* the precompiled regexp */ - int flags; /* Flags which control the match */ - pattern_type ptype; /* pattern type */ - int pskip; /* back-index to display pattern */ + char *input; /* Input string of RewriteCond */ + char *pattern; /* the RegExp pattern string */ + ap_regex_t *regexp; /* the precompiled regexp */ + ap_expr_info_t *expr; /* the compiled ap_expr */ + int flags; /* Flags which control the match */ + pattern_type ptype; /* pattern type */ + int pskip; /* back-index to display pattern */ } rewritecond_entry; /* single linked list for env vars and cookies */ @@ -3234,7 +3237,10 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf, /* determine the pattern type */ newcond->ptype = CONDPAT_REGEX; - if (*a2 && a2[1]) { + if (strcasecmp(a1, "expr") == 0) { + newcond->ptype = CONDPAT_AP_EXPR; + } + else if (*a2 && a2[1]) { if (!a2[2] && *a2 == '-') { switch (a2[1]) { case 'f': newcond->ptype = CONDPAT_FILE_EXISTS; break; @@ -3313,6 +3319,15 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf, newcond->regexp = regexp; } + else if (newcond->ptype == CONDPAT_AP_EXPR) { + newcond->expr = ap_expr_parse_cmd(cmd, a2, &err, NULL); + if (err) + return apr_psprintf(cmd->pool, "RewriteCond: cannot compile " + "expression \"%s\": %s", a2, err); + newcond->expr->module_index = rewrite_module.module_index; + if (newcond->flags & CONDFLAG_NOVARY) + newcond->expr->flags |= AP_EXPR_FLAGS_DONT_VARY; + } return NULL; } @@ -3679,13 +3694,16 @@ static APR_INLINE int compare_lexicography(char *a, char *b) */ static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx) { - char *input = do_expand(p->input, ctx, NULL); + char *input; apr_finfo_t sb; request_rec *rsub, *r = ctx->r; ap_regmatch_t regmatch[AP_MAX_REG_MATCH]; int rc = 0; int basis; + if (p->ptype != CONDPAT_AP_EXPR) + input = do_expand(p->input, ctx, NULL); + switch (p->ptype) { case CONDPAT_FILE_EXISTS: if ( apr_stat(&sb, input, APR_FINFO_MIN, r->pool) == APR_SUCCESS @@ -3799,6 +3817,24 @@ test_str_l: case CONDPAT_INT_EQ: rc = (atoi(input) == atoi(p->pattern)); break; + case CONDPAT_AP_EXPR: + { + const char *err, *source; + rc = ap_expr_exec_re(r, p->expr, AP_MAX_REG_MATCH, regmatch, + &source, &err); + if (rc < 0 || err) { + rewritelog((r, 1, ctx->perdir, + "RewriteCond: expr='%s' evaluation failed: %s", + p->pattern - p->pskip, err)); + rc = 0; + } + /* update briRC backref info */ + if (rc && !(p->flags & CONDFLAG_NOTMATCH)) { + ctx->briRC.source = source; + memcpy(ctx->briRC.regmatch, regmatch, sizeof(regmatch)); + } + } + break; default: /* it is really a regexp pattern, so apply it */ rc = !ap_regexec(p->regexp, input, AP_MAX_REG_MATCH, regmatch, 0); |