]> granicus.if.org Git - apache/commitdiff
This is part three.
authorAndre Malo <nd@apache.org>
Mon, 24 Feb 2003 21:55:07 +0000 (21:55 +0000)
committerAndre Malo <nd@apache.org>
Mon, 24 Feb 2003 21:55:07 +0000 (21:55 +0000)
It fixes the misunderstandings between local URL paths and local
system paths. Note that mod_rewrite handles _both_.
Fixed also some comments to make the explanations more clear.

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

modules/mappers/mod_rewrite.c

index 84e20714bcac96d82ec214714c7a4f9143a87439..71f43e28c0125faf27ced76b9cf2ed36996fbc43 100644 (file)
@@ -1287,8 +1287,11 @@ static int hook_uri2file(request_rec *r)
 #endif
             rewritelog(r, 2, "local path result: %s", r->filename);
 
-            /* the filename must be an absolute path! */
-            if (!ap_os_is_path_absolute(r->pool, 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->pool, r->filename)) {
                 return HTTP_BAD_REQUEST;
             }
 
@@ -1483,18 +1486,43 @@ static int hook_fixup(request_rec *r)
                     ;
                 /* skip '://' */
                 cp += 3;
-                if ((cp = strchr(cp, '/')) != NULL) {
+                if ((cp = ap_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 = apr_pstrcat(r->pool, r->filename,
-                                                 cp2, NULL);
+                                                  cp2, NULL);
                     }
                 }
             }
@@ -1572,8 +1600,11 @@ static int hook_fixup(request_rec *r)
                 r->filename = apr_pstrdup(r->pool, r->filename+12);
             }
 
-            /* the filename must be an absolute path! */
-            if (!ap_os_is_path_absolute(r->pool, 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->pool, r->filename)) {
                 return HTTP_BAD_REQUEST;
             }
 
@@ -2058,12 +2089,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
+     *   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 path nor
+     *   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->pool, 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);