]> granicus.if.org Git - apache/commitdiff
*) mod_rewrite: Introduce DiscardPathInfo|DPI flag to stop the troublesome
authorEric Covener <covener@apache.org>
Fri, 19 Dec 2008 12:59:52 +0000 (12:59 +0000)
committerEric Covener <covener@apache.org>
Fri, 19 Dec 2008 12:59:52 +0000 (12:59 +0000)
    way that per-directory rewrites append the previous notion of PATH_INFO
    to each substitution before evaluating subsequent rules.
    PR38642 [Eric Covener]

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@728015 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/mod_rewrite.html.en
docs/manual/mod/mod_rewrite.xml
modules/mappers/mod_rewrite.c

diff --git a/CHANGES b/CHANGES
index 7df2e1cf1d8c8f5f74e3235264533c25a83fb5a2..ea0c9661310d0a58a0cdb402a2b171e9f01f21aa 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,11 @@
 Changes with Apache 2.3.1
 [ When backported to 2.2.x, remove entry from this file ]
 
+ *) mod_rewrite: Introduce DiscardPathInfo|DPI flag to stop the troublesome
+    way that per-directory rewrites append the previous notion of PATH_INFO
+    to each substitution before evaluating subsequent rules. 
+    PR38642 [Eric Covener]
+
   *) mod_cgid: Do not add an empty argument when calling the CGI script.
      PR 46380 [Ruediger Pluem]
 
index 679c5e701d3663110a19012db8c9dc6ce66d1e63..e5f35bf677a481b6d33f574a9618cad75220429f 100644 (file)
@@ -1262,6 +1262,33 @@ cannot use <code>$N</code> in the substitution string!
         <code>HttpOnly</code> flag is used, making the cookie inaccessible
         to JavaScript code on browsers that support this feature.</dd>
 
+        <dt>'<code>discardpathinfo|DPI'
+        (discard PATH_INFO)</code></dt><dd>
+        <p>In per-directory context, the URI each <code class="directive">RewriteRule</code>
+        compares against is the concatenation of the current values of the URI 
+        and PATH_INFO.</p>  
+
+        <p>The current URI can be the initial URI as requested by the client, the
+        result of a previous round of mod_rewrite processing, or the resulf of
+        a prior rule in the current round of mod_rewrite processing.</p>
+
+        <p>In contrast, the PATH_INFO that is appended to the URI before each 
+        rule reflects only the value of PATH_INFO before this round of 
+        mod_rewrite processing. As a consequence, if large portions
+        of the URI are matched and copied into a substitution in multiple
+        <code class="directive">RewriteRule</code> directives, without regard for
+        which parts of the URI came from the current PATH_INFO, the final 
+        URI may have multiple copies of PATH_INFO appended to it.</p>
+
+        <p>Use this flag on any substitution where the PATH_INFO that resulted
+        from the previous mapping of this request to the filesystem is not of 
+        interest.  This flag permanently forgets the PATH_INFO established 
+        before this round of mod_rewrite processing began. PATH_INFO will 
+        not be recalculated until the current round of mod_rewrite processing
+        completes.  Subsequent rules during this round of processing will see 
+        only the direct result of substitutions, without any PATH_INFO 
+        appended.</p></dd>
+
         <dt>
         '<code>env|E=</code><em>VAR</em>:<em>VAL</em>'
         (set environment variable)</dt><dd>
index e16b7922fc08a4f12376dd667cc2357255b105e3..fb30330fcb4173909c9e2d3e18762d50422a52c5 100644 (file)
@@ -1277,6 +1277,33 @@ cannot use <code>$N</code> in the substitution string!
         <code>HttpOnly</code> flag is used, making the cookie inaccessible
         to JavaScript code on browsers that support this feature.</dd>
 
+        <dt>'<code>discardpathinfo|DPI'
+        (discard PATH_INFO)</code></dt><dd>
+        <p>In per-directory context, the URI each <directive>RewriteRule</directive>
+        compares against is the concatenation of the current values of the URI 
+        and PATH_INFO.</p>  
+
+        <p>The current URI can be the initial URI as requested by the client, the
+        result of a previous round of mod_rewrite processing, or the resulf of
+        a prior rule in the current round of mod_rewrite processing.</p>
+
+        <p>In contrast, the PATH_INFO that is appended to the URI before each 
+        rule reflects only the value of PATH_INFO before this round of 
+        mod_rewrite processing. As a consequence, if large portions
+        of the URI are matched and copied into a substitution in multiple
+        <directive>RewriteRule</directive> directives, without regard for
+        which parts of the URI came from the current PATH_INFO, the final 
+        URI may have multiple copies of PATH_INFO appended to it.</p>
+
+        <p>Use this flag on any substitution where the PATH_INFO that resulted
+        from the previous mapping of this request to the filesystem is not of 
+        interest.  This flag permanently forgets the PATH_INFO established 
+        before this round of mod_rewrite processing began. PATH_INFO will 
+        not be recalculated until the current round of mod_rewrite processing
+        completes.  Subsequent rules during this round of processing will see 
+        only the direct result of substitutions, without any PATH_INFO 
+        appended.</p></dd>
+
         <dt>
         '<code>env|E=</code><em>VAR</em>:<em>VAL</em>'
         (set environment variable)</dt><dd>
index 000a6ffa13b81f984d5a963c4803771556666e21..c4e563b0f6b816eaa72c1b2a2f53e9e1672cea8c 100644 (file)
@@ -152,6 +152,7 @@ static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
 #define RULEFLAG_NOSUB              1<<12
 #define RULEFLAG_STATUS             1<<13
 #define RULEFLAG_ESCAPEBACKREF      1<<14
+#define RULEFLAG_DISCARDPATHINFO    1<<15
 
 /* return code of the rewrite rule
  * the result may be escaped - or not
@@ -3379,7 +3380,12 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
             ++error;
         }
         break;
-
+    case 'd':
+    case 'D':
+        if (!*key || !strcasecmp(key, "PI") || !strcasecmp(key,"iscardpath")) {       
+            cfg->flags |= (RULEFLAG_DISCARDPATHINFO);
+        } 
+        break;
     case 'e':
     case 'E':
         if (!*key || !strcasecmp(key, "nv")) {             /* env */
@@ -3435,7 +3441,6 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
             ++error;
         }
         break;
-
     case 'l':
     case 'L':
         if (!*key || !strcasecmp(key, "ast")) {            /* last */
@@ -3987,6 +3992,11 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
 
     /* Now adjust API's knowledge about r->filename and r->args */
     r->filename = newuri;
+
+    if (ctx->perdir && (p->flags & RULEFLAG_DISCARDPATHINFO)) {
+        r->path_info = "\0"; 
+    }
+
     splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND);
 
     /* Add the previously stripped per-directory location prefix, unless