From: Eric Covener Date: Fri, 29 Oct 2010 14:43:49 +0000 (+0000) Subject: Add an END flag to RewriteRule that acts like L=LAST but also prevents X-Git-Tag: 2.3.9~205 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a81eb0d43d61067eb67e6eab230a52c67542b804;p=apache 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 --- diff --git a/CHANGES b/CHANGES index 47eb0ec671..be3fc8bffb 100644 --- a/CHANGES +++ b/CHANGES @@ -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 ] diff --git a/docs/manual/mod/mod_rewrite.xml b/docs/manual/mod/mod_rewrite.xml index fe28f15d43..1cecf6a89d 100644 --- a/docs/manual/mod/mod_rewrite.xml +++ b/docs/manual/mod/mod_rewrite.xml @@ -1042,7 +1042,7 @@ cannot use $N in the substitution string! last|L Stop the rewriting process immediately and don't apply any more rules. Especially note caveats for per-directory and - .htaccess context. details ... @@ -1102,6 +1102,13 @@ cannot use $N in the substitution string! href="../rewrite/flags.html#flag_r">details ... + + END + 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) + details ... + skip|S=num Tells the rewriting engine to skip the next num diff --git a/docs/manual/rewrite/flags.xml b/docs/manual/rewrite/flags.xml index 3b3eb9e8e0..482b8e90ae 100644 --- a/docs/manual/rewrite/flags.xml +++ b/docs/manual/rewrite/flags.xml @@ -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.

+

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.

+

The example given here will rewrite any request to index.php, giving the original request as a query string argument to index.php, however, the 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.