diff options
author | Eric Covener <covener@apache.org> | 2014-11-30 00:16:56 +0100 |
---|---|---|
committer | Eric Covener <covener@apache.org> | 2014-11-30 00:16:56 +0100 |
commit | 838b88e3d08ba2c53d930de8498971acd69920b7 (patch) | |
tree | 411c3692d70b8bd113154cf069a52cbff78e996e /modules | |
parent | Rebuild. (diff) | |
download | apache2-838b88e3d08ba2c53d930de8498971acd69920b7.tar.xz apache2-838b88e3d08ba2c53d930de8498971acd69920b7.zip |
Remove some instances where a RewriteBase must be specified
Previously, any time you used a relative substitution in
per-directory/htaccess context, you needed to specify
a RewriteBase. But in case where the context document root
and context prefix are known via e.g. mod_userdir
or mod_alias, and the substitution is under the context
document root, we can determine the replacement automatically.
This makes htaccess files or config snippets a bit more
portable.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1642484 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r-- | modules/mappers/mod_rewrite.c | 30 |
1 files changed, 29 insertions, 1 deletions
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)); |