Я установил свой виртуальный хост на Apache 2.4.7 с очень простой конфигурацией:
<VirtualHost *:80>
ServerName foo.example.com
DocumentRoot /var/www/html
DirectoryIndex index.php
FallbackResource /index.php
</VirtualHost>
Под корнем документа у меня есть следующая структура:
/index.php
/help/readme.txt
Когда я делаю запросы, я получаю следующие результаты:
/bla -> 200 OK
/help/ -> 404 Not Found
/help/a -> 200 OK
Кажется, что существование /help/
каталог заставляет Apache вернуться 404
потому что нет index.php
там, но я ожидаю, что все запросы будут вызывать /index.php
и таким образом получить 200 OK
ответ.
Я не помню, чтобы это было проблемой при использовании mod_rewrite
, но я предпочитаю использовать FallbackResource
если возможно. Есть способ исправить это?
Обновить
Работает, если я удалю DirectoryIndex
директива, но она страдает от проблемы с пятисекундной задержкой.
Обновление 3
Я использую следующую тестовую среду; структура каталогов следующая:
./htdocs
index.html
test/
bla.txt
./conf
httpd.conf
./logs
Содержание httpd.conf
является:
ServerName apache-bug.local
Listen 8085
DirectoryIndex disabled
DirectorySlash Off
<VirtualHost *:8085>
DocumentRoot /home/user/apache-bug/htdocs
FallbackResource /index.html
</VirtualHost>
Мой config.nice
содержит:
"./configure" \
"--enable-debugger-mode" \
"--with-apr=/usr/local/apr/bin/apr-1-config" \
"--enable-dir=static" \
"--with-mpm=prefork" \
"--enable-unixd=static" \
"--enable-authn-core=static" \
"--enable-authz-core=static" \
"$@"
Для запуска сервера:
httpd -X -d /home/user/work/apache-bug/
Я тоже на это отвечаю, потому что уверен, что проблема связана с тем, как mod_dir.c
работает внутри и я думаю это Жук.
Если ресурс не может быть сопоставлен с локальной файловой системой, функция fixup_dflt()
будет работать, используя FallbackResource
чтобы определить, какой документ следует загрузить вместо этого.
Однако когда ресурс жестяная банка быть сопоставленным с локальной файловой системой и каталогом, он попытается разрешить документ, запустив fixup_dir()
; эта функция выполняет итерацию по списку DirectoryIndex
значений, пока не будет найден первый подходящий документ.
В моем случае в конфигурации есть пустой список DirectoryIndex
ценности, поэтому fixup_dir()
завершится ошибкой, и будет возвращено 404.
У меня работает следующий патч (PR):
static int dir_fixups(request_rec *r)
{
if (r->finfo.filetype == APR_DIR) {
- return fixup_dir(r);
+ if (fixup_dir(r) != OK) {
+ /* use fallback */
+ return fixup_dflt(r);
+ }
+
+ return OK;
}
else if ((r->finfo.filetype == APR_NOFILE) && (r->handler == NULL)) {
/* No handler and nothing in the filesystem - use fallback */
return fixup_dflt(r);
}
return DECLINED;
}
Это в основном пытается fixup_dflt()
после fixup_dir()
не смогли.
А исправить внесен в проект, запланированный на 2.5; он также может быть перенесен на 2.4.
Исправление было вернулся так как:
[...] это [по крайней мере] вызывает
FallBackResource
забить раньшеmod_autoindex
мог бы сработать.
Я все еще пытаюсь понять, как избежать такой ситуации.
Ваша конфигурация должна быть правильной.
Проблема, как ни странно, кажется mod_deflate.
После успешного воспроизведения вашей конфигурации здесь (не получение 404), я также получил 5-секундную задержку. Однако я заметил, что когда UA пропускает gzip
из заголовков Accept-Headers страница отображается / принимается мгновенно. Вы можете проверить это сами с помощью wget
.
Интересно, что дальнейшая отладка с strace
показывает, что apache отправляет содержимое вашего FallbackResource
в розетку вашего клиента без заметной разницы в задержке для обе случаи. Это также очевидно на проводе, где пакет ответа отправляется с сервера клиенту после HTTP-запроса без какой-либо заметной задержки.1.
Похоже, что при использовании mod_deflate в этом случае, однако, UA не знает, когда данные, отправленные сервером, заканчиваются, и, таким образом, ничего не отображает до истечения времени ожидания TCP-соединения.2 и принудительно закрывается сервером. Это соответствует HTTP / 1.0, где закрытое соединение означает конец содержимого.
Для HTTP / 1.1, на сервере есть другие средства, доступные для сигнализации о конце содержимого - но ничего из этого, похоже, здесь не происходит.
Однако, если ошибка скрывается в mod_dir или mod_deflate, сейчас мое время выходит за рамки моего свободного времени. Я заставил его работать безупречно, отключив сжатие gzip; в качестве временного решения, пока проблема не будет окончательно решена, вы можете выборочно отключить gzip.
1) Это говорит нам о том, что проблема не в не очищенных буферах на сервере.
2) По умолчанию тайм-аут составляет 5 секунд с apache - отсюда ваши 5 секунд.