Apache mod_rewrite RewriteCond旁路静态资源不起作用

时间:2010-04-22 03:30:58

标签: apache mod-rewrite fastcgi

我无法理解为什么这个RewriteCond会导致每个请求被发送到我的FastCGI应用程序,而实际上它应该让Apache提供静态资源。< / p>

我在我的DocumentRoot中添加了一个hello.txt文件来演示。

文本文件:

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

VirtualHost及其重写规则:

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>

即使使用-f,Apache也会指示对此文本文件的请求(即访问http://cioccolata-test.webdev/hello.txt会返回我的应用程序,而不是文本文件。)

作为概念验证,我将RewriteCond更改为:

RewriteCond %{REQUEST_URI} !^/hello.txt

这使得它正确地提供了文本文件并允许每个其他请求命中FastCGI应用程序。

为什么我的原始版本不起作用?我需要告诉apache将DocumentRoot中的每个文件作为静态资源提供服务,但如果该文件不存在,则应该将请求重写为我的FastCGI应用程序。

注意:正在运行的FastCGI应用程序位于/Sites/CioccolataTest.webapp/Contents/MacOS/CioccolataTest(没有.fcgi前缀)... .fcgi前缀仅用于告诉fastcgi模块将请求定向到应用程序。

3 个答案:

答案 0 :(得分:2)

我找到了一种方法让它发挥作用,但我从来没有在我6年的网络开发中都曾经做过这件事。在检查它是否是文件之前,我将%{DOCUMENT_ROOT}作为REQUEST_FILENAME的前缀。

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>

由于某种原因,它将所有路径视为绝对文件系统路径。通常apache处理相对于文档根目录的路径,不是吗?

我想知道是否与我的fastcgi应用程序以绝对路径引用这一事实有关(我认为它需要)。我是fastcgi世界的新手。

答案 1 :(得分:1)

%{REQUEST_FILENAME}在VHost上下文中不可用,因为mod_rewrite在设置此变量的阶段之前挂钩到请求中。预先设置DOCUMENT_ROOT是解决此问题的好方法。

答案 2 :(得分:0)

我猜测REQUEST_FILENAME可能不是你想要的。增加你的RewriteLogLevel,它会告诉你为什么它正在做它正在做的事情。