Apache - Пользовательская страница с ошибкой, возвращающая ошибку AH01071 только для файловых запросов

У меня есть сайт, размещенный у провайдера виртуального хостинга. Это Apache с FPM / FastCGI и PHP 7.2

В качестве общего хостинга включен Конфигурация, к которой у меня есть доступ, - это htaccess, но, очевидно, не какой-либо из файлов конфигурации Apache.

У меня есть настраиваемая страница ошибок, настроенная в моем htaccess следующим образом: ErrorDocument 404 /error404.php. Сегодня я заметил, что моя пользовательская страница с ошибкой 404 не отображается. Вместо обычного текста Файл не найден. возвращается в браузер с кодом состояния 404 в заголовке. Дальнейшее расследование показало, что это происходит только тогда, когда запрашивается файл . Если вы запрашиваете несуществующий каталог , вы получаете настраиваемую страницу ошибки! Например, запрос mydomain.info/dummy.htm дает ошибку, а запрос mydomain.info/dummy/ возвращает пользовательскую страницу ошибки.

Сервер регистрирует ошибку ] AH01071 , то есть Основной сценарий неизвестен для каждого Файл не найден. ошибка.

Похоже, что ModSecurity включен на сервере, потому что журналы регистрируют отклоненные злонамеренные запросы, например [клиент xxx.xxx.xxx.xxx] ModSecurity: Доступ запрещен с кодом 403 (фаза 2). ... etc

Кроме того, я недавно перешел на PHP 7.2 в соответствии с рекомендациями хостинг-провайдера. Однако возврат к версии 5.6 не меняет симптомов.

Есть идеи, что вызывает это? Я видел информацию, которая предполагает, что, возможно, ProxyPass или ProxyErrorOverride может решить проблему, но я не знаю, где это настроить.

Для записи, вот полный htaccess, бородавки и все такое:

RewriteEngine on

# AddType TYPE/SUBTYPE EXTENSION
AddType audio/mpeg mp3
AddType video/mp4 mp4 m4v

# Add WWW
RewriteCond %{HTTP_HOST} ^mydomain\.info [NC]
RewriteRule ^(.*) https://www.mydomain.info/$1 [R=301,L,NE]

# Redirect for .COM
RewriteCond %{HTTP_HOST} mydomain\.com$ [NC]
RewriteRule ^/?(.*) https://www.mydomain.info/$1 [R=301,L,NE]

# Force HTTPS
RewriteEngine On 
RewriteCond %{HTTPS} off 
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]

# Home page canonicalization
RewriteCond %{THE_REQUEST} ^.*\/index\.htm\ HTTP/
RewriteRule ^(.*)index\.htm$ /$1 [R=301,L,NE]

# Removed page_missing.htm
Redirect 301 /page_missing.htm /new_page.htm#section_b

# Some content moved to sub-folder
Redirect 301 /extra_content.htm /extra/extra_content.htm

# Internally redirect all HTM & HTML URLs to PHP
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.(htm|html)$ /$1\.php

# Error 404 page
ErrorDocument 404 /error404.php

<IfModule mod_expires.c>
    # Activate mod_expires for this directory
    ExpiresActive on

    # Default
    ExpiresDefault "access plus 7 days"

    # Default for actual documents
    ExpiresByType text/html "access plus 15 minutes"

    # cache CSS files for 7 days
    ExpiresByType text/css "access plus 7 days"

    # locally cache common resource types for 7 days
    ExpiresByType image/jpg "access plus 7 days"
    ExpiresByType image/jpeg "access plus 7 days"
    ExpiresByType image/gif "access plus 7 days"
    ExpiresByType image/png "access plus 7 days"
    ExpiresByType application/pdf "access plus 7 days"    
    ExpiresByType audio/mpeg "access plus 7 days"    
</IfModule> 
1
задан 11 September 2019 в 02:31
1 ответ
 # Внутреннее перенаправление всех URL-адресов HTM и HTML на PHP
RewriteCond% {REQUEST_FILENAME}! -F
RewriteRule ^ (. *) \. (Htm | html) $ /$1\.php
 

Я бы не ожидал, что это вызовет проблему, с которой вы столкнулись, однако у вас есть директивы, которые «вслепую» перезаписывают любой несуществующий .htm (или .html ] ) к эквивалентному файлу .php независимо от того, существует ли этот файл .php или нет. (В этом случае документ об ошибке должен обнаруживать отсутствующий файл .php , а не отсутствующий файл .htm , который изначально был запрошен.)

Это также может объяснить разницу в вашем поведении наблюдают с запросом несуществующего «каталога» (т. е. запроса формы / dummy / ), который не может быть переписан вышеуказанной директивой и, кажется, «работает», как задумано (т. е. вызывается пользовательский документ об ошибке).

Вы можете изменить приведенное выше правило, чтобы перезаписать его в .php , только если файл существует. Например:

# Internally redirect all HTM & HTML URLs to PHP
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.*)\.(htm|html)$ /$1.php [L]

Нет необходимости экранировать буквальную точку в подстановке RewriteRule . Вы должны включить флаг L (хотя в настоящее время это последняя директива mod_rewrite, поэтому не имеет особого значения).


ОБНОВЛЕНИЕ: Если вы запрашиваете несуществующую страницу php, вы все равно получить ответ «Файл не найден»

Похоже на проблему конфигурации сервера. Вы можете "обойти" эту проблему, вручную переписав документ об ошибке:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.php$ /error404.php [L]

Хотя вам, вероятно, потребуется изменить error404.php , чтобы учесть это.

ИЛИ ... Я Также было бы любопытно, изменит ли запуск 404 из Apache (который, на первый взгляд, не имеет большого смысла) это поведение. Например, вместо приведенной выше перезаписи:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.php$ - [R=404]

Идея этого подхода заключается в том, что он, как мы надеемся, вызовет внутренний подзапрос для документа об ошибке до того, как запрос будет передан обработчику PHP (который, похоже, что противоречит документу об ошибке). Затем обработчик PHP вызывается только для обслуживания документа об ошибке.

1
ответ дан 3 December 2019 в 23:00

Теги

Похожие вопросы