title: How to redirect URL with htaccess (RewriteRule) and prevent direct access
body: <p>using .htaccess I'd like to transparently redirect requests for folder "old" to folder "new", and in the same time prevent direct access to folder "new":</p>
  
  <p>desired result:</p>
  
  <p><a href="http://example.com/old/" rel="nofollow">http://example.com/old/</a>... -> will display what's in "new" (no URL change in browser!)
  <a href="http://example.com/new/" rel="nofollow">http://example.com/new/</a>... -> no access</p>
  
  <p>this is my code in .htaccess (the 1st line is here because several domains share the same root folder):</p>
  
  <pre><code>RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
  RewriteRule ^old(.*)$ new$1 [L]
  RewriteRule ^new(.*)$ - [F]
  </code></pre>
  
  <p>Well, what happens is that the 3d line triggers because of the substitution in the 2nd. I was convinced that the flag "L" would prevent this from happening (end of processing), but it seems that's not the case.</p>
  
  <p>Do you have any suggestions what needs to be done (I tried to debug with rewrite log, but without success)?</p>
  
  <p>I did some logging and found the following:</p>
  
  <pre><code>[rid#d0ac98/initial] (3) [per-dir C:/www/example/] add path info postfix: C:/www/example/new -&gt; C:/www/example/new/
  [rid#d0ac98/initial] (3) [per-dir C:/www/example/] strip per-dir prefix: C:/www/example/new/ -&gt; new/
  [rid#d0ac98/initial] (3) [per-dir C:/www/example/] applying pattern '^new(.*)$' to uri 'new/'
  [rid#d0ac98/initial] (4) RewriteCond: input='localhost' pattern='^example\.com$' =&gt; not-matched
  [rid#d0ac98/initial] (4) RewriteCond: input='localhost' pattern='^localhost$' =&gt; matched
  [rid#d0ac98/initial] (2) [per-dir C:/www/example/] rewrite new/ -&gt; old/
  [rid#d0ac98/initial] (3) [per-dir C:/www/example/] add per-dir prefix: old/ -&gt; C:/www/example/old/
  [rid#d0ac98/initial] (2) [per-dir C:/www/example/] strip document_root prefix: C:/www/example/old/ -&gt; /example/old/
  [rid#d0ac98/initial] (1) [per-dir C:/www/example/] internal redirect with /example/old/ [INTERNAL REDIRECT]
  [rid#d217a8/initial/redir#1] (3) [per-dir C:/www/example/] strip per-dir prefix: C:/www/example/old/ -&gt; old/
  [rid#d217a8/initial/redir#1] (3) [per-dir C:/www/example/] applying pattern '^new(.*)$' to uri 'old/'
  [rid#d217a8/initial/redir#1] (3) [per-dir C:/www/example/] strip per-dir prefix: C:/www/example/old/ -&gt; old/
  [rid#d217a8/initial/redir#1] (3) [per-dir C:/www/example/] applying pattern '^old(.*)$' to uri 'old/'
  [rid#d217a8/initial/redir#1] (2) forcing 'C:/www/example/old/' to be forbidden
  </code></pre>
  
  <p>This seems an internal redirect, which causes the "forbidden" result. Indeed, the documentation mentions it:</p>
  
  <p><em>It is therefore important, if you are using RewriteRule 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. 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...</em></p>
  
  <p>So I suppose that in my example the error was due to the fact that I used "L" flag instead the "END" flag?</p>
  
  <p>I found an alternative solution (3rd line is inserted here):</p>
  
  <pre><code>RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
  RewriteRule ^old(.*)$ new$1 [L]
  RewriteCond %{ENV:REDIRECT_STATUS} ^$
  RewriteRule ^new(.*)$ - [F]
  </code></pre>
  
  <p>The 4th line will be executed only if there's no internal redirect.</p>