7

I'm trying to first use an Alias folder to store my project files in a different location than my DocumentRoot, and then execute a mod_rewrite on this request. However it doesn't seem to parse the .htaccess file.

This is the content of my Alias file:

Alias /test F:/Path/To/Project

<Directory F:/Path/To/Project>
    Order allow,deny
    Allow from all
</Directory>

This is my .htaccess file:

Options +FollowSymlinks
RewriteEngine on

RewriteRule .* index.php [NC] [PT]

When I remove the Alias everything works fine.

Gottlieb Notschnabel
  • 9,408
  • 18
  • 74
  • 116
TJHeuvel
  • 12,403
  • 4
  • 37
  • 46
  • In the rewritten folder, so F:/Path/To/Project/.htaccess – TJHeuvel Aug 29 '12 at 08:38
  • So without the `Alias`, what's the URL you go to that accesses the `F:/Path/To/Project/` directory and the htaccess file works? – Jon Lin Aug 29 '12 at 08:42
  • When i put it all (index.php and .htaccess) in my docroot it works fine. After i make an alias, and move my files to the new server, the rewriterules dont work. – TJHeuvel Aug 29 '12 at 12:05
  • 1
    Well, if you move it to the doc root, it will definitely work. The problem is the interpreting of htaccess files happens on a URI-path to file-path mapping. That sort of breaks when your aliased directory is outside of your document root. – Jon Lin Aug 29 '12 at 12:14
  • Thanks for the answer :) Its not the behaviour i had expected. – TJHeuvel Aug 29 '12 at 12:22

2 Answers2

7

mod_alias ALWAYS takes precedence over mod_rewrite. You can never override a mod_alias directive with mod_rewrite.

The AliasMatch directive may help you in this case.

jornak
  • 478
  • 3
  • 9
  • I'm not talking about overriding, i just want both. So first redirect the documentroot to F:/Path/To/Project and then apply the .htaccess file located at F:/Path/To/Project/.htaccess – TJHeuvel Aug 28 '12 at 14:26
  • You're still unintentionally overriding mod_rewrite with the mod_alias directive. – jornak Aug 28 '12 at 14:30
  • Not sure if this was true in 2012, but it is WRONG in 2021 with Apache 2.4. mod_alias does NOT take precedence over mod_rewrite. My test showed the opposite, Alias was not evaluated, when a RewriteRule matched before (when both are in the vhost config). There is a PT flag for rewrite rules: "The target [...] in a RewriteRule is assumed to be a file path, by default. [...] The use of the [PT] flag causes the result of the RewriteRule to be passed back through URL mapping, so that location-based mappings, such as Alias, Redirect, or ScriptAlias, for example, might have a chance to take effect." – dr fu manchu Nov 27 '21 at 00:59
5

Here is a solution that may address some scenarios where you are trying to use alias and rewrite but can't because they conflict.

Suppose your DocumentRoot for a particular application is /var/www/example.com/myapp, and you have the following basic directory structure, where public requests are either for files in public (e.g., a css file), or are otherwise routed through index.php.

myapp/
|- private_library/
   |- private_file.php
|- private_configs/
   |- private_file.php
|- public/
   |- index.php
   |- css/
      |- styles.css

The objective is to only serve content inside public_webroot, however, the URL should be example.com/myapp not example.com/myapp/public.

The following might seem like it should work:

DocumentRoot /var/www/example.com
Alias /myapp /var/www/example.com/myapp/public
<Directory /var/www/example.com/myapp/public>
    # (or in this dir's .htaccess)
    RewriteEngine On
    RewriteBase /public
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?q=$1 [QSA,PT]
</Directory>

But this will lead to an infinite loop if you request a URL for a file that doesn't exist (i.e., one that should be routed through index.php).

One solution is to not use mod_alias, and instead just use mod_rewrite in your application's root directory, like this:

DocumentRoot /var/www/example.com
<Directory /var/www/example.com/myapp>
    # (or in this dir's .htaccess)
    RewriteEngine On
    RewriteRule   (.*) public/$1 [L]
</Directory>
<Directory /var/www/example.com/myapp/public>
    # (or in this dir's .htaccess)
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?q=$1 [QSA,L]
</Directory>

And that's all!

Synexis
  • 1,255
  • 14
  • 14