Как в Windows поменять сообщения ошибок Apache

Ошибки веб-сервера, например, 404 «Документ не найден» - являются частью протокола HTTP — кодами статуса ответов. Ошибками считаются коды статусов вида 4xx и 5xx (то есть начинающиеся на 4 или 5).

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

Not Found в Apache

Начнём с практического примера самой популярной ошибки Not Found — не найдено (запрошенная страница или документ отсутствуют). Чтобы получить это сообщение, достаточно набрать любой несуществующий адрес на сервере:

Not Found
The requested URL /test.php was not found on this server.

Предположим, мы хотим поменять сообщение «Not Found» на любое другое. Это можно сделать изменив настройки веб-сервера в главном конфигурационном файле, либо с помощью .htaccess (смотрите подробности о его включении и возможностях в статье «Файл .htaccess в Apache»).

В качестве примера добавим в файл .htaccess следующую строку:

ErrorDocument 404 "Something went wrong... Please contact admin, email: <a href=\"admin@gmail.com\">admin@gmail.com</a>"

В результате получим:

Сообщение должно быть заключено в двойные кавычки. Структура директивы следующая:

ErrorDocument КОД "СООБЩЕНИЕ"

Пример настроенного сообщения при запрете доступа:

ErrorDocument 403 "By default, Mutillidae only allows access from localhost (127.*.*.*). Edit the .htaccess file to change this behavior (not recommended on a public network)."

Поскольку сообщение будет отправляться в кодировке iso-8859-1, то его нужно писать латинскими буквами. Это ограничение можно обойти, если, например, в качестве страницы ошибки показывать заготовленный файл. О том, как это сделать, будет рассказано далее, где возможности директивы ErrorDocument будут рассмотрены более детально.

Директива ErrorDocument

Настраиваемые ответы на ошибки могут быть заданы для любого кода статуса HTTP считающегося ошибкой, то есть это статусы вида 4xx или 5xx.

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

Настройка своих сообщений об ошибках веб сервера

Как уже было сказано, настройка страниц ошибок выполняется с использованием директивы ErrorDocument, которая может использоваться в глобально контексте, контексте виртуального хоста или на уровне директории. Её можно использовать в файле .htaccess, если AllowOverride установлена на FileInfo (или более широкие возможности).

В ответ на возникновение проблемы или ошибки Apache httpd можно настроить выполнять одно из четырёх действий:

  • вывести простое жёстко прописанное сообщение
  • вывести настроенное сообщение
  • внутренне перенаправить на локальный URL путь для обработки проблемы/ошибки
  • перенаправить на внешний URL для обработки проблемы ошибки

По умолчанию используется первый вариант, а для настройки опций со 2 по 4 используется директива ErrorDocument, за который следует код ответа HTTP и затем URL или сообщение. Apache httpd иногда будет предоставлять дополнительную информацию в зависимости от проблемы/ошибки.

Начиная с версии 2.4.13 может использоваться синтаксис выражений внутри директивы для создания динамических строк и URL.

URL могут начинаться со слэша (/) для локальный веб-путей (относительных DocumentRoot) или быть полным URL, который клиент сможет понять. Альтернативно можно написать сообщение, которое будет показано браузером. Помните, принятие решение, чем является параметр: URL, путём или сообщением, выполняется перед обработкой выражения.

Примеры:

# Показ статичного сообщения об ошибке:
ErrorDocument 500 "Sorry, our script crashed. Oh dear"
ErrorDocument 403 "Sorry, can't allow you access today"
ErrorDocument 403 Forbidden!

# Передача управления динамическому обработчику:
ErrorDocument 500 /cgi-bin/crash-recover
ErrorDocument 404 /errors/bad_urls.php
ErrorDocument 500 http://example.com/cgi-bin/server-error.cgi

# Показ статичной страницы об ошибке (будет сделан внутренний редирект, то есть
# пользователь увидит другую страницу, но адрес в веб-браузере не поменяется):
ErrorDocument 500 http://error.example.com/server_error.html
ErrorDocument 404 /errors/not_found.html
ErrorDocument 401 /subscription/how_to_subscribe.html
ErrorDocument 401 /subscription_info.html

# Передача управления динамическому обработчику, а также передача переменной
ErrorDocument 403 /errors/forbidden.py?referrer=%{escape:%{HTTP_REFERER}}

Синтаксис директивы ErrorDocument следующий:

ErrorDocument <3-цифровой-код> <действие>

где в качестве <действия> могут быть:

  • Локальный URL для перенаправления (если действие начинается с "/").
  • Внешний URL для перенаправления (если действие является правильным URL).
  • Текст для отображения (если не подходит ничего из вышеперечисленного). Текст должен быть обёрнут в двойные кавычки (") если он состоит из более чем одного слова.

При перенаправлении к локальному URL устанавливаются дополнительные переменные окружения, на основе которых можно более детально настроить ответ. Они не отправляются на внешние URL.

Доступные переменные окружения

Перенаправление на другой URL может быть полезным особенно если передаётся некоторая информация, которая может использоваться для более ясного объяснения или журналирования условия ошибки.

Для достижения этого, когда отправляется редирект ошибки, устанавливаются дополнительные переменные окружения, которые генерируются из заголовков, предоставленных исходным запросом, их имя получается из добавления к оригинальному имени заголовкапрефикса 'REDIRECT_'. Это позволяет документу для обработки ошибки получить контекст оригинального запроса.

Например, вы можете получить, в дополнении к более обычным переменным окружения, следующие:

REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/jpeg, image/png
REDIRECT_HTTP_USER_AGENT=Mozilla/5.0 Fedora/3.5.8-1.fc12 Firefox/3.5.8
REDIRECT_PATH=.:/bin:/usr/local/bin:/sbin
REDIRECT_QUERY_STRING=
REDIRECT_REMOTE_ADDR=121.345.78.123
REDIRECT_REMOTE_HOST=client.example.com
REDIRECT_SERVER_NAME=www.example.edu
REDIRECT_SERVER_PORT=80
REDIRECT_SERVER_SOFTWARE=Apache/2.2.15
REDIRECT_URL=/cgi-bin/buggy.pl

Чтобы посмотреть на эти переменные, вы можете в файл .htaccess добавить строку:

ErrorDocument 404 /er.php

В файл er.php скопируйте:

<?php

print_r($_SERVER);

И вызовите на сервере ошибку 404:

Переменные окружения REDIRECT_ создаются из переменных окружения, которые существовали перед редиректом. Они переименовываются с префиксом REDIRECT_, то есть HTTP_USER_AGENT становится REDIRECT_HTTP_USER_AGENT.

REDIRECT_URL, REDIRECT_STATUS, и REDIRECT_QUERY_STRING гарантировано будут установлены, а другие заголовки будут установлены только если они существовали до условий возникновения ошибки.

Ни одна из них не будут установлены если целью ErrorDocument является внешний редирект (всё что угодно, начинающееся со схем вроде http:, даже если она отсылает на тот же хост что и сервер).

Кстати, обычные переменные окружения можно использовать прямо в директиве ErrorDocument, пример вывода пользователю, вызвавшему ошибку 404, небольшой истории:

Для этого в файл .htaccess нужно добавить строку:

ErrorDocument 404 "You requested <b>%{REQUEST_URI}</b> on the <b>%{HTTP_HOST}</b> host using the <b>%{REQUEST_METHOD}</b> method and the <b>%{REQUEST_SCHEME}</b> scheme, but you got the 404 error.<br>So I collected some information about you: your IP address is <b>%{REMOTE_ADDR}</b>, and your User Agent is <b>%{HTTP_USER_AGENT}</b>."

Как можно убедиться, такие динамические сообщения показываются даже без внешнего обработчика. Правда, если хотя бы одна из используемых переменных окружения не определена, то это вызовет ошибку сервера 500.

Дополнительно можно использовать специальное значение default, чтобы указать Apache httpd простое жёстко прописанное сообщение. Хотя это не требуется в обычных обстоятельствах, слово default может восстановить то значение, которое используется в Apache httpd по умолчанию для простого жёстко прописанного сообщения, в противном случае, это сообщение будет получено от существующей директивы ErrorDocument.

ErrorDocument 404 /cgi-bin/bad_urls.pl

<Directory "/web/docs">
  ErrorDocument 404 default
</Directory>

Помните, что когда устанавливаете ErrorDocument, который указывает на удалённый URL (любая строка, перед которой стоит протокол http или что-то подобное), то Apache HTTP отправит перенаправление клиенту, говоря ему, где найти этот документ, даже если документ в конечном счёте находится на этом же самом сервере. Это имеет несколько последствий, самым важным из которых является то, что клиент не получит оригинальный код статуса ошибки, но вместо этого получит код статуса редиректа. Это, в свою очередь, может сбить веб роботов и других клиентов, которые на основании кода статуса пытаются определить, является ли URL действительным. Дополнительно, если вы используете удалённый URL в ErrorDocument 401, клиент не будет знать о запросе пароля у пользователя, поскольку он не получит код статуса 401. Следоавтельно, если вы используете директиву ErrorDocument 401, то вы должны отправлять на локальный документ.

Microsoft Internet Explorer (MSIE) по умолчанию игнорирует сообщения об ошибках сгенерированные сервером, когда они «слишком маленькие» и подставляет свои собственные «дружественные» сообщения об ошибках. Порог размер варьирует от типа ошибки, но в общем если вы делаете вашу страницу ошибки больше чем 512 байт, тогда MSIE покажет сгенерированную сервером ошибку не маскируя её.

Настройка ответов об ошибках

Если вы укажете свой ErrorDocument на какие-то динамические обработчики, такие как документ на стороне сервера, сценарий CGI или другой обработчик, вы можете использовать доступные переменные среды для настройки этого ответа.

Если ErrorDocument указывает локальное перенаправление на сценарий CGI, сценарий должен включить в свой вывод поле заголовка «Status:», чтобы обеспечить получение на клиенте код статуса ошибки. Например, сценарий Perl ErrorDocument может включать следующее:

...
print "Content-type: text/html\n";
printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
...

Если скрипт предназначен для обработки определённого состояния ошибки, например 404 Not Found, он может вместо этого использовать конкретный код и текст ошибки.

Обратите внимание, что если ответ содержит заголовок Location: (для того, чтобы выполнить перенаправление на стороне клиента), сценарий должен выдать соответствующий заголовок Status: (например, 302 Найдено). В противном случае заголовок Location: может не иметь никакого эффекта.

Многоязычные документы с ошибками

С вашей установкой Apache HTTP Server поставляется папка пользовательских документов об ошибках, переведённых на 16 различных языков. В каталоге конфигурации conf/extra также есть файл конфигурации, который можно включить, чтобы задействовать эту функцию.

В файле конфигурации вашего сервера вы увидите строку, такую как:

# Multi-language error messages
#Include conf/extra/httpd-multilang-errordoc.conf

Снятие комментария с этих строк включит эту функцию и предоставит согласованные с языком сообщения об ошибках на основе языкового предпочтения, установленного в браузере клиента.

Кроме того, эти документы содержат различные переменные REDIRECT_, так что конечный пользователь может предоставить дополнительную информацию о том, что произошло и что они могут сделать сейчас.

Эти документы могут быть настроены в любой степени, чтобы вы предоставили пользователям более полезную информацию о вашем сайте и о том, что они могут там ожидать.

Для использования этой функции должны быть включены mod_include и mod_negotiation.

Заключение

Хотя большинство сообщений об ошибках могут быть переопределены, существуют определённые обстоятельства, когда внутренние сообщения используются независимо от настройки ErrorDocument. В частности, если обнаружен некорректный запрос, обычная обработка запроса будет немедленно остановлена, и будет возвращено внутреннее сообщение об ошибке. Это необходимо для защиты от проблем безопасности, вызванных неправильными запросами.

Если вы используете mod_proxy, вы можете включить ProxyErrorOverride, чтобы вы могли предоставлять пользовательские сообщения об ошибках от имени ваших серверов Origin. Если вы не включите ProxyErrorOverride, Apache httpd не будет генерировать пользовательские документы об ошибках для проксируемого (передаваемого в качестве посредника) содержимого.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *