views:

244

answers:

3

I can't for the life of me fathom out why this RewriteCond is causing every request to be sent to my FastCGI application when it should in fact be letting Apache serve up the static resources.

I've added a hello.txt file to my DocumentRoot to demonstrate.

The text file:

ls /Sites/CioccolataTest.webapp/Contents/Resources/static  
hello.txt

The VirtualHost and it's rewrite rules:

AppClass /Sites/CioccolataTest.webapp/Contents/MacOS/CioccolataTest -port 5065
FastCgiExternalServer /Sites/CioccolataTest.webapp/Contents/MacOS/CioccolataTest.fcgi -host 127.0.0.1:5065
<VirtualHost *:80>
    ServerName cioccolata-test.webdev
    DocumentRoot /Sites/CioccolataTest.webapp/Contents/Resources/static

    RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^/(.*)$ /Sites/CioccolataTest.webapp/Contents/MacOS/CioccolataTest.fcgi/$1 [QSA,L]
</VirtualHost>

Even with the -f, Apache is directing requests for this text file (i.e. access http://cioccolata-test.webdev/hello.txt returns my app, not the text file).

As a proof of concept I changed the RewriteCond to:

RewriteCond %{REQUEST_URI} !^/hello.txt

That made it serve the text file correctly and allowed every other request to hit the FastCGI application.

Why doesn't my original version work? I need to tell apache to serve every file in the DocumentRoot as a static resource, but if the file doesn't exist it should rewrite the request to my FastCGI application.

NOTE: The running FastCGI application is at /Sites/CioccolataTest.webapp/Contents/MacOS/CioccolataTest (without the .fcgi prefix)... the .fcgi prefix is only being used to tell the fastcgi module to direct the request to the app.

A: 

I'm going to guess that REQUEST_FILENAME is probably not what you want in this context. Increase your RewriteLogLevel and it will tell you exactly why it's doing whatever it's doing.

Azeem.Butt
Ah, I was wondering if there was some way to debug what these variables are! I'll try this and post back, thanks.
d11wtq
With the log level set to 3 and 4 and I get the same output so I assume it doesn't go any higher. Since I don't believe I can paste code blocks in comments, here's a link to the log output for a single request.http://w3style.co.uk/~d11wtq/rewrite_log.txtNote that it looks at the RewriteCond for the input '/hello.txt' and decides that it matched the rule and must therefore rewrite to FastCGI.
d11wtq
+1  A: 

I found a way to make it work, but I've never in all of my 6 years of web development ever had to do this. I prefixed %{DOCUMENT_ROOT} to the REQUEST_FILENAME before checking if it's a file or not.

FastCgiServer /Sites/CioccolataTest.webapp/Contents/MacOS/CioccolataTest -port 5065
<VirtualHost *:80>
    ServerName cioccolata-test.webdev
    DocumentRoot /Sites/CioccolataTest.webapp/Contents/Resources/static

    RewriteEngine On

    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
    RewriteRule ^/(.*)$ /Sites/CioccolataTest.webapp/Contents/MacOS/CioccolataTest [QSA,L]
</VirtualHost>

For some reason it's treating all the paths as absolute filesystem paths. Usually apache handles paths relative to the document root, doesn't it?

I wonder if it has anything to do with the fact that my fastcgi app is referenced at an absolute path (I think it needs to be). I'm new to the world of fastcgi.

d11wtq
Look up per-directory context and RewriteBase in your documentation.
Azeem.Butt
+1  A: 

%{REQUEST_FILENAME} is not available as you would expect within the VHost context because mod_rewrite hooks into the request prior to the phase that sets this variable. Prepending DOCUMENT_ROOT is a good way to work around this.

agperson