我有一个主要目的是处理RPC请求的Apache服务器。 所有这样的请求都以一个固定的前缀(比如/rpc )开头,我使用Location指令来设置这个URL的处理器(例如<Location /rpc>...</Location> )。
我现在喜欢这个服务器也提供静态文件。 我把一个index.html文件放到它的DocumentRoot但是不能让apache来为我服务。 相反,我得到404响应。 访问日志显示了这一点:
127.0.0.1 - - [18/Aug/2010:11:41:52 -0400] "GET /index.html HTTP/1.1" 404 208
错误日志显示这个:
[...] [error] [client 127.0.0.1] File does not exist: /www/htdocs/index.html
这个错误信息是一个肮脏的谎言。 我可以复制并粘贴该path并运行ls /www/htdocs/index.html ,看到该文件确实存在。
目前为止我尝试过的东西:
LogLevel debug (日志中不显示新消息) SetHandler default-handler指令的<Location />块 SetHandler default-handler指令的<Location /index.html>块 Location块移动到<Location /rpc>块的上方和下方 dtruss并没有看到Apache在处理请求时发出一个stat()调用 我正在用尽想法。 还有什么我应该尝试?
(我在Mac OS X 10.5.8上使用apache 2.2.12,在CentOS 5.4上使用apache 2.2.3)
答案最终取决于我的问题中没有的一条信息,但是这个结果应该是一个很大的提示!
我有一个PerlMapToStorageHandler Apache2::Const::OK指令在我的Apacheconfiguration根据mod_perl文档中的build议 。 这是一个主机范围的设置,它可以防止apache在每次获取请求时调用ap_directory_walk()和stat()一堆文件。 当所有的URI都是“虚拟的”(即不与磁盘上的真实文件相对应)时,这是可取的,但这也意味着你不能提供任何静态文件!
我的解决scheme是创build一个自定义的PerlMapToStorageHandler例程,避免除了我想要服务的每个文件的stat()调用:
package MyMapToStorageHandler; use strict; use Apache2::RequestRec(); use Apache2::Const -compile => qw(DECLINED OK M_TRACE); sub handler { my $r = shift; # Fall through to the default handling for TRACE requests and requests # for the index.html file. if ($r->method_number == Apache2::Const::M_TRACE || $r->uri eq '/index.html') { return Apache2::Const::DECLINED; } # Skip ap_directory_walk stat() calls by just returning OK return Apache2::Const::OK; } 1;
然后,在我的httpd.conf文件中,我用这个replace了现有的PerlMapToStorageHandler Apache2::Const::OK指令:
PerlLoadModule MyMapToStorageHandler ... PerlMapToStorageHandler MyMapToStorageHandler
那就是诀窍。