Apache2 mod_rewrite Clean URL – working, but files not accessible

apache-2.4mod-rewrite

Server: Debian Jessie
Apache: 2.4.9-1
PHP: 5.5

What I want is all non-files and non-directories to redirect to index.php where I handle them myself. Due to the nature of my project I must work from within a virtual host.

I'm using virtual hosting (vHosts) along with mod_rewrite in a web project I'm working on. Here's the vHost file…

<VirtualHost *:80>

        ServerName foo.com

        ServerAlias www.foo.com

        ServerAdmin admin@foo.com

        DocumentRoot /srv/foo/main/www/

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        <IfModule mod_rewrite.c>

                RewriteEngine on

                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteCond %{REQUEST_FILENAME} !-d

                RewriteRule ^(.*)$ /index.php [L]

        </IfModule>

</VirtualHost>

The vHost is working as expected, and the rewrite rules are redirecting requests to index.php as expected. However when I try to access files on the server, for example:

foo.com/css/style.css

located in:

/srv/foo/main/www/css/style.css

my request is redirected to index.php

This is strange as the rewrite condition statements is supposed to fix that.

All folder permissions are set to 755, all files to 644.

I have been able to confirm without a doubt that the rewrite conditions are matching when they should not be. I was able to see this by looking at apache's error log with debug output enabled for mod_rewrite.

Why are the two RewriteCond statements incorrectly matching?

Are they perhaps not seeing the vHost DocumentRoot?

UPDATE: Turning the rewrite engine OFF allows me to get to the file I'm testing with. IE, my URI is correct. I know my path is good, the conditions are just failing for some reason.

Best Answer

For anyone using Apache 2.4 with virtual hosts & wanting to use mod_rewrite inside said vHost with rewrite conditions that need to check files or folders inside the vHost, this is how to do the rewrite conditions...

<VirtualHost *:80>

       <IfModule mod_rewrite.c>

                RewriteEngine on

                RewriteCond %{CONTEXT_DOCUMENT_ROOT}%{REQUEST_URI} !-f
                RewriteCond %{CONTEXT_DOCUMENT_ROOT}%{REQUEST_URI} !-d

                RewriteRule ^(.*)$ /index.php [L]

        </IfModule>

</VirtualHost>

I came up with this and it seems to be working well.

The explanation...

%{CONTEXT_DOCUMENT_ROOT}%{REQUEST_URI} will give you a context sensitive document root. IE, the document root AFTER virtual hosting has been applied. But it will not give you the URI so we need to add the %{REQUEST_URI} to finish the job.

CONTEXT_DOC_ROOT == /srv/foo/main/www

REQUEST_URI == /css/style.css

CONTEXT_DOC_ROOT + REQUEST_URI == /srv/foo/main/www/css/style.css

The rest is easy. Awesome sauce. Hope this helps!

Related Topic