<button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12" /><line y2="12" x2="22" y1="12" x1="2" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></button>
<div class="toplang">
<p><span>Available Languages: </span><a href="../en/rewrite/avoid.html" title="English"> en </a> |
-<a href="../fr/rewrite/avoid.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/avoid.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div>
<li><img alt="" src="../images/down.gif" /> <a href="#host-deny">Denying Hosts in a Reject List</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#vhosts">Virtual Hosting</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#load-balancing">Load Balancing</a></li>
-</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li></ul></div>
+</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="htaccess.html">Per-directory Rewrites</a></li><li><a href="flags.html">RewriteRule Flags</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="tech.html">Technical details</a></li></ul></div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="redirect" id="redirect">Simple Redirection</a> <a title="Permanent link" href="#redirect" class="permalink">¶</a></h2>
<a href="remapping.html#canonicalhost">Canonical Hostnames</a>
recipe.</p>
-<p>To redirect <code>http</code> URLs to <code>https</code>, do the
-following:</p>
-
-<pre class="prettyprint lang-config"><VirtualHost *:80>
- ServerName www.example.com
- Redirect "/" "https://www.example.com/"
-</VirtualHost>
-
-<VirtualHost *:443>
- ServerName www.example.com
- # ... SSL configuration goes here
-</VirtualHost></pre>
-
-
-<p>The use of <code>RewriteRule</code> to perform this task may be
-appropriate if there are other <code>RewriteRule</code> directives in
-the same scope. This is because, when there are <code>Redirect</code>
-and <code>RewriteRule</code> directives in the same scope, the
-<code>RewriteRule</code> directives will run first, regardless of the
-order of appearance in the configuration file.</p>
-
-<p>In the case of the <em>http-to-https</em> redirection, the use of
-<code>RewriteRule</code> would be appropriate if you don't have access
-to the main server configuration file, and are obliged to perform this
-task in a <code>.htaccess</code> file instead.</p>
+<p>To redirect <code>http</code> URLs to <code>https</code>, a
+<code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code> in a dedicated
+HTTP virtual host is the cleanest approach. See the
+<a href="remapping.html#https-redirect">Forcing HTTPS</a> recipe for
+the recommended configuration and the
+<code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> alternative for <code>.htaccess</code>
+use.</p>
+
+ <div class="note"><h3>Processing order</h3>
+ <p>If you do mix <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code>
+ and <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> in the
+ same context, be aware that their execution order depends on where
+ they appear. In server/virtual-host context,
+ <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> runs first; in per-directory context
+ (<code>.htaccess</code>), <code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> runs first. See
+ <a href="tech.html#order">Module Processing Order</a> for
+ details.</p>
+ </div>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="alias" id="alias">URL Aliasing</a> <a title="Permanent link" href="#alias" class="permalink">¶</a></h2>
<p>The <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> directive
-provides mapping from a URI to a directory - usually a directory outside
+provides mapping from a URL-path to a directory - usually a directory outside
of your <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>. Although it
is possible to perform this mapping with <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>,
<code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> is the preferred method, for
</div></div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/rewrite/avoid.html" title="English"> en </a> |
-<a href="../fr/rewrite/avoid.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/avoid.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div><div id="footer">
<p class="apache">Copyright 2026 The Apache Software Foundation.<br />Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
-<!-- English Revision: 1898650:1933719 (outdated) -->
+<!-- English Revision: 1898650:1934664 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
<li><img alt="" src="../images/down.gif" /> <a href="#flag_unsafe_allow_3f">UnsafeAllow3F</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#flag_unsafe_prefix_stat">UnsafePrefixStat</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#flag_unc">UNC</a></li>
-</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li></ul></div>
+</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="htaccess.html">Per-directory Rewrites</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="tech.html">Technical details</a></li></ul></div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="introduction" id="introduction">Introduction</a> <a title="Permanent link" href="#introduction" class="permalink">¶</a></h2>
<p>To limit the characters escaped this way, see <a href="#flag_bne">#flag_bne</a>
and <a href="#flag_bctls">#flag_bctls</a></p>
+
+<p>See <a href="tech.html#encoding">URL Encoding and Decoding</a> for
+a full explanation of how Apache decodes URIs before pattern matching.</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_bnp" id="flag_bnp">BNP|backrefnoplus (don't escape space to +)</a> <a title="Permanent link" href="#flag_bnp" class="permalink">¶</a></h2>
<p>This flag is available in version 2.4.26 and later.</p>
+
+<p>See <a href="tech.html#encoding">URL Encoding and Decoding</a> for
+background on how encoding is handled in the rewrite pipeline.</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_bctls" id="flag_bctls">BCTLS</a> <a title="Permanent link" href="#flag_bctls" class="permalink">¶</a></h2>
the next rule, and any other rules that are chained together, are
skipped.</p>
+<pre class="prettyprint lang-config"># Rewrite legacy product URLs to the new catalog app,
+# and add a tracking parameter — but only for the rewritten ones.
+RewriteRule "^/products/([0-9]+)$" "/catalog/item/$1" [C]
+RewriteRule "^/catalog/(.*)$" "/catalog/$1?via=legacy" [QSA]</pre>
+
+
+<p>Without the [C] flag, the second rule would also match requests
+that arrive at <code>/catalog/</code> directly. The chain ensures the
+second rule is only applied when the first rule matched.</p>
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_co" id="flag_co">CO|cookie</a> <a title="Permanent link" href="#flag_co" class="permalink">¶</a></h2>
<dt>samesite</dt>
<dd>If set to anything other than <code>false</code> or <code>0</code>, the <code>SameSite</code>
attribute is set to the specified value. Typical values are <code>None</code>,
-<code>Lax</code>, and <code>Strict</code>. Available in 2.5.1 and later.</dd>
+<code>Lax</code>, and <code>Strict</code>. Available in 2.4.47 and later.</dd>
</dl>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_dpi" id="flag_dpi">DPI|discardpath</a> <a title="Permanent link" href="#flag_dpi" class="permalink">¶</a></h2>
-<p>The DPI flag causes the PATH_INFO that was appended to the rewritten
-URI to be discarded.</p>
-<p>In per-directory context, the URI that each <code class="directive">RewriteRule</code>
-compares against is the concatenation of the current values of the URI
-and PATH_INFO.</p>
-
-<p>The current URI can be the initial URI as requested by the client, the
-result of a previous round of <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> processing, or the result of
-a prior rule in the current round of <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> processing.</p>
-
-<p>In contrast, the PATH_INFO that is appended to the URI before each
-rule reflects only the value of PATH_INFO before this round of
-<code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> processing. As a consequence, if large portions
-of the URI are matched and copied into a substitution in multiple
+<p>The DPI flag causes the <a class="glossarylink" href="../glossary.html#pathinfo" title="see glossary">PATH_INFO</a>
+that was appended to the rewritten
+<a class="glossarylink" href="../glossary.html#urlpath" title="see glossary">URL-path</a> to be discarded.</p>
+
+<p>In <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a>, the
+<a class="glossarylink" href="../glossary.html#urlpath" title="see glossary">URL-path</a> each
+<code class="directive">RewriteRule</code> compares against is the concatenation
+of the current URL-path and PATH_INFO.</p>
+
+<p>The current URL-path can be the initial path as requested by the
+client, the result of a previous round of <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
+processing, or the result of a prior rule in the current round of
+<code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> processing.</p>
+
+<p>In contrast, the PATH_INFO that is appended to the URL-path before
+each rule reflects only the value of PATH_INFO before this round of
+<code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> processing. As a consequence, if large
+portions of the URL-path are matched and copied into a substitution in multiple
<code class="directive">RewriteRule</code> directives, without regard for
-which parts of the URI came from the current PATH_INFO, the final
-URI may have multiple copies of PATH_INFO appended to it.</p>
+which parts of the URL-path came from the current PATH_INFO, the final
+URL-path may have multiple copies of PATH_INFO appended to it.</p>
<p>Use this flag on any substitution where the PATH_INFO that resulted
from the previous mapping of this request to the filesystem is not of
completes. Subsequent rules during this round of processing will see
only the direct result of substitutions, without any PATH_INFO
appended.</p>
+
+<pre class="prettyprint lang-config"># Request: /app/script.php/extra/path (PATH_INFO is /extra/path)
+# Without DPI, the substitution would see "script.php/extra/path"
+# and could inadvertently copy PATH_INFO into the result.
+RewriteRule "^script\.php(.*)$" "/new-app/handler$1" [DPI]</pre>
+
+
+<p>The [DPI] flag discards <code>/extra/path</code> so that only the
+substitution result (<code>/new-app/handler</code>) is passed to
+subsequent rules or the final request.</p>
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_e" id="flag_e">E|env</a> <a title="Permanent link" href="#flag_e" class="permalink">¶</a></h2>
CustomLog directives.</p>
<p>The following example sets an environment variable called 'image' to a
-value of '1' if the requested URI is an image file. Then, that
+value of '1' if the requested URL-path is an image file. Then, that
environment variable is used to exclude those requests from the access
log.</p>
<p>Note that environment variables do not survive an external
redirect. You might consider using the [CO] flag to set a
-cookie. For per-directory rewrites, where the final
-substitution is processed as an internal redirect, environment
-variables from the previous round of rewriting are prefixed with
-"REDIRECT_". </p>
+cookie.</p>
+
+ <div class="note"><h3>REDIRECT_ prefix after internal redirects</h3>
+ <p>In <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a>,
+ a successful substitution triggers an internal redirect. When this
+ happens, all environment variables set during the previous pass —
+ including those created with <code>[E=VAR:VAL]</code> — are renamed
+ with a <code>REDIRECT_</code> prefix. A variable you set as
+ <code>rewritten</code> becomes <code>REDIRECT_rewritten</code> in
+ the redirected request.</p>
+
+ <p>To test for the renamed variable, reference it with the
+ prefix:</p>
+ </div>
+
+<pre class="prettyprint lang-config">RewriteRule "^/horses/(.*)" "/ponies/$1" [E=rewritten:1]
+
+# In the next pass, the variable has been renamed:
+RewriteCond "%{ENV:REDIRECT_rewritten}" =1
+RewriteRule "^/ponies/(.*)" "-" [E=seen_redirect:1,L]</pre>
+
+
+ <p>If the request is redirected multiple times, the prefix stacks:
+ <code>REDIRECT_REDIRECT_rewritten</code>, and so on. See
+ <a href="../env.html#redirect-vars">REDIRECT_ variables</a> for
+ the complete description of this mechanism.</p>
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_end" id="flag_end">END</a> <a title="Permanent link" href="#flag_end" class="permalink">¶</a></h2>
<p>This does not apply to new requests resulting from external
redirects.</p>
-<p>See the <a href="htaccess.html#loops">.htaccess looping</a>
+<p>See the <a href="htaccess.html#loops">Per-directory Rewrites</a>
discussion for a detailed explanation of why [L] behaves differently
in per-directory context, and when [END] is the right choice.</p>
<p>This example uses the "-" syntax for the rewrite target, which means
-that the requested URI is not modified. There's no reason to rewrite to
-another URI, if you're going to forbid the request.</p>
+that the requested URL-path is not modified. There's no reason to rewrite to
+another URL-path, if you're going to forbid the request.</p>
<p>When using [F], an [L] is implied - that is, the response is returned
immediately, and no further rules are evaluated.</p>
C. Use this flag to indicate that the current rule should be applied
immediately without considering further rules.</p>
-<p>If you are using <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> in either
-<code>.htaccess</code> files or in
-<code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> sections,
-it is important to have some understanding of how the rules are
-processed. The simplified form of this is that once the rules have been
-processed, the rewritten request is handed back to the URL parsing
-engine to do what it may with it. It is possible that as the rewritten
-request is handled, the <code>.htaccess</code> file or
-<code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> section
-may be encountered again, and thus the ruleset may be run again from the
-start. Most commonly this will happen if one of the rules causes a
-redirect - either internal or external - causing the request process to
-start over.</p>
-
-<p>It is therefore important, if you are using <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> directives in one of these
-contexts, that you take explicit steps to avoid rules looping, and not
-count solely on the [L] flag to terminate execution of a series of
-rules, as shown below.</p>
-
-<p> An alternative flag, [END], can be used to terminate not only the
-current round of rewrite processing but prevent any subsequent
-rewrite processing from occurring in per-directory (htaccess)
-context. This does not apply to new requests resulting from external
-redirects.</p>
+<p>In <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory</a> context,
+[L] stops the current pass through the ruleset, but the rewritten
+request may be re-processed from the top — which can cause loops.
+Use the <a href="#flag_end">[END]</a> flag to prevent this, or see
+the <a href="htaccess.html#loops">Per-directory Rewrites</a> document
+for a full discussion of the issue and alternative solutions.</p>
<p>The example given here will rewrite any request to
<code>index.php</code>, giving the original request as a query string
<pre class="prettyprint lang-config">RewriteRule "(.*)A(.*)" "$1B$2" [N]</pre>
<p>You can think of this as a <code>while</code> loop: While this
-pattern still matches (i.e., while the URI still contains an
+pattern still matches (i.e., while the URL-path still contains an
<code>A</code>), perform this substitution (i.e., replace the
<code>A</code> with a <code>B</code>).</p>
-<p>In 2.5.0 and later, this module returns an error after 10,000 iterations to
-protect against unintended looping. An alternative maximum number of
-iterations can be specified by adding to the N flag. </p>
-<pre class="prettyprint lang-config"># Be willing to replace 1 character in each pass of the loop
-RewriteRule "(.+)[><;]$" "$1" [N=32000]
-# ... or, give up if after 10 loops
-RewriteRule "(.+)[><;]$" "$1" [N=10]</pre>
-
+<p>Use with extreme caution. If no termination condition is met, this
+flag will cause the rule to loop indefinitely. In most cases you should
+use [L] instead of [N], unless you truly intend iterative processing.</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_nc" id="flag_nc">NC|nocase</a> <a title="Permanent link" href="#flag_nc" class="permalink">¶</a></h2>
<p>Use of the [NC] flag causes the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to be matched in a
case-insensitive manner. That is, it doesn't care whether letters appear
-as upper-case or lower-case in the matched URI.</p>
+as upper-case or lower-case in the matched URL-path.</p>
<p>In the example below, any request for an image file will be proxied
to your dedicated image server. The match is case-insensitive, so that
then result in a 404 Not Found error condition.
</p>
+<p>See <a href="tech.html#encoding">URL Encoding and Decoding</a> for
+the full picture of how Apache encodes and decodes URIs during
+rewriting.</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_ns" id="flag_ns">NS|nosubreq</a> <a title="Permanent link" href="#flag_ns" class="permalink">¶</a></h2>
are not subrequests - the browser requests them as separate HTTP
requests.
</p>
+
+<pre class="prettyprint lang-config"># Only rewrite direct requests to the front controller,
+# not subrequests from SSI includes or mod_dir.
+RewriteCond "%{REQUEST_FILENAME}" !-f
+RewriteCond "%{REQUEST_FILENAME}" !-d
+RewriteRule "^(.*)$" "/app/index.php?page=$1" [NS,L]</pre>
+
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_p" id="flag_p">P|proxy</a> <a title="Permanent link" href="#flag_p" class="permalink">¶</a></h2>
considered.</p>
<p>
-You must make sure that the substitution string is a valid URI
+You must make sure that the substitution string is a valid URL
(typically starting with <code>http://</code><em>hostname</em>) which can be
handled by the <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>. If not, you will get an
error from the proxy module. Use this flag to achieve a
<div class="warning">
<h3>Security Warning</h3>
<p>Take care when constructing the target URL of the rule, considering
-the security impact from allowing the client influence over the set of
-URLs to which your server will act as a proxy. Ensure that the scheme
-and hostname part of the URL is either fixed, or does not allow the
-client undue influence.</p>
+the security impact of allowing the client influence over the set of
+URLs to which your server will act as a proxy. If any part of the
+target URL is derived from user input (backreferences, query strings,
+etc.), an attacker may be able to cause your server to make requests
+to arbitrary internal or external hosts. This is known as a
+Server-Side Request Forgery (SSRF) vulnerability. Ensure that the
+scheme and hostname part of the URL is either fixed, or does not allow
+the client undue influence.</p>
</div>
<div class="warning">
<p>Note: <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> must be enabled in order
to use this flag.</p>
-<div class="warning"><h3>Security warning</h3>
-<p>Take care when constructing the target URL of the rule, considering
-the security impact of allowing the client influence over the set of
-URLs to which your server will act as a proxy. If any part of the
-target URL is derived from user input (backreferences, query strings,
-etc.), an attacker may be able to cause your server to make requests
-to arbitrary internal or external hosts. This is known as a
-Server-Side Request Forgery (SSRF) vulnerability.</p>
-</div>
-
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_pt" id="flag_pt">PT|passthrough</a> <a title="Permanent link" href="#flag_pt" class="permalink">¶</a></h2>
<p>
The target (or substitution string) in a RewriteRule is assumed to be a
file path, by default. The use of the [PT] flag causes it to be treated
-as a URI instead. That is to say, the
+as a URL-path instead. That is to say, the
use of the [PT] flag causes the result of the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to be passed back through
URL mapping, so that location-based mappings, such as <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code>, <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code>, or <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>, for example, might have a
chance to take effect.
<div class="section">
<h2><a name="flag_qsa" id="flag_qsa">QSA|qsappend</a> <a title="Permanent link" href="#flag_qsa" class="permalink">¶</a></h2>
<p>
-When the replacement URI contains a query string, the default behavior
+When the replacement URL contains a query string, the default behavior
of <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> is to discard
the existing query string, and replace it with the newly generated one.
Using the [QSA] flag causes the query strings to be combined.
<div class="section">
<h2><a name="flag_qsd" id="flag_qsd">QSD|qsdiscard</a> <a title="Permanent link" href="#flag_qsd" class="permalink">¶</a></h2>
<p>
-When the requested URI contains a query string, and the target URI does
+When the requested URL contains a query string, and the target URL does
not, the default behavior of <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> is to copy that query
-string to the target URI. Using the [QSD] flag causes the query string
+string to the target URL. Using the [QSD] flag causes the query string
to be discarded.
</p>
</p>
<p>
-If the target URI has a query string, the default behavior will be
+If the target URL has a query string, the default behavior will be
observed - that is, the original query string will be discarded and
replaced with the query string in the <code>RewriteRule</code> target
-URI.
+URL.
</p>
+<pre class="prettyprint lang-config"># Redirect old search URLs to the new path, discarding the query string.
+# /search?q=term&page=2 becomes /find (query string removed)
+RewriteRule "^/search" "/find" [QSD,R=301,L]</pre>
+
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_qsl" id="flag_qsl">QSL|qslast</a> <a title="Permanent link" href="#flag_qsl" class="permalink">¶</a></h2>
<p>
You will almost always want to use [R] in conjunction with [L] (that is,
use [R,L]) because on its own, the [R] flag prepends
-<code>http://thishost[:thisport]</code> to the URI, but then passes this
+<code>http://thishost[:thisport]</code> to the URL-path, but then passes this
on to the next rule in the ruleset, which can often result in 'Invalid
URI in request' warnings.
</p>
spec. Using an unrecognized status code will result in a 500 error and
error log message.</p>
+<div class="warning"><h3>[R=4xx] does not serve the substitution</h3>
+<p>When a status code outside the 300-399 range is specified (e.g.,
+<code>[R=403]</code> or <code>[R=410]</code>), the
+<em>substitution string is ignored</em>. The URL you wrote as the
+target is not served to the client. Instead, httpd returns the
+specified status code and handles it through the normal error
+response path (including any configured
+<code class="directive"><a href="../mod/core.html#errordocument">ErrorDocument</a></code>).
+If you want to deny access, the <a href="#flag_f">[F]</a> and
+<a href="#flag_g">[G]</a> flags are clearer ways to express the
+same intent.</p>
+</div>
+
+<pre class="prettyprint lang-config"># Redirect requests for the old docs path to the new location.
+RewriteRule "^/docs/(.*)$" "http://docs.example.com/$1" [R=301,L]</pre>
+
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_s" id="flag_s">S|skip</a> <a title="Permanent link" href="#flag_s" class="permalink">¶</a></h2>
RewriteCond</a></code> directives match). This can be thought of as a
<code>goto</code> statement in your rewrite ruleset. In the following
example, we only want to run the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">
-RewriteRule</a></code> if the requested URI doesn't correspond with an
+RewriteRule</a></code> if the requested URL-path doesn't correspond with an
actual file.</p>
<pre class="prettyprint lang-config"># Is the request for a non-existent file?
rewritten result has a '?' in the substitution. This protects from a malicious
URL taking advantage of a capture and re-substitution of the encoded
question mark.</p>
+
+<pre class="prettyprint lang-config"># A PHP front controller that routes all requests via a query parameter.
+# Without UnsafeAllow3F, a request like /page%3Fname=test would return
+# 403 Forbidden because the rewritten substitution contains '?' while
+# the original request contains an encoded '%3F'.
+RewriteCond "%{REQUEST_FILENAME}" !-f
+RewriteCond "%{REQUEST_FILENAME}" !-d
+RewriteRule "(.+)" "index.php?route=$1" [L,QSA,UnsafeAllow3F]</pre>
+
+
+<div class="warning">
+This flag exists because of <a href="https://www.cve.org/CVERecord?id=CVE-2024-38474">CVE-2024-38474</a>.
+Use it only on rules where you are certain that user-supplied <code>%3F</code>
+in the request cannot be exploited to manipulate the query string of the
+substitution target. Prefer restructuring URLs to avoid encoded question
+marks where possible.
+</div>
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_unsafe_prefix_stat" id="flag_unsafe_prefix_stat">UnsafePrefixStat</a> <a title="Permanent link" href="#flag_unsafe_prefix_stat" class="permalink">¶</a></h2>
This protects from a malicious URL causing the expanded substitution to
map to an unexpected filesystem location.</p>
- <p>Available in Apache HTTP Server 2.5.1 and later.</p>
+ <p>Available in Apache HTTP Server 2.4.60 and later.</p>
+
+<pre class="prettyprint lang-config"># This rule starts the substitution with a backreference.
+# Since 2.4.60, this is rejected by default to prevent the expanded
+# path from escaping the document root (CVE-2024-38475).
+# Only add UnsafePrefixStat after verifying the substitution cannot
+# resolve to a filesystem path outside your web root.
+RewriteRule "^/mirror/(.+)$" "$1" [PT,UnsafePrefixStat]</pre>
+
+
+<div class="warning">
+This flag exists because of <a href="https://www.cve.org/CVERecord?id=CVE-2024-38475">CVE-2024-38475</a>.
+Without it, a substitution beginning with a backreference or variable
+that happens to match an existing filesystem path could allow requests
+to escape the document root. Use this flag only after confirming that
+the substitution is adequately constrained.
+</div>
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="flag_unc" id="flag_unc">UNC</a> <a title="Permanent link" href="#flag_unc" class="permalink">¶</a></h2>
as used in Windows UNC paths. The flag is not necessary when the rules
substitution starts with multiple literal slashes.</p>
- <p>Available in Apache HTTP Server 2.5.1 and later.</p>
+ <p>Available in Apache HTTP Server 2.4.63 and later.</p>
+
+<pre class="prettyprint lang-config"># On Windows, rewrite to a UNC file share using a variable.
+# Without [UNC], the leading slashes in the substitution would be
+# collapsed (//server/share becomes /server/share).
+RewriteCond "%{HTTP_HOST}" "^(.+)\.internal$"
+RewriteRule "^/shared/(.*)$" "//%1/fileshare/$1" [UNC]</pre>
+
+
+<p>This flag is only relevant on Windows. It prevents Apache from
+merging the leading double slash (<code>//</code>) that denotes a
+UNC path when the path is constructed from a backreference or
+variable. If the substitution begins with literal double slashes,
+no flag is needed.</p>
+
</div></div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/rewrite/flags.html" title="English"> en </a> |
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
-<!-- English Revision: 1933063:1934606 (outdated) -->
+<!-- English Revision: 1933063:1934664 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
This file is generated from xml source: DO NOT EDIT
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-->
-<title>mod_rewrite and .htaccess files - Apache HTTP Server Version 2.4</title>
+<title>Per-directory Rewrites - Apache HTTP Server Version 2.4</title>
<link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
<link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
<link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
<img alt="" src="../images/feather.png" /></div>
<div class="up"><a href="./"><img title="<-" alt="<-" src="../images/left.gif" /></a></div>
<div id="path">
-<a href="https://www.apache.org/">Apache</a> > <a href="https://httpd.apache.org/">HTTP Server</a> > <a href="https://httpd.apache.org/docs/">Documentation</a> > <a href="../">Version 2.4</a> > <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>mod_rewrite and .htaccess files</h1>
+<a href="https://www.apache.org/">Apache</a> > <a href="https://httpd.apache.org/">HTTP Server</a> > <a href="https://httpd.apache.org/docs/">Documentation</a> > <a href="../">Version 2.4</a> > <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Per-directory Rewrites</h1>
<button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12" /><line y2="12" x2="22" y1="12" x1="2" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></button>
<div class="toplang">
<p><span>Available Languages: </span><a href="../en/rewrite/htaccess.html" title="English"> en </a> |
-<a href="../fr/rewrite/htaccess.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/htaccess.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div>
<li><img alt="" src="../images/down.gif" /> <a href="#loops">The [L] flag and looping</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#rewritemap-restriction">RewriteMap cannot be
declared in .htaccess</a></li>
+<li><img alt="" src="../images/down.gif" /> <a href="#context-restrictions">Which contexts support rewrite rules?</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#inheritance">Rule inheritance with RewriteOptions</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#debugging">Debugging .htaccess rewrite rules</a></li>
-<li><img alt="" src="../images/down.gif" /> <a href="#context-restrictions">Which contexts support rewrite rules?</a></li>
+<li><img alt="" src="../images/down.gif" /> <a href="#caching">Browser caching of 301 redirects</a></li>
</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="flags.html">RewriteRule Flags</a></li><li><a href="tech.html">Technical details</a></li><li><a href="../mod/mod_rewrite.html#what_is_matched">What is matched?</a></li></ul></div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
in either the pattern or the substitution. This is the single most
common source of confusion with per-directory rewriting.</p>
+<p>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 <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> directive
+determines what URL-path prefix is prepended. This subrequest
+mechanism is also why rules can loop — see
+<a href="#loops">below</a>.</p>
+
+
+<div class="warning"><h3>Do not start .htaccess patterns with /</h3>
+<p>Because the directory prefix (including the trailing
+slash) is stripped before matching, patterns in
+<a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a>
+will <em>never</em> match a leading slash. A pattern
+beginning with <code>^/</code> will never match in this
+context. A rule like <code>RewriteRule "^/foo" ...</code> will
+silently fail to match anything when placed in a
+<code>.htaccess</code> file.</p>
+</div>
+
+<p>If you need to match against the full original
+URL-path (including the directory prefix), use
+<code>%{REQUEST_URI}</code> in a
+<code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>:</p>
+
+<pre class="prettyprint lang-config">RewriteCond "%{REQUEST_URI}" "^/admin/"
+RewriteRule "^.*$" "-" [F]</pre>
+
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="rewritebase" id="rewritebase">When you need RewriteBase</a> <a title="Permanent link" href="#rewritebase" class="permalink">¶</a></h2>
<div class="note">For this particular use case - routing all unmatched
requests to a front controller - the
-<a href="remapping.html#fallback-resource">FallbackResource</a> directive
+<a href="avoid.html#fallback-resource">FallbackResource</a> directive
is a simpler and more efficient alternative to mod_rewrite.</div>
<p>Without the <code>RewriteBase "/myapp/"</code> line, the rewritten
<code>dbm:</code>, <code>dbd:</code>, and <code>prg:</code> map types)
would be prohibitively expensive to repeat each time.</p>
+</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
+<div class="section">
+<h2><a name="context-restrictions" id="context-restrictions">Which contexts support rewrite rules?</a> <a title="Permanent link" href="#context-restrictions" class="permalink">¶</a></h2>
+
+<p>Rewrite rules are supported in
+<a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a>
+(<a href="../howto/htaccess.html">.htaccess</a> files,
+<code class="directive"><a href="../mod/core.html#directory"><Directory></a></code>, and
+<code class="directive"><a href="../mod/core.html#if"><If></a></code> blocks).</p>
+
+<p>Although rewrite rules are syntactically permitted in
+<code class="directive"><a href="../mod/core.html#location"><Location></a></code>
+and <code class="directive"><a href="../mod/core.html#files"><Files></a></code>
+sections (including their regex counterparts), this is
+unsupported and should never be necessary. Relative
+substitutions, in particular, are likely to break in
+these contexts.</p>
+
+<div class="warning"><h3>These containers silently change rewrite
+behavior</h3>
+<p>Placing a <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
+inside a <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code>,
+<code class="directive"><a href="../mod/core.html#if"><If></a></code>, or
+<code class="directive"><a href="../mod/core.html#location"><Location></a></code> block
+— even inside a
+<code class="directive"><a href="../mod/core.html#virtualhost"><VirtualHost></a></code> in the
+main server config — silently switches to
+<a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a> behavior.
+This means the leading slash is stripped from the URL before pattern
+matching, substitutions trigger an internal redirect (with loop risk),
+and the <a href="../rewrite/flags.html#flag_l">[L]</a> flag no longer
+truly stops processing — use
+<a href="../rewrite/flags.html#flag_end">[END]</a> instead.</p>
+</div>
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="inheritance" id="inheritance">Rule inheritance with RewriteOptions</a> <a title="Permanent link" href="#inheritance" class="permalink">¶</a></h2>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
-<h2><a name="context-restrictions" id="context-restrictions">Which contexts support rewrite rules?</a> <a title="Permanent link" href="#context-restrictions" class="permalink">¶</a></h2>
-
-<p>Rewrite rules are supported in
-<a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a>
-(<a href="../howto/htaccess.html">.htaccess</a> files,
-<code class="directive"><a href="../mod/core.html#directory"><Directory></a></code>, and
-<code class="directive"><a href="../mod/core.html#if"><If></a></code> blocks).</p>
-
-<p>Although rewrite rules are syntactically permitted in
-<code class="directive"><a href="../mod/core.html#location"><Location></a></code>
-and <code class="directive"><a href="../mod/core.html#files"><Files></a></code>
-sections (including their regex counterparts), this is
-unsupported and should never be necessary. Relative
-substitutions, in particular, are likely to break in
-these contexts.</p>
-
-<div class="warning"><h3>These containers silently change rewrite
-behavior</h3>
-<p>Placing a <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
-inside a <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code>,
-<code class="directive"><a href="../mod/core.html#if"><If></a></code>, or
-<code class="directive"><a href="../mod/core.html#location"><Location></a></code> block
-— even inside a
-<code class="directive"><a href="../mod/core.html#virtualhost"><VirtualHost></a></code> in the
-main server config — silently switches to
-<a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a> behavior.
-This means the leading slash is stripped from the URL before pattern
-matching, substitutions trigger an internal redirect (with loop risk),
-and the <a href="../rewrite/flags.html#flag_l">[L]</a> flag no longer
-truly stops processing — use
-<a href="../rewrite/flags.html#flag_end">[END]</a> instead.</p>
-</div>
+<h2><a name="caching" id="caching">Browser caching of 301 redirects</a> <a title="Permanent link" href="#caching" class="permalink">¶</a></h2>
+
+<p>When you issue a <code>301 Moved Permanently</code> redirect
+(via <code>[R=301]</code> or <code class="directive"><a href="../mod/mod_alias.html#redirect permanent">Redirect permanent</a></code>), the browser is allowed to cache
+that response indefinitely. This means that even after you fix an
+incorrect redirect rule in your configuration, returning visitors
+may continue to be sent to the old (wrong) destination without
+ever contacting your server again.</p>
+
+<p>While debugging redirect rules, use <code>[R=302]</code>
+(temporary redirect) instead of <code>[R=301]</code>. Switch to 301
+only after you have confirmed the rule is correct. If you have
+already issued an incorrect 301, affected users will need to clear
+their browser cache (or use a private/incognito window) to see
+the corrected behavior.</p>
+
+<div class="note">Search engines also cache 301 redirects. An incorrect 301
+may take days or weeks to be re-crawled, even after the
+configuration is fixed. This is another reason to test with 302
+first.</div>
</div></div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/rewrite/htaccess.html" title="English"> en </a> |
-<a href="../fr/rewrite/htaccess.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/htaccess.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div><div id="footer">
<p class="apache">Copyright 2026 The Apache Software Foundation.<br />Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
<?xml version="1.0" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
-<!-- English Revision: 1933066:1934452 (outdated) -->
+<!-- English Revision: 1933066:1934664 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
<button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12" /><line y2="12" x2="22" y1="12" x1="2" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></button>
<div class="toplang">
<p><span>Available Languages: </span><a href="../en/rewrite/" title="English"> en </a> |
-<a href="../fr/rewrite/" hreflang="fr" rel="alternate" title=""> fr </a> |
-<a href="../tr/rewrite/" hreflang="tr" rel="alternate" title=""> tr </a> |
+<a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français"> fr </a> |
+<a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe"> tr </a> |
<a href="../zh-cn/rewrite/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese"> zh-cn </a></p>
</div>
+<p><em>The great thing about mod_rewrite is it gives you all the
+configurability and flexibility of Sendmail. The downside to
+mod_rewrite is that it gives you all the configurability and
+flexibility of Sendmail.</em>
+-- Brian Behlendorf</p>
+
+<p><em>Despite the tons of examples and docs, mod_rewrite is voodoo.
+Damned cool voodoo, but still voodoo.</em>
+-- Brian Moore</p>
+
<p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> provides a way to modify incoming
URL requests, dynamically, based on <a href="intro.html#regex">regular
expression</a> rules. This allows you to map arbitrary URLs onto
your internal URL structure in any way you like.</p>
- <p>It supports an unlimited number of rules and an
- unlimited number of attached rule conditions for each rule to
- provide a really flexible and powerful URL manipulation
- mechanism. The URL manipulations can depend on various tests:
- server variables, environment variables, HTTP
- headers, time stamps, external database lookups, and various other
- external programs or handlers, can be used to achieve granular URL
- matching.</p>
+ <p>This guide supplements <a href="../mod/mod_rewrite.html">the
+ reference manual</a> with annotated examples, conceptual
+ explanations, and practical advice. It is organized as follows:</p>
+
+<dl>
+<dt><a href="intro.html">Introduction</a></dt>
+<dd>Core concepts: regular expression syntax, RewriteRule and
+RewriteCond basics, and how mod_rewrite fits into the request
+processing lifecycle.</dd>
+
+<dt><a href="htaccess.html">Per-directory Rewrites</a></dt>
+<dd>The key differences between using rewrite rules in server
+configuration versus <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory</a>
+context, including path stripping, RewriteBase, and the looping behavior
+of the [L] flag.</dd>
+
+<dt><a href="flags.html">RewriteRule Flags</a></dt>
+<dd>A complete reference for all flags that can modify the behavior of
+a RewriteRule, with examples for each.</dd>
+
+<dt><a href="rewritemap.html">Using RewriteMap</a></dt>
+<dd>How to use external lookup sources — text files, DBM databases,
+SQL queries, and internal functions — to drive your rewrite
+rules.</dd>
- <p>Rewrite rules can operate on the full URLs, including the path-info
- and query string portions, and may be used in per-server context
- (<code>httpd.conf</code>), per-virtualhost context (<code class="directive"><a href="../mod/core.html#virtualhost"><VirtualHost></a></code> blocks), or
- <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a>
- (<code>.htaccess</code> files and <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> blocks). The
- rewritten result can lead to further rules, internal
- sub-processing, external request redirection, or proxy
- passthrough, depending on what <a href="flags.html">flags</a> you
- attach to the rules.</p>
+<dt><a href="remapping.html">Redirection and Remapping</a></dt>
+<dd>Recipes for common tasks: HTTPS redirection, canonical hostnames,
+trailing slash normalization, front-controller routing, and more.</dd>
- <p>Since <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> is so powerful, it can indeed be rather
- complex. This guide supplements the <a href="../mod/mod_rewrite.html">reference documentation</a>, and
- attempts to allay some of that complexity, and provide highly
- annotated examples of common scenarios that you may handle with
- <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. But we also attempt to show you when you should not
- use <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>, and use other standard Apache features instead,
- thus avoiding this unnecessary complexity.</p>
+<dt><a href="vhosts.html">Dynamic Virtual Hosts</a></dt>
+<dd>Using mod_rewrite to dynamically map hostnames to document roots
+without individual VirtualHost blocks.</dd>
+<dt><a href="avoid.html">When NOT to use mod_rewrite</a></dt>
+<dd>Many common tasks are better accomplished with simpler directives.
+This document shows the alternatives and when to prefer them.</dd>
-<ul>
-<li><a href="../mod/mod_rewrite.html">mod_rewrite reference
-documentation</a></li>
-<li><a href="intro.html">Introduction to regular expressions and mod_rewrite</a></li>
-<li><a href="htaccess.html">mod_rewrite in .htaccess files</a></li>
-<li><a href="flags.html">RewriteRule Flags</a></li>
-<li><a href="rewritemap.html">Using RewriteMap</a></li>
-<li><a href="avoid.html">When <strong>NOT</strong> to use mod_rewrite</a></li>
-<li><a href="remapping.html">Using mod_rewrite for redirection and remapping of URLs</a></li>
-<li><a href="vhosts.html">Dynamic virtual hosts with mod_rewrite</a></li>
-<li><a href="tech.html">Technical details</a></li>
-</ul>
+<dt><a href="tech.html">Technical Details</a></dt>
+<dd>How mod_rewrite hooks into the Apache request processing phases,
+and the order in which rules and conditions are evaluated.</dd>
+</dl>
</div>
-<div id="quickview"><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">mod_rewrite reference
-documentation</a></li><li><a href="../urlmapping.html">Mapping URLs to the Filesystem</a></li><li><a href="https://cwiki.apache.org/confluence/display/httpd/Rewrite">mod_rewrite
+<div id="quickview"><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">mod_rewrite Reference Documentation</a></li><li><a href="../urlmapping.html">Mapping URLs to the Filesystem</a></li><li><a href="https://cwiki.apache.org/confluence/display/httpd/Rewrite">mod_rewrite
wiki</a></li><li><a href="../glossary.html">Glossary</a></li></ul></div>
</div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/rewrite/" title="English"> en </a> |
-<a href="../fr/rewrite/" hreflang="fr" rel="alternate" title=""> fr </a> |
-<a href="../tr/rewrite/" hreflang="tr" rel="alternate" title=""> tr </a> |
+<a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français"> fr </a> |
+<a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe"> tr </a> |
<a href="../zh-cn/rewrite/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese"> zh-cn </a></p>
</div><div id="footer">
<p class="apache">Copyright 2026 The Apache Software Foundation.<br />Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
<a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe"> tr </a> |
<a href="../zh-cn/rewrite/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese"> zh-cn </a></p>
</div>
+<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version
+ anglaise pour les changements récents.</div>
<p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> permet de modifier les requêtes
<button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12" /><line y2="12" x2="22" y1="12" x1="2" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></button>
<div class="toplang">
<p><span>可用语言: </span><a href="../en/rewrite/" hreflang="en" rel="alternate" title="English"> en </a> |
-<a href="../fr/rewrite/" hreflang="fr" rel="alternate" title=""> fr </a> |
-<a href="../tr/rewrite/" hreflang="tr" rel="alternate" title=""> tr </a> |
+<a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français"> fr </a> |
+<a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe"> tr </a> |
<a href="../zh-cn/rewrite/" title="Simplified Chinese"> zh-cn </a></p>
</div>
<div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
</div>
<div class="bottomlang">
<p><span>可用语言: </span><a href="../en/rewrite/" hreflang="en" rel="alternate" title="English"> en </a> |
-<a href="../fr/rewrite/" hreflang="fr" rel="alternate" title=""> fr </a> |
-<a href="../tr/rewrite/" hreflang="tr" rel="alternate" title=""> tr </a> |
+<a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français"> fr </a> |
+<a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe"> tr </a> |
<a href="../zh-cn/rewrite/" title="Simplified Chinese"> zh-cn </a></p>
</div><div id="footer">
<p class="apache">Copyright 2026 The Apache Software Foundation.<br />基于 <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
<?xml version="1.0" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
-<!-- English Revision: 1933954 -->
+<!-- English Revision: 1933954:1934664 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
<variants>
<variant>en</variant>
- <variant>fr</variant>
+ <variant outdated="yes">fr</variant>
<variant outdated="yes">tr</variant>
<variant outdated="yes">zh-cn</variant>
</variants>
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.tr.xsl"?>
-<!-- English Revision: 1328305:1933954 (outdated) -->
+<!-- English Revision: 1328305:1934664 (outdated) -->
<!-- =====================================================
Translated by: Nilgün Belma Bugüner <nilgun belgeler.gen.tr>
Reviewed by: Orhan Berent <berent belgeler.gen.tr>
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.zh-cn.xsl"?>
-<!-- English Revision: 1028730:1933954 (outdated) -->
+<!-- English Revision: 1028730:1934664 (outdated) -->
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
<li><img alt="" src="../images/down.gif" /> <a href="#rewritemap">Rewrite maps</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#htaccess">.htaccess files</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#security">Security Considerations</a></li>
-</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li></ul></div>
+</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="htaccess.html">Per-directory Rewrites</a></li><li><a href="flags.html">RewriteRule Flags</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="tech.html">Technical details</a></li></ul></div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="introduction" id="introduction">Introduction</a> <a title="Permanent link" href="#introduction" class="permalink">¶</a></h2>
<div class="section">
<h2><a name="regex" id="regex">Regular Expressions</a> <a title="Permanent link" href="#regex" class="permalink">¶</a></h2>
-<p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> uses the <a href="https://www.pcre.org/">Perl Compatible
-Regular Expression</a> vocabulary. In this document, we do not attempt
+<p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> uses the <a href="https://www.pcre.org/current/doc/html/pcre2syntax.html">Perl Compatible
+Regular Expressions</a> vocabulary, via the PCRE2 library. In this document, we do not attempt
to provide a detailed reference to regular expressions. For that, we
-recommend the <a href="https://www.pcre.org/pcre.txt">PCRE man pages</a>, the
+recommend the <a href="https://www.pcre.org/current/doc/html/pcre2syntax.html">PCRE2 documentation</a>, the
<a href="https://perldoc.perl.org/perlre">Perl regular
-expression man page</a>, and <a href="https://www.oreilly.com/library/view/mastering-regular-expressions/0596528124/">Mastering
+expressions man page</a>, and <a href="https://www.oreilly.com/library/view/mastering-regular-expressions/0596528124/">Mastering
Regular Expressions, by Jeffrey Friedl</a> (the third edition is from
2006, but regular expression syntax is essentially unchanged, and this
remains the definitive reference on the subject).</p>
</ol>
<p>The <var>Pattern</var> is a <a href="#regex">regular expression</a>.
-It is initially (for the first rewrite rule or until a substitution occurs)
-matched against the URL-path of the incoming request (the part after the
-hostname but before any question mark indicating the beginning of a query
-string) or, in per-directory context, against the request's path relative
-to the directory for which the rule is defined. Once a substitution has
-occurred, the rules that follow are matched against the substituted
-value.
+In server or virtualhost context, it is matched against the
+%-decoded <a href="../directive-dict.html#Syntax">URL-path</a>
+of the incoming request — the part after the hostname and port,
+and not including the query string (e.g., <code>/app/index.html</code>).
+In <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a>,
+the pattern is matched against the request's path relative to the
+directory for which the rule is defined (with the directory prefix
+stripped — see <a href="htaccess.html#path-stripping">Per-directory
+Rewrites</a> for details).
</p>
+<p>Once a substitution has occurred, any rules that follow are
+matched against the substituted value.</p>
+
+<p>The <var>Pattern</var> is matched only against the URL-path
+— not the hostname, port, or query string. To match against
+those, use a
+<code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> with the
+<code>%{HTTP_HOST}</code>, <code>%{SERVER_PORT}</code>, or
+<code>%{QUERY_STRING}</code> variables respectively.</p>
+
+<div class="note"><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> operates entirely on the URL-path
+and HTTP headers. It cannot inspect the request body (e.g., POST
+data). If you need to make routing decisions based on request body
+content, handle that in your application logic or use a module such
+as <code class="module"><a href="../mod/mod_request.html">mod_request</a></code> paired with a custom filter.</div>
+
<p class="figure">
<img src="../images/syntax_rewriterule.png" alt="Syntax of the RewriteRule directive" /><br />
<dfn>Figure 2:</dfn> Syntax of the RewriteRule directive.
<div class="section">
<h2><a name="htaccess" id="htaccess">.htaccess files</a> <a title="Permanent link" href="#htaccess" class="permalink">¶</a></h2>
-<p>Rewriting is typically configured in the main server configuration
-setting (outside any <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> section) or
-inside <code class="directive"><a href="../mod/core.html#virtualhost"><VirtualHost></a></code>
-containers. This is the easiest way to do rewriting and is
-recommended. It is possible, however, to do rewriting
-inside <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code>
-sections or <a href="../howto/htaccess.html"><code>.htaccess</code>
-files</a> at the expense of some additional complexity. This technique
-is called <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory</a> rewrites.
-Note that
+<p>It is possible to use rewrite rules in
+<a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory</a> context
+(<a href="../howto/htaccess.html"><code>.htaccess</code> files</a> and
+<code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> blocks),
+but the rules behave differently there — in particular, the directory
+prefix is stripped from the URL before matching. See the
+<a href="htaccess.html#path-stripping">Per-directory Rewrites</a>
+document for full details. Note that
<code class="directive"><a href="../mod/core.html#if"><If></a></code> and
<code class="directive"><a href="../mod/core.html#location"><Location></a></code> blocks
also trigger per-directory behavior — see
<a href="htaccess.html#context-restrictions">Which contexts support rewrite rules?</a>.</p>
-<p>The main difference from per-server rewrites is that the path
-prefix of the directory containing the <code>.htaccess</code> file is
-stripped before matching in
-the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>. In addition, the <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> should be used to assure the request is properly mapped.</p>
-
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="security" id="security">Security Considerations</a> <a title="Permanent link" href="#security" class="permalink">¶</a></h2>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
-<!-- English Revision: 1933424:1934624 (outdated) -->
+<!-- English Revision: 1933424:1934664 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
<button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12" /><line y2="12" x2="22" y1="12" x1="2" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></button>
<div class="toplang">
<p><span>Available Languages: </span><a href="../en/rewrite/remapping.html" title="English"> en </a> |
-<a href="../fr/rewrite/remapping.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/remapping.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div>
</div>
<div id="quickview"><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#old-to-new">From Old to New (internal)</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#https-redirect">Forcing HTTPS</a></li>
+<li><img alt="" src="../images/down.gif" /> <a href="#acme-exemption">Exempting ACME challenge requests from HTTPS redirect</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#trailing-slash">Trailing Slash Normalization</a></li>
-<li><img alt="" src="../images/down.gif" /> <a href="#www-resolve">Canonical www/non-www Hostname</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#front-controller">Front Controller / Application Routing</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#old-to-new-extern">Rewriting From Old to New (external)</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#movehomedirs">Resource Moved to Another Server</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#multipledirs">Search for pages in more than one directory</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#canonicalurl">Canonical URLs</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#moveddocroot">Moved <code>DocumentRoot</code></a></li>
-<li><img alt="" src="../images/down.gif" /> <a href="#fallback-resource">Fallback Resource</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#rewrite-query">Rewrite query string</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#structuredhomedirs">Structured Userdirs</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#redirectanchors">Redirecting Anchors</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#time-dependent">Time-Dependent Rewriting</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#on-the-fly-content">On-the-fly Content-Regeneration</a></li>
-</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li></ul></div>
+</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="htaccess.html">Per-directory Rewrites</a></li><li><a href="flags.html">RewriteRule Flags</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="tech.html">Technical details</a></li></ul></div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="old-to-new" id="old-to-new">From Old to New (internal)</a> <a title="Permanent link" href="#old-to-new" class="permalink">¶</a></h2>
<p>See also the <a href="avoid.html#redirect">When not to use
mod_rewrite</a> document for more discussion of the
<code>Redirect</code> approach.</p>
+
+ <div class="note"><h3>Behind a load balancer or SSL terminator</h3>
+ <p>The <code>%{HTTPS}</code> variable is not a general-purpose
+ environment variable — it queries <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>
+ directly. If SSL/TLS is terminated at an upstream load balancer
+ or reverse proxy, <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> is not handling the
+ connection and <code>%{HTTPS}</code> will always report
+ <code>off</code>, even when the original client connected over
+ HTTPS.</p>
+
+ <p>In this situation, check the header set by the upstream proxy
+ instead. Most load balancers set
+ <code>X-Forwarded-Proto</code>:</p>
+ </div>
+
+<pre class="prettyprint lang-config">RewriteEngine On
+RewriteCond "%{HTTP:X-Forwarded-Proto}" =http [NC]
+RewriteRule "^(.*)" "https://%{SERVER_NAME}$1" [R=301,L]</pre>
+
+
+ <div class="warning">
+ <p>Only trust <code>X-Forwarded-Proto</code> if you control the
+ upstream proxy and it overwrites the header on every request. An
+ attacker can forge this header when connecting directly to your
+ server. Consider restricting access so that only your load
+ balancer can reach the backend, or use
+ <code class="module"><a href="../mod/mod_remoteip.html">mod_remoteip</a></code> to validate the source.</p>
+ </div>
+
</dd>
</dl>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
-<h2><a name="trailing-slash" id="trailing-slash">Trailing Slash Normalization</a> <a title="Permanent link" href="#trailing-slash" class="permalink">¶</a></h2>
+<h2><a name="acme-exemption" id="acme-exemption">Exempting ACME challenge requests from HTTPS redirect</a> <a title="Permanent link" href="#acme-exemption" class="permalink">¶</a></h2>
<dt>Description:</dt>
<dd>
- <p>You want to ensure that URLs for directories always end with
- a trailing slash, or conversely, that they never do. This is a
- common requirement for SEO and for consistent URL handling by
- web applications.</p>
+ <p>You have forced all traffic to HTTPS (as above), but your
+ ACME client (Let's Encrypt, Certbot, etc.) needs plain HTTP
+ access to <code>/.well-known/acme-challenge/</code> to complete
+ domain validation.</p>
</dd>
<dt>Solution:</dt>
<dd>
- <p>To add a trailing slash to URLs that map to directories:</p>
+ <p>Place an exception <em>before</em> your HTTPS redirect
+ rule:</p>
-<pre class="prettyprint lang-config">RewriteCond "%{REQUEST_FILENAME}" -d
-RewriteCond "%{REQUEST_URI}" "!/$"
-RewriteRule "^(.*)$" "$1/" [R=301,L]</pre>
+<pre class="prettyprint lang-config">RewriteEngine On
+RewriteRule "^/\.well-known/acme-challenge/" - [L]
+RewriteCond "%{HTTPS}" !=on
+RewriteRule "^(.*)" "https://%{SERVER_NAME}$1" [R=301,L]</pre>
+ </dd>
- <p>To remove a trailing slash (except for actual directories):</p>
+ <dt>Discussion:</dt>
-<pre class="prettyprint lang-config">RewriteCond "%{REQUEST_FILENAME}" !-d
-RewriteCond "%{REQUEST_URI}" "(.+)/$"
-RewriteRule "^" "%1" [R=301,L]</pre>
+ <dd>
+ <p>The dash (<code>-</code>) substitution means "do not rewrite."
+ Combined with <code>[L]</code>, it stops rule processing for any
+ request matching the ACME challenge path, allowing it to be
+ served over plain HTTP. All other requests continue to the
+ next rule and are redirected to HTTPS as usual.</p>
+ <p>If you are using the <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code> approach in a dedicated
+ port-80 VirtualHost, use an
+ <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> and
+ <code class="directive"><a href="../mod/mod_alias.html#redirectmatch">RedirectMatch</a></code>
+ instead:</p>
- </dd>
+<pre class="prettyprint lang-config"><VirtualHost *:80>
+ ServerName www.example.com
+
+ # Allow ACME challenges over HTTP
+ Alias "/.well-known/acme-challenge/" "/var/www/acme/.well-known/acme-challenge/"
+ <Directory "/var/www/acme/.well-known/acme-challenge">
+ Require all granted
+ </Directory>
+
+ # Everything else goes to HTTPS
+ RedirectMatch permanent "^/(?!\.well-known/acme-challenge/)" "https://www.example.com/$0"
+</VirtualHost></pre>
- <dt>Discussion:</dt>
- <dd>
- <p>Apache's <code class="module"><a href="../mod/mod_dir.html">mod_dir</a></code> already handles trailing
- slash redirects for real directories when
- <code class="directive"><a href="../mod/mod_dir.html#directoryslash">DirectorySlash</a></code> is enabled
- (the default). You only need a <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> rule
- if you want to enforce trailing slash behavior for URLs that do
- not correspond to actual directories on disk, or if you want to
- remove trailing slashes.</p>
</dd>
</dl>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
-<h2><a name="www-resolve" id="www-resolve">Canonical www/non-www Hostname</a> <a title="Permanent link" href="#www-resolve" class="permalink">¶</a></h2>
+<h2><a name="trailing-slash" id="trailing-slash">Trailing Slash Normalization</a> <a title="Permanent link" href="#trailing-slash" class="permalink">¶</a></h2>
<dt>Description:</dt>
<dd>
- <p>You want to force all requests to use either
- <code>www.example.com</code> or <code>example.com</code>,
- not both. This ensures search engines treat them as one site
- and prevents cookie scope issues.</p>
+ <p>You want to ensure that URLs for directories always end with
+ a trailing slash, or conversely, that they never do. This is a
+ common requirement for SEO and for consistent URL handling by
+ web applications.</p>
</dd>
<dt>Solution:</dt>
<dd>
- <p>The best approach does not use <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> at
- all. Place a <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code>
- in the virtual host for the non-canonical hostname:</p>
-
-<pre class="prettyprint lang-config"># Redirect example.com -> www.example.com
-<VirtualHost *:80 *:443>
- ServerName example.com
- Redirect permanent "/" "https://www.example.com/"
-</VirtualHost></pre>
-
+ <p>To add a trailing slash to URLs that map to directories:</p>
- <p>If you only have <code>.htaccess</code> access:</p>
+<pre class="prettyprint lang-config">RewriteCond "%{REQUEST_FILENAME}" -d
+RewriteCond "%{REQUEST_URI}" "!/$"
+RewriteRule "^(.*)$" "$1/" [R=301,L]</pre>
-<pre class="prettyprint lang-config"># Add www
-RewriteEngine On
-RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
-RewriteRule "^(.*)" "https://www.%{HTTP_HOST}$1" [R=301,L]</pre>
+ <p>To remove a trailing slash (except for actual directories):</p>
-<pre class="prettyprint lang-config"># Remove www
-RewriteEngine On
-RewriteCond "%{HTTP_HOST}" "^www\.(.+)$" [NC]
-RewriteRule "^(.*)" "https://%1$1" [R=301,L]</pre>
+<pre class="prettyprint lang-config">RewriteCond "%{REQUEST_FILENAME}" !-d
+RewriteCond "%{REQUEST_URI}" "(.+)/$"
+RewriteRule "^" "%1" [R=301,L]</pre>
</dd>
<dt>Discussion:</dt>
<dd>
- <p>See also the <a href="#canonicalhost">Canonical Hostnames</a>
- recipe above, which covers the general case. This recipe focuses
- specifically on the www/non-www choice, which is the most common
- hostname canonicalization need.</p>
+ <p>Apache's <code class="module"><a href="../mod/mod_dir.html">mod_dir</a></code> already handles trailing
+ slash redirects for real directories when
+ <code class="directive"><a href="../mod/mod_dir.html#directoryslash">DirectorySlash</a></code> is enabled
+ (the default). You only need a <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> rule
+ if you want to enforce trailing slash behavior for URLs that do
+ not correspond to actual directories on disk, or if you want to
+ remove trailing slashes.</p>
</dd>
</dl>
- <dl>
- <dt>Description:</dt>
-
- <dd>
- <p>Most modern web frameworks (PHP, Python, Ruby, etc.) use a
- single entry point - often called a "front controller" - that
- handles all requests. URLs like <code>/products/widget</code>
- are routed to <code>index.php</code> (or equivalent), which
- parses the URL internally.</p>
- </dd>
-
- <dt>Solution:</dt>
-
- <dd>
-
- <div class="note">For this use case, the
- <code class="directive"><a href="../mod/mod_dir.html#fallbackresource">FallbackResource</a></code> directive is
- almost always the better choice. See the
- <a href="#fallback-resource">Fallback Resource</a> recipe above.</div>
-
- <p>If you need <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> (for example, to add
- additional conditions), the standard pattern is:</p>
-
-<pre class="prettyprint lang-config">RewriteEngine On
-RewriteCond "%{REQUEST_FILENAME}" !-f
-RewriteCond "%{REQUEST_FILENAME}" !-d
-RewriteRule "^(.*)$" "/index.php" [L]</pre>
+ <p>Most modern web frameworks route all requests through a single
+ entry point (a "front controller"). The
+ <code class="directive"><a href="../mod/mod_dir.html#fallbackresource">FallbackResource</a></code> directive
+ handles this more simply and efficiently than
+ <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. See <a href="avoid.html#fallback-resource">When NOT to use mod_rewrite</a>
+ for the recommended approach.</p>
-
- <p>The <code>!-f</code> and <code>!-d</code> conditions skip the
- rule for requests that map to an existing file or directory, so
- static assets (images, CSS, JavaScript) are still served
- directly.</p>
- </dd>
-
- <dt>Discussion:</dt>
-
- <dd>
- <p>In <code>.htaccess</code> context, consider using
- <code>[END]</code> instead of <code>[L]</code> to avoid
- reprocessing loops. See the
- <a href="htaccess.html#loops">.htaccess looping</a> discussion
- for details.</p>
- </dd>
- </dl>
+ <p>If you genuinely need <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> for this (for
+ example, to add conditions beyond "file doesn't exist"), see the
+ <a href="htaccess.html#rewritebase">per-directory rewrites</a>
+ document for an annotated example that also demonstrates
+ <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> usage.</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<strong>example.com</strong>, you could use the following
recipe:</p>
+<p>To do the reverse - strip the <code>www.</code> prefix - swap the
+condition:</p>
+
+<pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}" "^www\.(.+)$" [NC]
+RewriteRule "^(.*)" "http://%1/$1" [L,R,NE]</pre>
+
+
+<p>To generically add <code>www.</code> to any hostname:</p>
+
<pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
RewriteCond "%{HTTP_HOST}" "!^$"
RewriteRule "^/?(.*)" "http://www.%{HTTP_HOST}/$1" [L,R,NE]</pre>
<p>These rulesets will work either in your main server configuration
file, or in a <code>.htaccess</code> file placed in the <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> of the server.</p>
-
</dd>
-
+
<dt>Discussion:</dt>
<dd>
<p>If you have access to the server configuration, a
<code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code> in a dedicated
<code class="directive"><a href="../mod/core.html#virtualhost"><VirtualHost></a></code>
- is the cleanest approach. Use the
+ is the cleanest approach. Canonicalizing the hostname ensures that
+ search engines treat your site as a single entity and avoids
+ cookie scope issues that arise when the same site is reachable
+ under multiple names.</p>
+ <p>Use the
<code class="directive"><a href="../mod/core.html#if"><If></a></code> directive
as a middle ground, and <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> only if you
are limited to <code>.htaccess</code>.</p>
</dd>
- </dl>
-
+</dl>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
</dd>
</dl>
-</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
-<div class="section">
-<h2><a name="fallback-resource" id="fallback-resource">Fallback Resource</a> <a title="Permanent link" href="#fallback-resource" class="permalink">¶</a></h2>
-
-
-<dl>
-<dt>Description:</dt>
-<dd>You want a single resource (say, a certain file, like index.php) to
-handle all requests that come to a particular directory, except those
-that should go to an existing resource such as an image, or a css file.</dd>
-
-<dt>Solution:</dt>
-<dd>
-<p>As of version 2.2.16, you should use the <code class="directive"><a href="../mod/mod_dir.html#fallbackresource">FallbackResource</a></code> directive for this:</p>
-
-<pre class="prettyprint lang-config"><Directory "/var/www/my_blog">
- FallbackResource index.php
-</Directory></pre>
-
-
-<p>However, in earlier versions of Apache, or if your needs are more
-complicated than this, you can use a variation of the following rewrite
-set to accomplish the same thing:</p>
-
-<pre class="prettyprint lang-config"><Directory "/var/www/my_blog">
- RewriteBase "/my_blog"
-
- RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-f
- RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-d
- RewriteRule "^" "index.php" [PT]
-</Directory></pre>
-
-
-<p>If, on the other hand, you wish to pass the requested URI as a query
-string argument to index.php, you can replace that RewriteRule with:</p>
-
-<pre class="prettyprint lang-config">RewriteRule "(.*)" "index.php?$1" [PT,QSA]</pre>
-
-
-<p>Note that these rulesets can be used in a <code>.htaccess</code>
-file, as well as in a <Directory> block.</p>
-
-</dd>
-
-<dt>Discussion:</dt>
-
-<dd>
-<p>The <code class="directive"><a href="../mod/mod_dir.html#fallbackresource">FallbackResource</a></code> directive
-is almost always the better choice for this use case. See the
-<a href="avoid.html#fallback-resource">When not to use mod_rewrite</a>
-document for a simpler one-line alternative.</p>
-</dd>
-
-</dl>
-
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="rewrite-query" id="rewrite-query">Rewrite query string</a> <a title="Permanent link" href="#rewrite-query" class="permalink">¶</a></h2>
</li>
<li>This solution shows the reverse of the previous ones, copying
- path components (perhaps PATH_INFO) from the URL into the query string.
+ path components (perhaps <a class="glossarylink" href="../glossary.html#pathinfo" title="see glossary">PATH_INFO</a>) from the URL into the query string.
<pre class="prettyprint lang-config"># The desired URL might be /products/kitchen-sink, and the script expects
# /path?products=kitchen-sink.
RewriteRule "^/?path/([^/]+)/([^/]+)" "/path?$1=$2" [PT]</pre>
</div></div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/rewrite/remapping.html" title="English"> en </a> |
-<a href="../fr/rewrite/remapping.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/remapping.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div><div id="footer">
<p class="apache">Copyright 2026 The Apache Software Foundation.<br />Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
-<!-- English Revision: 1933072:1933783 (outdated) -->
+<!-- English Revision: 1933072:1934664 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
<button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12" /><line y2="12" x2="22" y1="12" x1="2" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></button>
<div class="toplang">
<p><span>Available Languages: </span><a href="../en/rewrite/rewritemap.html" title="English"> en </a> |
-<a href="../fr/rewrite/rewritemap.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/rewritemap.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div>
<li><img alt="" src="../images/down.gif" /> <a href="#dbd">dbd or fastdbd: SQL Query</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#sharding">URL-based sharding across multiple backends</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#summary">Summary</a></li>
-</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="htaccess.html">Per-directory rewrites (.htaccess)</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li></ul></div>
+</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="flags.html">RewriteRule Flags</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="htaccess.html">Per-directory Rewrites</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="tech.html">Technical details</a></li></ul></div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="introduction" id="introduction">Introduction</a> <a title="Permanent link" href="#introduction" class="permalink">¶</a></h2>
the int function, and then use that in your <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>:
</p>
- <p> <strong>Redirect a URI to an all-lowercase version of itself</strong></p>
+ <p> <strong>Redirect a URL-path to an all-lowercase version of itself</strong></p>
<pre class="prettyprint lang-config">RewriteMap lc int:tolower
RewriteRule "(.*)" "${lc:$1}" [R]</pre>
<code class="directive"><a href="../mod/core.html#mutex">Mutex</a></code> directive.</p>
<p>A simple example is shown here which will replace all dashes with
- underscores in a request URI.</p>
+ underscores in a request URL-path.</p>
<p><strong>Rewrite configuration</strong></p>
<pre class="prettyprint lang-config">RewriteMap d2u "prg:/www/bin/dash2under.py" apache:apache
print(line.strip().replace('-', '_'), flush=True)</pre>
+ <p>A more complete example shows the typical pattern for a
+ prg: map program: read a line, look up the result, and write
+ it back. Diagnostic output is written to <code>STDERR</code>,
+ which ends up in the Apache error log.</p>
+
+ <p><strong>Rewrite configuration</strong></p>
+ <pre class="prettyprint lang-config">RewriteMap vhost2docroot "prg:/www/bin/vhost_lookup.py"
+RewriteRule "^/(.*)$" "${vhost2docroot:%{HTTP_HOST}}/$1"</pre>
+
+
+ <p><strong>vhost_lookup.py</strong></p>
+ <pre class="prettyprint lang-python">#!/usr/bin/env python3
+"""Map a hostname to its document root directory."""
+import sys
+
+VHOSTS = {
+ "example.com": "/srv/www/example",
+ "blog.example.com": "/srv/www/blog",
+}
+
+for line in sys.stdin:
+ host = line.strip().lower()
+ docroot = VHOSTS.get(host)
+ if docroot:
+ print(docroot, flush=True)
+ else:
+ # "NULL" tells mod_rewrite the lookup failed
+ print("NULL", flush=True)
+ print(f"vhost_lookup: no match for {host!r}", file=sys.stderr)</pre>
+
+
+
<div class="note"><h3>Caution!</h3>
<ul>
<li>Keep your rewrite map program as simple as possible. If the program
<li>Be sure to turn off buffering in your program. In the Python example
above, this is done by passing <code>flush=True</code> to
<code>print()</code>. Buffered I/O will cause httpd to wait for the
-output, and so it will hang.</li>
+output, and so it will hang. This is the single most common cause
+of prg: maps appearing to "do nothing" — the program has the
+answer but httpd never sees it because it is stuck in a buffer.</li>
<li>Remember that there is only one copy of the program, started at
server startup. All requests will need to go through this one bottleneck.
This can cause significant slowdowns if many requests must go through
</div></div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/rewrite/rewritemap.html" title="English"> en </a> |
-<a href="../fr/rewrite/rewritemap.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/rewritemap.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div><div id="footer">
<p class="apache">Copyright 2026 The Apache Software Foundation.<br />Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
-<!-- English Revision: 1932820:1933729 (outdated) -->
+<!-- English Revision: 1932820:1934664 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
and URL matching.</p>
</div>
<div id="quickview"><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#InternalAPI">API Phases</a></li>
+<li><img alt="" src="../images/down.gif" /> <a href="#order">Module Processing Order</a></li>
+<li><img alt="" src="../images/down.gif" /> <a href="#encoding">URL Encoding and Decoding</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#InternalRuleset">Ruleset Processing</a></li>
-</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="htaccess.html">Per-directory rewrites (.htaccess)</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li></ul></div>
+</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="flags.html">RewriteRule Flags</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="htaccess.html">Per-directory Rewrites</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li></ul></div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="InternalAPI" id="InternalAPI">API Phases</a> <a title="Permanent link" href="#InternalAPI" class="permalink">¶</a></h2>
<p>In each of these cases, <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> rewrites the
<code>REQUEST_URI</code> either to a new URL, or to a filename.</p>
- <p>In <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a> (i.e., within <code>.htaccess</code> files
- and <code>Directory</code> blocks), these rules are being applied
- after a URL has already been translated to a filename. Because of
- this, the URL-path that <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> initially compares <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> directives against
- is the full filesystem path to the translated filename with the current
- directories path (including a trailing slash) removed from the front.</p>
-
- <p> 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.</p>
-
- <p> 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 <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> 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 <a href="https://cwiki.apache.org/confluence/display/httpd/RewriteLooping">RewriteLooping</a>
- for further discussion of this problem.)</p>
-
- <p>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.</p>
-
- <table class="bordered">
-
- <tr>
- <th>Location of rule</th>
- <th>Rule</th>
- </tr>
-
- <tr>
- <td>VirtualHost section</td>
- <td>RewriteRule "^/images/(.+)\.jpg" "/images/$1.gif"</td>
- </tr>
-
- <tr>
- <td>.htaccess file in document root</td>
- <td>RewriteRule "^images/(.+)\.jpg" "images/$1.gif"</td>
- </tr>
-
- <tr>
- <td>.htaccess file in images directory</td>
- <td>RewriteRule "^(.+)\.jpg" "$1.gif"</td>
- </tr>
-
- </table>
-
- <p>For even more insight into how <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> manipulates URLs in
- different contexts, you should consult the <a href="../mod/mod_rewrite.html#logging">log entries</a> made during
- rewriting.</p>
+ <p>In <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a>,
+ 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
+ <a href="htaccess.html#path-stripping">Per-directory Rewrites</a>
+ document for practical details on path stripping, RewriteBase, and
+ how to avoid looping.</p>
+
+</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
+<div class="section">
+<h2><a name="order" id="order">Module Processing Order</a> <a title="Permanent link" href="#order" class="permalink">¶</a></h2>
+
+ <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> and <code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> both
+ operate during the URL-to-filename translation phase, but
+ <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 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 <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> and <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code> (or <code class="directive"><a href="../mod/mod_alias.html#redirectmatch">RedirectMatch</a></code>) 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 URL-path (or returns a redirect), <code>Redirect</code> never sees
+ the request.</p>
+
+ <pre class="prettyprint lang-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]</pre>
+
+
+ <div class="note"><h3>Per-directory context reverses the order</h3>
+ <p>In <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a>,
+ the situation is different. <code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> directives like
+ <code>Redirect</code> still run in the URL-to-filename translation
+ phase, but <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 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>
+ </div>
+
+ <p>Because of this inconsistency between contexts, mixing
+ <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> and <code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code>
+ 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>
+
+</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
+<div class="section">
+<h2><a name="encoding" id="encoding">URL Encoding and Decoding</a> <a title="Permanent link" href="#encoding" class="permalink">¶</a></h2>
+
+ <p>Apache httpd unescapes URL-encoded characters in the request URL-path before any
+ <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> pattern
+ matching takes place. A request for
+ <code>/my%20page/cats%3Fdogs</code> is decoded to
+ <code>/my page/cats?dogs</code>, and that decoded string is what the
+ <code>RewriteRule</code> pattern matches against.</p>
+
+ <p>This means you cannot write a pattern that matches the literal
+ URL-encoded form. If you need to distinguish
+ <code>/horses%2Fponies</code> from <code>/horses/ponies</code>, use
+ <code>%{THE_REQUEST}</code> in a <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> — it preserves the
+ original request line exactly as the client sent it, before any
+ decoding:</p>
+
+<pre class="prettyprint lang-config"># Match only the literally-encoded %2F, not a real path separator
+RewriteCond "%{THE_REQUEST}" "/horses%2F"
+RewriteRule "^/horses/ponies$" "/special-handler" [L]</pre>
+
+
+ <p>After substitution, <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> re-encodes the
+ resulting URL-path for output. Several flags control this behavior:</p>
+
+ <ul>
+ <li><a href="flags.html#flag_b">[B]</a> — re-escape
+ backreferences so that special characters captured from the
+ decoded URL-path are not interpreted as delimiters in the
+ substitution.</li>
+
+ <li><a href="flags.html#flag_bnp">[BNP]</a> — when [B] is
+ active, encode spaces as <code>%20</code> rather than
+ <code>+</code> (appropriate for path components, not query
+ strings).</li>
+
+ <li><a href="flags.html#flag_ne">[NE]</a> — suppress the
+ default escaping of special characters in the substitution
+ result, allowing literal <code>#</code>, <code>?</code>, and
+ other characters to pass through unmodified on external
+ redirects.</li>
+ </ul>
+
+ <h3><a name="allowencodedslashes" id="allowencodedslashes">AllowEncodedSlashes</a></h3>
+
+
+ <p>By default, Apache returns 404 for any URL containing an encoded
+ slash (<code>%2F</code>). The <code class="directive"><a href="../mod/core.html#allowencodedslashes">AllowEncodedSlashes</a></code> directive controls
+ this behavior:</p>
+
+ <ul>
+ <li><code>Off</code> (default) — reject <code>%2F</code> with
+ 404.</li>
+ <li><code>On</code> — allow <code>%2F</code> and decode it to
+ <code>/</code> before passing to handlers.</li>
+ <li><code>NoDecode</code> — allow <code>%2F</code> but keep it
+ in encoded form, letting the backend application distinguish it
+ from a real path separator.</li>
+ </ul>
+
+ <p>When using the <a href="flags.html#flag_b">[B]</a> flag with
+ URLs that may contain encoded slashes, you typically need
+ <code>AllowEncodedSlashes NoDecode</code> to prevent Apache from
+ rejecting the re-encoded result.</p>
+
+
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
engine is started with the contained ruleset (one or more
rules together with their conditions). The operation of the
URL rewriting engine itself is exactly the same for both
- configuration contexts. Only the final result processing is
+ configuration contexts. Only the final result processing is
different.</p>
<p class="figure">
<?xml version="1.0" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
-<!-- English Revision: 1933719:1934613 (outdated) -->
+<!-- English Revision: 1933719:1934664 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
<button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12" /><line y2="12" x2="22" y1="12" x1="2" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></button>
<div class="toplang">
<p><span>Available Languages: </span><a href="../en/rewrite/vhosts.html" title="English"> en </a> |
-<a href="../fr/rewrite/vhosts.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/vhosts.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div>
<li><img alt="" src="../images/down.gif" /> <a href="#simple.rewrite">Dynamic
Virtual Hosts Using <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code></a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#xtra-conf">Using a Separate Virtual Host Configuration File</a></li>
-</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="rewritemap.html">RewriteMap</a></li><li><a href="htaccess.html">Per-directory rewrites (.htaccess)</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li></ul></div>
+</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="htaccess.html">Per-directory Rewrites</a></li><li><a href="flags.html">RewriteRule Flags</a></li><li><a href="rewritemap.html">RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="tech.html">Technical details</a></li></ul></div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="per-hostname" id="per-hostname">Virtual Hosts For Arbitrary Hostnames</a> <a title="Permanent link" href="#per-hostname" class="permalink">¶</a></h2>
</div></div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/rewrite/vhosts.html" title="English"> en </a> |
-<a href="../fr/rewrite/vhosts.html" hreflang="fr" rel="alternate" title=""> fr </a></p>
+<a href="../fr/rewrite/vhosts.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p>
</div><div id="footer">
<p class="apache">Copyright 2026 The Apache Software Foundation.<br />Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
-<!-- English Revision: 1933072:1933719 (outdated) -->
+<!-- English Revision: 1933072:1934664 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->