Використовуйте FallbackResource, навіть якщо каталог існує


11

Я створив свій віртуальний хост на 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/

А для чого відповідає орган реагування /bla?
zerkms

Я не впевнений, що тоді розумію проблему: -S
zerkms

Просто для того, щоб переконатися - на якій версії Apache ви працюєте?
Jenny D

@JennyD Я біжу на 2.4.7.
Джек

Відповіді:


8

Я також відповідаю на це, бо я майже впевнений, що питання пов'язане з тим, як 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()невдалого.

Оновлення 2015-04-21

Виправлення було представлено проект, запланований на 2,5; він також може бути перенесений на 2.4.

Оновлення 2015-05-18

Виправлення було скасовано, оскільки:

[...] це [принаймні] змушує FallBackResourceбити, перш ніж, mod_autoindexможливо, забив.

Я все ще намагаюся розібратися, як уникнути подібної ситуації.


Я б сказав, що помилка полягає в fixup_dir()ігноруванні FallbackResource.
Рікі Бім

@RickyBeam Так, але технічно про fixup_dir()це не слід знати fixup_dflt(), тому їмхо краще це виправити "вище" :)
Джек

7

Ваша конфігурація повинна бути правильною.

Проблема, як не дивно, здається, що 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 секунд з апашем - ось звідки і ваші 5 секунд.


Дякую. Проблема із затримкою 5с є другорядним моєю основною проблемою, я оновив своє запитання про те, як відтворити проблему на місцевому рівні.
Джек
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.