From: Rich Bowen Date: Mon, 11 May 2026 16:46:22 +0000 (+0000) Subject: Rewrite guide: deduplicate per-directory path stripping explanation X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5e91c12ad8b43066bd75e3ab682ca8fa5938b9f8;p=thirdparty%2Fapache%2Fhttpd.git Rewrite guide: deduplicate per-directory path stripping explanation The same concept (directory prefix is stripped before matching in per-directory context) was explained in full across three files with near-identical comparison tables. Now htaccess.xml owns the complete explanation; intro.xml and tech.xml each have a brief mention with a cross-reference. Moved the subrequest/reprocessing detail from tech.xml into htaccess.xml where it bridges into the looping discussion — most users will never read the tech doc. tech.xml retains its unique content about the two API phases (URL-to-filename hook and Fixup hook). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1934108 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/rewrite/htaccess.xml b/docs/manual/rewrite/htaccess.xml index 432bebfca9..2e42ab9bc9 100644 --- a/docs/manual/rewrite/htaccess.xml +++ b/docs/manual/rewrite/htaccess.xml @@ -123,6 +123,14 @@ where the rule lives:

in either the pattern or the substitution. This is the single most common source of confusion with per-directory rewriting.

+

When a substitution is made in per-directory context, Apache issues +a new internal subrequest with the rewritten URL, restarting request +processing from the top. If the substitution is a relative path, +the RewriteBase directive +determines what URL-path prefix is prepended. This subrequest +mechanism is also why rules can loop — see +below.

+
When you need RewriteBase diff --git a/docs/manual/rewrite/intro.xml b/docs/manual/rewrite/intro.xml index ebeb393263..b2daa7dbc2 100644 --- a/docs/manual/rewrite/intro.xml +++ b/docs/manual/rewrite/intro.xml @@ -370,21 +370,14 @@ href="rewritemap.html">RewriteMap supplementary documentation.

.htaccess files -

Rewriting is typically configured in the main server configuration -setting (outside any Directory section) or -inside VirtualHost -containers. This is the easiest way to do rewriting and is -recommended. It is possible, however, to do rewriting -inside Directory -sections or .htaccess -files at the expense of some additional complexity. This technique -is called per-directory rewrites.

- -

The main difference from per-server rewrites is that the path -prefix of the directory containing the .htaccess file is -stripped before matching in -the RewriteRule. In addition, the RewriteBase should be used to assure the request is properly mapped.

+

It is possible to use rewrite rules in +per-directory context +(.htaccess files and +Directory blocks), +but the rules behave differently there — in particular, the directory +prefix is stripped from the URL before matching. See the +Per-directory Rewrites +document for full details.

diff --git a/docs/manual/rewrite/tech.xml b/docs/manual/rewrite/tech.xml index fbb9da662d..da65017271 100644 --- a/docs/manual/rewrite/tech.xml +++ b/docs/manual/rewrite/tech.xml @@ -71,64 +71,13 @@ and URL matching.

In each of these cases, mod_rewrite rewrites the REQUEST_URI either to a new URL, or to a filename.

-

In per-directory context (i.e., within .htaccess files - and Directory blocks), these rules are being applied - after a URL has already been translated to a filename. Because of - this, the URL-path that mod_rewrite initially compares RewriteRule directives against - is the full filesystem path to the translated filename with the current - directories path (including a trailing slash) removed from the front.

- -

To illustrate: If rules are in /var/www/foo/.htaccess and a request - for /foo/bar/baz is being processed, an expression like ^bar/baz$ would - match.

- -

If a substitution is made in per-directory context, a new internal - subrequest is issued with the new URL, which restarts processing of the - request phases. If the substitution is a relative path, the RewriteBase directive - determines the URL-path prefix prepended to the substitution. - In per-directory context, care must be taken to - create rules which will eventually (in some future "round" of per-directory - rewrite processing) not perform a substitution to avoid looping. - (See RewriteLooping - for further discussion of this problem.)

- -

Because of this further manipulation of the URL in per-directory - context, you'll need to take care to craft your rewrite rules - differently in that context. In particular, remember that the - leading directory path will be stripped off of the URL that your - rewrite rules will see. Consider the examples below for further - clarification.

- - - - - - - - - - - - - - - - - - - - - - - -
Location of ruleRule
VirtualHost sectionRewriteRule "^/images/(.+)\.jpg" "/images/$1.gif"
.htaccess file in document rootRewriteRule "^images/(.+)\.jpg" "images/$1.gif"
.htaccess file in images directoryRewriteRule "^(.+)\.jpg" "$1.gif"
- -

For even more insight into how mod_rewrite manipulates URLs in - different contexts, you should consult the log entries made during - rewriting.

+

In per-directory context, + rules are applied during the Fixup phase after the URL has already + been translated to a filename. This changes what the pattern matches + against and how substitutions are handled. See the + Per-directory Rewrites + document for practical details on path stripping, RewriteBase, and + how to avoid looping.