]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
rewrite guide: document mod_rewrite vs mod_alias processing order
authorRich Bowen <rbowen@apache.org>
Thu, 14 May 2026 19:17:27 +0000 (19:17 +0000)
committerRich Bowen <rbowen@apache.org>
Thu, 14 May 2026 19:17:27 +0000 (19:17 +0000)
tech.xml: new "Module Processing Order" section explaining that
mod_rewrite runs before mod_alias in server/vhost context (hook
priority, not config order), and that per-directory context reverses
this. Includes a concrete example and practical guidance.

avoid.xml: add cross-reference note to the "Simple Redirection"
section warning about the order inconsistency.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1934198 13f79535-47bb-0310-9956-ffa450edef68

docs/manual/rewrite/TODO.md
docs/manual/rewrite/avoid.xml
docs/manual/rewrite/tech.xml

index 57f75f9a2b03733f843d622fe214c0ef1cc9899d..c7e24680ce32a2ea215958687d33b12b40ca7df1 100644 (file)
@@ -56,7 +56,7 @@ address. Sorted by priority.
 
 ### HIGH — Widely asked, not covered
 
-- [ ] **Redirect vs. RewriteRule processing order** — mod_rewrite runs
+- [x] **Redirect vs. RewriteRule processing order** — mod_rewrite runs
       *before* mod_alias regardless of config file order. Mixing them
       in the same context confuses users every year. Belongs in avoid.xml
       or tech.xml.
index 1b8c124e34ce38e77fd749567cc39d97b19534de..297207460c6066bf8bc98106980647c5d6b0e729 100644 (file)
@@ -106,6 +106,17 @@ the recommended configuration and the
 <module>mod_rewrite</module> alternative for <code>.htaccess</code>
 use.</p>
 
+    <note><title>Processing order</title>
+    <p>If you do mix <directive module="mod_alias">Redirect</directive>
+    and <directive module="mod_rewrite">RewriteRule</directive> in the
+    same context, be aware that their execution order depends on where
+    they appear. In server/virtual-host context,
+    <module>mod_rewrite</module> runs first; in per-directory context
+    (<code>.htaccess</code>), <module>mod_alias</module> runs first. See
+    <a href="tech.html#order">Module Processing Order</a> for
+    details.</p>
+    </note>
+
 </section>
 
 <section id="alias"><title>URL Aliasing</title>
index 275a98d96553d0a41e8b2f7259fe33988048a57a..d70ae1fe3994a8da415344f7ef22bcc63c711c45 100644 (file)
@@ -82,6 +82,53 @@ and URL matching.</p>
 
 </section>
 
+<section id="order"><title>Module Processing Order</title>
+
+    <p><module>mod_rewrite</module> and <module>mod_alias</module> both
+    operate during the URL-to-filename translation phase, but
+    <module>mod_rewrite</module> runs <strong>first</strong> regardless
+    of the order in which directives appear in the configuration file.
+    This is determined by the hook priority each module registers, not
+    by source order.</p>
+
+    <p>The practical consequence: when both <directive
+    module="mod_rewrite">RewriteRule</directive> and <directive
+    module="mod_alias">Redirect</directive> (or <directive
+    module="mod_alias">RedirectMatch</directive>) are present in the
+    same server or virtual-host context, the rewrite rules are
+    evaluated first. If a <code>RewriteRule</code> matches and rewrites
+    the URI (or returns a redirect), <code>Redirect</code> never sees
+    the request.</p>
+
+    <highlight language="config">
+# In this configuration, the Redirect is never reached for /old
+# because the RewriteRule matches first — even though
+# the Redirect appears earlier in the file.
+Redirect "/old" "http://example.com/new"
+RewriteRule "^/old" "/other" [L]
+</highlight>
+
+    <note><title>Per-directory context reverses the order</title>
+    <p>In <glossary ref="perdirectory">per-directory context</glossary>,
+    the situation is different. <module>mod_alias</module> directives like
+    <code>Redirect</code> still run in the URL-to-filename translation
+    phase, but <module>mod_rewrite</module> rules run later, in the
+    Fixup phase. This means that in per-directory context,
+    <code>Redirect</code> is evaluated <em>before</em>
+    <code>RewriteRule</code>.</p>
+    </note>
+
+    <p>Because of this inconsistency between contexts, mixing
+    <module>mod_rewrite</module> and <module>mod_alias</module>
+    directives in the same scope is a common source of confusion. The
+    simplest advice: choose one module for a given task. If you need
+    rewrite conditions or pattern matching, use
+    <code>RewriteRule</code> exclusively. If a simple prefix redirect
+    suffices, use <code>Redirect</code> and don't add rewrite rules
+    that might interact with it.</p>
+
+</section>
+
 <section id="InternalRuleset"><title>Ruleset Processing</title>
 
       <p>Now when <module>mod_rewrite</module> is triggered in these two API phases, it