]> granicus.if.org Git - apache/commitdiff
Add an END flag to RewriteRule that acts like L=LAST but also prevents
authorEric Covener <covener@apache.org>
Fri, 29 Oct 2010 14:43:49 +0000 (14:43 +0000)
committerEric Covener <covener@apache.org>
Fri, 29 Oct 2010 14:43:49 +0000 (14:43 +0000)
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

CHANGES
docs/manual/mod/mod_rewrite.xml
docs/manual/rewrite/flags.xml
modules/mappers/mod_rewrite.c

diff --git a/CHANGES b/CHANGES
index 47eb0ec6715470e2b47952bd196c7c9a45eccf65..be3fc8bffbf2574a076ced207fcddbf117a1e5e1 100644 (file)
--- 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 <issues apache org ourdetour com>]
 
index fe28f15d43f7c26197510374b9e41239f1f0218a..1cecf6a89d85fd74a60293ceb49e448ea96133e9 100644 (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>
index 3b3eb9e8e03c3c702f24cce7b577107af425dd90..482b8e90aecc8c2fa8744ded10292edaece2b45c 100644 (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
index a7d6f7a8fddcad75a8ab78014b1371b8ca211475..b83067cfc2b676dd00173b0d4d575a00c471a786 100644 (file)
 
 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.