From: Eric Covener Date: Tue, 24 Mar 2015 13:01:49 +0000 (+0000) Subject: Merge r1642484 from trunk: X-Git-Tag: 2.4.13~330 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79b009c9e67ab212a5ea81338b6408f5a32ffdae;p=thirdparty%2Fapache%2Fhttpd.git Merge r1642484 from trunk: 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/branches/2.4.x@1668870 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 3a0a4b8a603..3c0a569ce84 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,10 @@ Changes with Apache 2.4.13 calls r:wsupgrade() can cause a child process crash. [Edward Lu ] + *) mod_rewrite: Improve relative substitutions in per-directory/htaccess + context for directories found by mod_userdir and mod_alias. These no + longer require RewriteBase to be specified. [Eric Covener] + *) mod_lua: After a r:wsupgrade(), mod_lua was not properly responding to a websockets PING but instead invoking the specified script. PR57524. [Edward Lu ] diff --git a/STATUS b/STATUS index a2159263922..08c268508e6 100644 --- a/STATUS +++ b/STATUS @@ -106,12 +106,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_rewrite: use the context info API to alleviate the need to specify - a RewriteBase in some situations - trunk patch: http://svn.apache.org/r1642484 - 2.4.x patch: trunk works - +1 covener, jim, ylavic - *) SECURITY: CVE-2015-0253 (cve.mitre.org) core: Fix a crash introduced in with ErrorDocument 400 pointing to a local URL-path with the INCLUDES filter active, introduced diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index de0c11ba540..a879f6a0c91 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -195,6 +195,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 @@ -909,7 +910,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); @@ -2948,6 +2949,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); @@ -4974,6 +4978,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 @@ -5005,6 +5010,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 @@ -5042,6 +5049,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));