Apache mod_rewrite RewriteCond 绕过静态资源不起作用
我一生都无法理解为什么这个 RewriteCond 会导致每个请求发送到我的 FastCGI 应用程序,而实际上它应该让 Apache 提供静态资源。
我已将 hello.txt
文件添加到我的 DocumentRoot 中进行演示。
文本文件:
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 模块将请求定向到应用程序。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我找到了一种让它发挥作用的方法,但在我 6 年的 Web 开发生涯中,我从来没有这样做过。在检查 REQUEST_FILENAME 是否是文件之前,我在 REQUEST_FILENAME 前面添加了
%{DOCUMENT_ROOT}
前缀。由于某种原因,它将所有路径视为绝对文件系统路径。通常 apache 处理相对于文档根的路径,不是吗?
我想知道这是否与我的 fastcgi 应用程序在绝对路径上引用这一事实有关(我认为它需要如此)。我是 fastcgi 世界的新手。
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.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.
%{REQUEST_FILENAME} 在 VHost 上下文中不可用,因为 mod_rewrite 在设置此变量的阶段之前挂钩到请求。前置 DOCUMENT_ROOT 是解决此问题的好方法。
%{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.
我猜测 REQUEST_FILENAME 可能不是您在这种情况下想要的。增加您的 RewriteLogLevel,它会准确地告诉您它正在执行的操作的原因。
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.