summaryrefslogtreecommitdiff
path: root/modules/mappers/mod_rewrite.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mappers/mod_rewrite.c')
-rw-r--r--modules/mappers/mod_rewrite.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 0ac4dc9d..7646407b 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -192,6 +192,9 @@ static const char* really_last_key = "rewrite_really_last";
#define OPTION_NOSLASH 1<<3
#define OPTION_ANYURI 1<<4
#define OPTION_MERGEBASE 1<<5
+#define OPTION_INHERIT_DOWN 1<<6
+#define OPTION_INHERIT_DOWN_BEFORE 1<<7
+#define OPTION_IGNORE_INHERIT 1<<8
#ifndef RAND_MAX
#define RAND_MAX 32767
@@ -231,6 +234,9 @@ static const char* really_last_key = "rewrite_really_last";
#define subreq_ok(r) (!r->main || \
(r->main->uri && r->uri && strcmp(r->main->uri, r->uri)))
+#ifndef REWRITE_MAX_ROUNDS
+#define REWRITE_MAX_ROUNDS 32000
+#endif
/*
* +-------------------------------------------------------+
@@ -308,6 +314,7 @@ typedef struct {
data_item *env; /* added environment variables */
data_item *cookie; /* added cookies */
int skip; /* number of next rules to skip */
+ int maxrounds; /* limit on number of loops with N flag */
} rewriterule_entry;
typedef struct {
@@ -2135,7 +2142,10 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx)
break;
case 16:
- if (!strcmp(var, "REQUEST_FILENAME")) {
+ if (*var == 'C' && !strcmp(var, "CONN_REMOTE_ADDR")) {
+ result = r->connection->client_ip;
+ }
+ else if (!strcmp(var, "REQUEST_FILENAME")) {
result = r->filename; /* same as script_filename (15) */
}
break;
@@ -2758,7 +2768,9 @@ static void *config_server_merge(apr_pool_t *p, void *basev, void *overridesv)
a->server = overrides->server;
- if (a->options & OPTION_INHERIT) {
+ if (a->options & OPTION_INHERIT ||
+ (base->options & OPTION_INHERIT_DOWN &&
+ !(a->options & OPTION_IGNORE_INHERIT))) {
/*
* local directives override
* and anything else is inherited
@@ -2770,7 +2782,9 @@ static void *config_server_merge(apr_pool_t *p, void *basev, void *overridesv)
a->rewriterules = apr_array_append(p, overrides->rewriterules,
base->rewriterules);
}
- else if (a->options & OPTION_INHERIT_BEFORE) {
+ else if (a->options & OPTION_INHERIT_BEFORE ||
+ (base->options & OPTION_INHERIT_DOWN_BEFORE &&
+ !(a->options & OPTION_IGNORE_INHERIT))) {
/*
* local directives override
* and anything else is inherited (preserving order)
@@ -2847,13 +2861,17 @@ static void *config_perdir_merge(apr_pool_t *p, void *basev, void *overridesv)
a->directory = overrides->directory;
- if (a->options & OPTION_INHERIT) {
+ if (a->options & OPTION_INHERIT ||
+ (base->options & OPTION_INHERIT_DOWN &&
+ !(a->options & OPTION_IGNORE_INHERIT))) {
a->rewriteconds = apr_array_append(p, overrides->rewriteconds,
base->rewriteconds);
a->rewriterules = apr_array_append(p, overrides->rewriterules,
base->rewriterules);
}
- else if (a->options & OPTION_INHERIT_BEFORE) {
+ else if (a->options & OPTION_INHERIT_BEFORE ||
+ (base->options & OPTION_INHERIT_DOWN_BEFORE &&
+ !(a->options & OPTION_IGNORE_INHERIT))) {
a->rewriteconds = apr_array_append(p, base->rewriteconds,
overrides->rewriteconds);
a->rewriterules = apr_array_append(p, base->rewriterules,
@@ -2905,6 +2923,15 @@ static const char *cmd_rewriteoptions(cmd_parms *cmd,
else if (!strcasecmp(w, "inheritbefore")) {
options |= OPTION_INHERIT_BEFORE;
}
+ else if (!strcasecmp(w, "inheritdown")) {
+ options |= OPTION_INHERIT_DOWN;
+ }
+ else if(!strcasecmp(w, "inheritdownbefore")) {
+ options |= OPTION_INHERIT_DOWN_BEFORE;
+ }
+ else if (!strcasecmp(w, "ignoreinherit")) {
+ options |= OPTION_IGNORE_INHERIT;
+ }
else if (!strcasecmp(w, "allownoslash")) {
options |= OPTION_NOSLASH;
}
@@ -3498,6 +3525,10 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
}
else if (!*key || !strcasecmp(key, "ext")) { /* next */
cfg->flags |= RULEFLAG_NEWROUND;
+ if (val && *val) {
+ cfg->maxrounds = atoi(val);
+ }
+
}
else if (((*key == 'S' || *key == 's') && !key[1])
|| !strcasecmp(key, "osubreq")) { /* nosubreq */
@@ -3649,6 +3680,7 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
newrule->env = NULL;
newrule->cookie = NULL;
newrule->skip = 0;
+ newrule->maxrounds = REWRITE_MAX_ROUNDS;
if (a3 != NULL) {
if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
cmd_rewriterule_setflag)) != NULL) {
@@ -4192,6 +4224,7 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
int rc;
int s;
rewrite_ctx *ctx;
+ int round = 1;
ctx = apr_palloc(r->pool, sizeof(*ctx));
ctx->perdir = perdir;
@@ -4280,6 +4313,15 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
* the rewriting ruleset again.
*/
if (p->flags & RULEFLAG_NEWROUND) {
+ if (++round >= p->maxrounds) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02596)
+ "RewriteRule '%s' and URI '%s' exceeded "
+ "maximum number of rounds (%d) via the [N] flag",
+ p->pattern, r->uri, p->maxrounds);
+
+ r->status = HTTP_INTERNAL_SERVER_ERROR;
+ return ACTION_STATUS;
+ }
goto loop;
}
@@ -5004,7 +5046,7 @@ static int hook_fixup(request_rec *r)
rewritelog((r, 1, dconf->directory, "internal redirect with %s "
"[INTERNAL REDIRECT]", r->filename));
r->filename = apr_pstrcat(r->pool, "redirect:", r->filename, NULL);
- r->handler = "redirect-handler";
+ r->handler = REWRITE_REDIRECT_HANDLER_NAME;
return OK;
}
}
@@ -5050,7 +5092,7 @@ static int hook_mimetype(request_rec *r)
*/
static int handler_redirect(request_rec *r)
{
- if (strcmp(r->handler, "redirect-handler")) {
+ if (strcmp(r->handler, REWRITE_REDIRECT_HANDLER_NAME)) {
return DECLINED;
}