У меня есть сервер apache, основная цель которого - обрабатывать запросы RPC. Все такие запросы попадают на URL-адрес, который начинается с фиксированного префикса (например, /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
Это сообщение об ошибке - грязная ложь. Я могу скопировать и вставить этот путь и запустить ls /www/htdocs/index.html
и убедитесь, что файл действительно существует.
То, что я пробовал до сих пор:
LogLevel debug
(новых сообщений в логах не появлялось)<Location />
блок с SetHandler default-handler
директива<Location /index.html>
блок с SetHandler default-handler
директиваLocation
блоки выше и ниже <Location /rpc>
блокироватьdtruss
и не видел ни одной проблемы с apache stat()
позвонить во время обработки запросаУ меня заканчиваются идеи. Что еще мне попробовать?
(Я использую apache 2.2.12 в Mac OS X 10.5.8 и apache 2.2.3 в CentOS 5.4.)
Оказалось, что ответ зависит от части информации, которой нет в моем вопросе, но dtruss
вывод должен был быть большой подсказкой!
у меня есть PerlMapToStorageHandler Apache2::Const::OK
директива в моей конфигурации apache согласно предложение в документации mod_perl. Это параметр для всего хоста, и он предотвращает вызов apache ap_directory_walk()
и stat()
загружает кучу файлов каждый раз, когда получает запрос. Это желательно, когда все ваши URI являются «виртуальными» (т.е. не соответствуют реальным файлам на диске), но это также означает, что вы не можете обслуживать статические файлы!
Мое решение состояло в том, чтобы создать собственный 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
файл я заменил существующий PerlMapToStorageHandler Apache2::Const::OK
директива с этим:
PerlLoadModule MyMapToStorageHandler
...
PerlMapToStorageHandler MyMapToStorageHandler
Это сработало.