Как перенаправить на 404, когда url указывает на существующую папку (без косой черты). Связанный HAproxy или mod-rewrite
Я использую прослушивание HAProxy на 80 для отправки запросов на сервер node (порт: 3000) или php-сервер (4000); У меня также есть CSF, у которых есть порты 3000 и 80.
Он работает нормально, когда я просматриваю страницу в http://example.com/forum/1/page.php
, но иногда, когда я случайно вхожу example.com/forum/1
(без конечной косой черты), он продолжает загружать и в конечном итоге приводит к странице ошибок ERR_CONNECTION_TIMED_OUT
. Адресная строка показывает, что она перенаправлена на http://example.com:4000/forum/1/
.
Так как у меня нет открытого порта 4000, когда я несколько раз перехожу к example.com/forum/1
, он будет генерировать блок CSF. Мой вопрос: могу ли я перенаправить все запросы, указывающие на фактическую папку example.com/forum/1
(без конечной косой черты) на страницу 404? Я попытался добавить правило перезаписи для добавления конечной косой черты к каждому запросу, но это сломало бы все мои относительные пути (см. Мою проблему в этой статье).
Итак, что я хочу знать, почему я был перенаправлен на http://example.com:4000/forum/1/
из http://example.com/forum/1
? Это вызвано HAproxy?
Некоторая конфигурация HAproxy:
frontend all 0.0.0.0:80
timeout client 1h
# use apache2 as default webserver for incoming traffic
default_backend apache2
backend apache2
balance roundrobin
option forwardfor
server apache2 myIpAddress:4000 weight 1 maxconn 1024 check
# server must be contacted within 5 seconds
timeout connect 5s
# all headers must arrive within 3 seconds
timeout http-request 3s
# server must respond within 25 seconds. should equal client timeout
timeout server 25s
Здесь мои правила перезаписи:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
RewriteCond %{REQUEST_URI} !^.*\.(jpg|css|js|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Ответы
Ответ 1
Так как /forum/1
является действительным физическим каталогом, вы перенаправляетесь на /forum/1/
из-за этого параметра:
DirectorySlash On
который используется модулем под названием mod_dir
, который добавляет конечную косую черту после каталогов, если она отсутствует.
Вы можете, конечно, отключить этот флаг, используя:
DirectorySlash Off
но знать о последствиях безопасности.
Чтобы быть более безопасным, вам также необходимо:
Options -Indexes
чтобы отключить список каталогов.
Предупреждение о безопасности (скопировано из связанного руководства)
Отключение перенаправления трейлинг-косой черты может привести к раскрытию информации. Рассмотрим ситуацию, в которой mod_autoindex
активен (Options +Indexes
), а DirectoryIndex
установлен на допустимый ресурс (скажем, index.html), и для этого URL нет другого специального обработчика. В этом случае запрос с завершающей косой чертой отобразит файл index.html
. Но запрос без косой черты перечислил содержимое каталога.
Обновление: Чтобы ответить на эту часть вопроса:
Мой вопрос: могу ли я перенаправить все запросы, указывающие на фактическую папку example.com/forum/1
(без конечной косой черты) на страницу 404?
Вы можете использовать этот код в /forum/1/.htaccess
:
DirectorySlash On
RewriteEngine On
RewriteRule ^$ - [L,R=404]
Это заставит конечную косую черту, чтобы правило перезаписи могло использоваться для отправки ошибки 404.
Ответ 2
В вашем файле .htaccess добавьте следующий код. Замените /404.php любым файлом, который вы хотите.
ErrorDocument 404 /404.php
Ответ 3
Поместите это вверху вашего .htaccess
DirectorySlash Off
RewriteOptions AllowNoSlash
RewriteEngine On
RewriteCond ${REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ - [L,R=404]
DirectorySlash Off сделает каталоги доступными без косой черты без перенаправления.
Но проблема не слэш-версия просто перечислит содержимое каталога.
Я стараюсь избегать этого, добавляется RewriteOptions AllownoSlash.
Теперь, когда папка запрашивается без косой черты, возникает ошибка 404.