diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | docs/manual/mod/mod_rewrite.xml | 23 | ||||
-rw-r--r-- | modules/mappers/mod_rewrite.c | 30 |
3 files changed, 54 insertions, 3 deletions
@@ -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 <Directory /opt/myapp-1.2.3> RewriteEngine On RewriteBase /myapp/ RewriteRule ^index\.html$ welcome.html </Directory> </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)); |