Add an END flag to RewriteRule that acts like L=LAST but also prevents

further rounds of rewrite processing due to per-directory substitutions.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1028778 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eric Covener
2010-10-29 14:43:49 +00:00
parent 7893d3f5ed
commit a81eb0d43d
4 changed files with 44 additions and 1 deletions

View File

@ -6,6 +6,10 @@ Changes with Apache 2.3.9
Fix a denial of service attack against mod_reqtimeout.
[Stefan Fritsch]
*) mod_rewrite: Add END flag for RewriteRule to prevent further rounds
of rewrite processing when a per-directory substitution occurs.
[Eric Covener]
*) mod_ssl: Make sure to always log an error if loading of CA certificates
fails. PR 40312. [Paul Tiemann <issues apache org ourdetour com>]

View File

@ -1042,7 +1042,7 @@ cannot use <code>$N</code> in the substitution string!
<td>last|L</td>
<td>Stop the rewriting process immediately and don't apply any
more rules. Especially note caveats for per-directory and
.htaccess context. <em><a
.htaccess context (see also the END flag). <em><a
href="../rewrite/flags.html#flag_l">details ...</a></em></td>
</tr>
<tr>
@ -1102,6 +1102,13 @@ cannot use <code>$N</code> in the substitution string!
href="../rewrite/flags.html#flag_r">details ...</a></em>
</td>
</tr>
<tr>
<td>END</td>
<td>Stop the rewriting process immediately and don't apply any
more rules. Also prevents further execution of rewrite rules
in per-directory and .htaccess context. (Available in 2.3.9 and later)
<em><a href="../rewrite/flags.html#flag_l">details ...</a></em></td>
</tr>
<tr>
<td>skip|S=<em>num</em></td>
<td>Tells the rewriting engine to skip the next <em>num</em>

View File

@ -343,6 +343,12 @@ contexts, that you take explicit steps to avoid rules looping, and not
count solely on the [L] flag to terminate execution of a series of
rules, as shown below.</p>
<p> An alternative flag, [END], can be used to terminate not only the
current round of rewrite processing but prevent any subsequent
rewrite processing from occuring in per-directory (htaccess)
context. This does not apply to new requests resulting from external
redirects.</p>
<p>The example given here will rewrite any request to
<code>index.php</code>, giving the original request as a query string
argument to <code>index.php</code>, however, the <directive

View File

@ -102,6 +102,7 @@
static ap_dbd_t *(*dbd_acquire)(request_rec*) = NULL;
static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
static const char* really_last_key = "rewrite_really_last";
/*
* in order to improve performance on running production systems, you
@ -163,6 +164,7 @@ static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
#define RULEFLAG_ESCAPEBACKREF 1<<14
#define RULEFLAG_DISCARDPATHINFO 1<<15
#define RULEFLAG_QSDISCARD 1<<16
#define RULEFLAG_END 1<<17
/* return code of the rewrite rule
* the result may be escaped - or not
@ -3330,6 +3332,9 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
cp->next = NULL;
cp->data = val;
}
else if (!strcasecmp(key, "nd")) { /* end */
cfg->flags |= RULEFLAG_END;
}
else {
++error;
}
@ -4129,6 +4134,11 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
break;
}
if (p->flags & RULEFLAG_END) {
rewritelog((r, 8, perdir, "Rule has END flag, no further rewriting for this request"));
apr_pool_userdata_set("1", really_last_key, apr_pool_cleanup_null, r->pool);
break;
}
/*
* Stop processing also on proxy pass-through and
* last-rule and new-round flags.
@ -4293,6 +4303,7 @@ static int hook_uri2file(request_rec *r)
const char *thisurl;
unsigned int port;
int rulestatus;
void *skipdata;
/*
* retrieve the config structures
@ -4319,6 +4330,13 @@ static int hook_uri2file(request_rec *r)
return DECLINED;
}
/* END flag was used as a RewriteRule flag on this request */
apr_pool_userdata_get(&skipdata, really_last_key, r->pool);
if (skipdata != NULL) {
rewritelog((r, 8, NULL, "Declining, no further rewriting due to END flag"));
return DECLINED;
}
/*
* add the SCRIPT_URL variable to the env. this is a bit complicated
* due to the fact that apache uses subrequests and internal redirects
@ -4569,6 +4587,7 @@ static int hook_fixup(request_rec *r)
int n;
char *ofilename;
int is_proxyreq;
void *skipdata;
dconf = (rewrite_perdir_conf *)ap_get_module_config(r->per_dir_config,
&rewrite_module);
@ -4612,6 +4631,13 @@ static int hook_fixup(request_rec *r)
return DECLINED;
}
/* END flag was used as a RewriteRule flag on this request */
apr_pool_userdata_get(&skipdata, really_last_key, r->pool);
if (skipdata != NULL) {
rewritelog((r, 8, dconf->directory, "Declining, no further rewriting due to END flag"));
return DECLINED;
}
/*
* Do the Options check after engine check, so
* the user is able to explicitely turn RewriteEngine Off.