Apache mod_rewrite driving me mad

Posted by WishCow on Stack Overflow See other posts from Stack Overflow or by WishCow
Published on 2010-04-08T14:50:59Z Indexed on 2010/04/08 14:53 UTC
Read the original article Hit count: 589

The scenario

I have a webhost that is shared among multiple sites, the directory layout looks like this:

siteA/
    - css/
    - js/
    - index.php
siteB/
    - css/
    - js/
    - index.php
siteC/
    .
    .
    .

The DocumentRoot is at the top level, so, to access siteA, you type http://webhost/siteA in your browser, to access siteB, you type http://webhost/siteB, and so on.

Now I have to deploy my own site, which was designed with having 3 VirtualHosts in mind, so my structure looks like this:

siteD/
    - sites/sitename.com/
        - log/
        - htdocs/
            - index.php
    - sites/static.sitename.com
        - log/
        - htdocs/
            - css
            - js
    - sites/admin.sitename.com
        - log/
        - htdocs/
            - index.php

As you see, the problem is that my index.php files are not at the top level directory, unlike the already existing sites on the webhost. Each VirtualHost should point to the corresponding htdocs/ folder:

http://siteD.com -> siteD/sites/sitename.com/htdocs
http://static.siteD.com -> siteD/sites/static.sitename.com/htdocs
http://admin.siteD.com -> siteD/sites/admin.sitename.com/htdocs

The problem

I cannot have VirtualHosts on this host, so I have to emulate it somehow, possibly with mod_rewrite.

The idea

Have some predefined parts in all of the links on the site, that I can identify, and route accordingly to the correct file, with mod_rewrite.

Examples:

http://webhost/siteD/static/js/something.js -> siteD/sites/static.sitename.com/htdocs/js/something.js
http://webhost/siteD/static/css/something.css -> siteD/sites/static.sitename.com/htdocs/css/something.css
http://webhost/siteD/admin/something -> siteD/sites/admin.sitename.com/htdocs/index.php
http://webhost/siteD/admin/sub/something -> siteD/sites/admin.sitename.com/htdocs/index.php
http://webhost/siteD/something -> siteD/sites/sitename.com/htdocs/index.php
http://webhost/siteD/sub/something -> siteD/sites/sitename.com/htdocs/index.php

Anything that starts with http://url/sitename/admin/(.*) will get rewritten, to point to siteD/sites/admin.sitename.com/htdocs/index.php

Anything that starts with http://url/sitename/static/(.*) will get rewritten, to point to siteD/sites/static.sitename.com/htdocs/$1

Anything that starts with http://url/sitename/(.*) AND did not have a match already from above, will get rewritten to point to siteD/sites/sitename.com/htdocs/index.php

The solution

Here is the .htaccess file that I've come up with:

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI} ^/siteD/static/(.*)$ [NC]
RewriteRule ^siteD/static/(.*)$ siteD/sites/static/htdocs/$1 [L]

RewriteCond %{REQUEST_URI} ^/siteD/admin/(.*)$ [NC]
RewriteRule ^siteD/(.*)$ siteD/sites/admin/htdocs/index.php [L,QSA]

So far, so good. It's all working. Now to add the last rule:

RewriteCond %{REQUEST_URI} ^/siteD/(.*)$ [NC]
RewriteRule ^siteD/(.*)$ siteD/sites/public/htdocs/index.php [L,QSA]

And it's broken. The last rule catches everything, even the ones that have static/ or admin/ in them. Why? Shouldn't the [L] flag stop the rewriting process in the first two cases? Why is the third case evaluated?

Is there a better way of solving this? I'm not sticking to rewritemod, anything is fine as long as it does not need access to server-level config.

I don't have access to RewriteLog, or anything like that. Please help :(

© Stack Overflow or respective owner

Related posts about apache

Related posts about mod-rewrite