]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Fix the misunderstandings between local URL paths and local
authorAndré Malo <nd@apache.org>
Wed, 2 Apr 2003 21:11:41 +0000 (21:11 +0000)
committerAndré Malo <nd@apache.org>
Wed, 2 Apr 2003 21:11:41 +0000 (21:11 +0000)
system paths. Note that mod_rewrite handles _both_.
Fixed also some comments to make the explanations more clear.

PR: 12902
Obtained from: 2.1 (r1.144)
Reviewed by: Brad Nicholes, Will Rowe

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@99179 13f79535-47bb-0310-9956-ffa450edef68

src/CHANGES
src/modules/standard/mod_rewrite.c

index a6b9ee40d54e750bf630c0dae36203fb5f961ba1..690c187c72355fb27c668fdd6d8babb5dc65cfa6 100644 (file)
@@ -1,5 +1,9 @@
 Changes with Apache 1.3.28
 
+  *) Fix path handling of mod_rewrite, especially on non-unix systems.
+     There was some confusion between local paths and URL paths.
+     PR 12902.  [André Malo]
+
   *) backport from 2.x series: Prevent endless loops of internal redirects
      in mod_rewrite by aborting after exceeding a limit of internal redirects.
      The limit defaults to 10 and can be changed using the RewriteOptions
index fff2e6ea3b14bd8984cf8170e617ad7ce56d0d07..d5e33fe0cc1f311977a5d3ee8440a68b4a85b376 100644 (file)
@@ -1245,8 +1245,11 @@ static int hook_uri2file(request_rec *r)
 #endif
             rewritelog(r, 2, "local path result: %s", r->filename);
 
-            /* the filename has to start with a slash! */
-            if (!ap_os_is_path_absolute(r->filename)) {
+            /* the filename must be either an absolute local path or an
+             * absolute local URL.
+             */
+            if (   *r->filename != '/'
+                && !ap_os_is_path_absolute(r->filename)) {
                 return BAD_REQUEST;
             }
 
@@ -1441,14 +1444,39 @@ static int hook_fixup(request_rec *r)
                     ;
                 /* skip '://' */
                 cp += 3;
-                if ((cp = strchr(cp, '/')) != NULL) {
+                if ((cp = strchr(cp, '/')) != NULL && *(++cp)) {
                     rewritelog(r, 2,
                                "[per-dir %s] trying to replace "
                                "prefix %s with %s",
                                dconf->directory, dconf->directory,
                                dconf->baseurl);
-                    cp2 = subst_prefix_path(r, cp, dconf->directory,
-                                            dconf->baseurl);
+
+                    /* I think, that hack needs an explanation:
+                     * well, here is it:
+                     * mod_rewrite was written for unix systems, were
+                     * absolute file-system paths start with a slash.
+                     * URL-paths _also_ start with slashes, so they
+                     * can be easily compared with system paths.
+                     *
+                     * the following assumes, that the actual url-path
+                     * may be prefixed by the current directory path and
+                     * tries to replace the system path with the RewriteBase
+                     * URL.
+                     * That assumption is true if we use a RewriteRule like
+                     *
+                     * RewriteRule ^foo bar [R]
+                     *
+                     * (see apply_rewrite_rule function)
+                     * However on systems that don't have a / as system
+                     * root this will never match, so we skip the / after the
+                     * hostname and compare/substitute only the stuff after it.
+                     *
+                     * (note that cp was already increased to the right value)
+                     */
+                    cp2 = subst_prefix_path(r, cp, (*dconf->directory == '/')
+                                                   ? dconf->directory + 1
+                                                   : dconf->directory,
+                                            dconf->baseurl + 1);
                     if (strcmp(cp2, cp) != 0) {
                         *cp = '\0';
                         r->filename = ap_pstrcat(r->pool, r->filename,
@@ -1530,8 +1558,11 @@ static int hook_fixup(request_rec *r)
                 r->filename = ap_pstrdup(r->pool, r->filename+12);
             }
 
-            /* the filename has to start with a slash! */
-            if (!ap_os_is_path_absolute(r->filename)) {
+            /* the filename must be either an absolute local path or an
+             * absolute local URL.
+             */
+            if (   *r->filename != '/'
+                && !ap_os_is_path_absolute(r->filename)) {
                 return BAD_REQUEST;
             }
 
@@ -2067,12 +2098,12 @@ static int apply_rewrite_rule(request_rec *r, rewriterule_entry *p,
     splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND);
 
     /*
-     *   Again add the previously stripped per-directory location
-     *   prefix if the new URI is not a new one for this
-     *   location, i.e. if it's not starting with either a slash
-     *   or a fully qualified URL scheme.
+     *  Add the previously stripped per-directory location
+     *  prefix if the new URI is not a new one for this
+     *  location, i.e. if it's not an absolute URL (!) path nor
+     *  a fully qualified URL scheme.
      */
-    if (prefixstrip && !ap_os_is_path_absolute(r->filename)
+    if (prefixstrip && *r->filename != '/'
        && !is_absolute_uri(r->filename)) {
         rewritelog(r, 3, "[per-dir %s] add per-dir prefix: %s -> %s%s",
                    perdir, r->filename, perdir, r->filename);