summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--docs/manual/mod/mod_rewrite.xml23
-rw-r--r--modules/mappers/mod_rewrite.c30
3 files changed, 54 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index a962108758..650927a39a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,10 @@ Changes with Apache 2.5.0
mod_proxy_fcgi: Fix a potential crash with response headers' size above
8K. [Teguh <chain rop.io>, Yann Ylavic, Jeff Trawick]
+ *) mod_rewrite: Improve relative substitutions in per-directory/htaccess
+ context for directories found by mod_userdir and mod_alias. These no
+ loner require RewriteBase to be specified. [Eric Covener]
+
*) mod_ssl: Fix recognition of OCSP stapling responses that are encoded
improperly or too large. [Jeff Trawick]
diff --git a/docs/manual/mod/mod_rewrite.xml b/docs/manual/mod/mod_rewrite.xml
index 59904704c8..ff2907927a 100644
--- a/docs/manual/mod/mod_rewrite.xml
+++ b/docs/manual/mod/mod_rewrite.xml
@@ -258,8 +258,22 @@ URLs on the fly</description>
default behavior in 2.4.0 through 2.4.3, and the flag to restore it is
available Apache HTTP Server 2.4.4 and later.</p>
</dd>
- </dl>
+ <dt><code>IgnoreContextInfo</code></dt>
+ <dd>
+
+ <p>In versions 2.4.11 and later, when a relative substitution is made
+ in directory (htaccess) context and <directive module="mod_rewrite"
+ >RewriteBase</directive> has not been set, this module uses some
+ extended URL and filesystem context information to change the
+ relative substitution back into a URL. Modules such as
+ <module>mod_userdir</module> and <module>mod_alias</module>
+ supply this extended context info. This option disable the behavior
+ introduced in 2.4.11 and should only be set if all of the conditions
+ above are present and a substituion has an unexpected result. </p>
+ </dd>
+
+ </dl>
</usage>
</directivesynopsis>
@@ -379,6 +393,10 @@ URLs on the fly</description>
<directive>RewriteRule</directive>, suffixed by the relative
substitution is also valid as a URL path on the server
(this is rare).</li>
+ <li> In Apache HTTP Server 2.4.11 and later, this directive may be
+ omitted when the request is mapped via
+ <directive module="mod_alias">Alias</directive>
+ or <module>mod_userdir</module>.</li>
</ul>
<p> In the example below, <directive>RewriteBase</directive> is necessary
@@ -388,13 +406,14 @@ URLs on the fly</description>
directory under the document root.</p>
<highlight language="config">
DocumentRoot /var/www/example.com
-Alias /myapp /opt/myapp-1.2.3
+AliasMatch ^/myapp /opt/myapp-1.2.3
&lt;Directory /opt/myapp-1.2.3&gt;
RewriteEngine On
RewriteBase /myapp/
RewriteRule ^index\.html$ welcome.html
&lt;/Directory&gt;
</highlight>
+
</usage>
</directivesynopsis>
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index cbab2440ad..64c287c3c3 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -200,6 +200,7 @@ static const char* really_last_key = "rewrite_really_last";
#define OPTION_INHERIT_DOWN 1<<6
#define OPTION_INHERIT_DOWN_BEFORE 1<<7
#define OPTION_IGNORE_INHERIT 1<<8
+#define OPTION_IGNORE_CONTEXT_INFO 1<<9
#ifndef RAND_MAX
#define RAND_MAX 32767
@@ -935,7 +936,7 @@ static int prefix_stat(const char *path, apr_pool_t *pool)
/*
* substitute the prefix path 'match' in 'input' with 'subst' (RewriteBase)
*/
-static char *subst_prefix_path(request_rec *r, char *input, char *match,
+static char *subst_prefix_path(request_rec *r, char *input, const char *match,
const char *subst)
{
apr_size_t len = strlen(match);
@@ -2974,6 +2975,9 @@ static const char *cmd_rewriteoptions(cmd_parms *cmd,
else if (!strcasecmp(w, "mergebase")) {
options |= OPTION_MERGEBASE;
}
+ else if (!strcasecmp(w, "ignorecontextinfo")) {
+ options |= OPTION_IGNORE_CONTEXT_INFO;
+ }
else {
return apr_pstrcat(cmd->pool, "RewriteOptions: unknown option '",
w, "'", NULL);
@@ -5006,6 +5010,7 @@ static int hook_fixup(request_rec *r)
return n;
}
else {
+ const char *tmpfilename = NULL;
/* it was finally rewritten to a local path */
/* if someone used the PASSTHROUGH flag in per-dir
@@ -5039,6 +5044,8 @@ static int hook_fixup(request_rec *r)
return OK;
}
+ tmpfilename = r->filename;
+
/* if there is a valid base-URL then substitute
* the per-dir prefix with this base-URL if the
* current filename still is inside this per-dir
@@ -5076,6 +5083,27 @@ static int hook_fixup(request_rec *r)
}
}
+ /* No base URL, or r->filename wasn't still under dconf->directory
+ * or, r->filename wasn't still under the document root.
+ * If there's a context document root AND a context prefix, and
+ * the context document root is a prefix of r->filename, replace.
+ * This allows a relative substitution on a path found by mod_userdir
+ * or mod_alias without baking in a RewriteBase.
+ */
+ if (tmpfilename == r->filename &&
+ !(dconf->options & OPTION_IGNORE_CONTEXT_INFO)) {
+ if ((ccp = ap_context_document_root(r)) != NULL) {
+ const char *prefix = ap_context_prefix(r);
+ if (prefix != NULL) {
+ rewritelog((r, 2, dconf->directory, "trying to replace "
+ "context docroot %s with context prefix %s",
+ ccp, prefix));
+ r->filename = subst_prefix_path(r, r->filename,
+ ccp, prefix);
+ }
+ }
+ }
+
/* now initiate the internal redirect */
rewritelog((r, 1, dconf->directory, "internal redirect with %s "
"[INTERNAL REDIRECT]", r->filename));