Nginx + Apache. Посторонние числа на страницах ошибок
Nginx + Apache. Посторонние числа на страницах ошибок
Поздний вечер не предвещал ничего таинственного и, вернувшись после изнуряющей тренировки по хапкидо, хотелось быстрее забыться сладким сном...но не тут-то было...заметила на сайте странные посторонние числа при посещении несуществующих страниц. В начало страницы добавляется загадочное шестнадцатеричное число типа 32a4 и в конец 0.
Сначала решила, что забыла вывод какого-нибудь id в Drupal, но в хидерах обнаружила двойной chunked:
Transfer-Encoding: chunked, chunked
Chunked transfer encoding - механизм передачи данных в протоколе передачи гипертекста (HTTP), позволяющий надёжно доставлять данные от сервера клиенту (чаще всего клиентскому web-браузеру) без необходимости заранее знать точный размер всего тела HTTP сообщения. Это достигается разбиением сообщения на небольшие части (chunks), а затем передачей каждой части с указанием только её размера. Окончание передачи сообщения определяется наличием последней части с нулевой длиной. Такой механизм позволяет передать динамически сформированные объекты, для которых нельзя заранее определить размер. Он стал доступен только начиная с HTTP версии 1.1 (HTTP/1.1). Без механизма сhunked transfer encoding с каждым HTTP пакетом необходимо указывать заголовок Content-length, чтобы клиент мог найти конец передаваемого сообщения.
Итак, при "Transfer-encoding: chuncked" данные передаются кусками с указанием их размера. Откуда тогда взялся двойной chunked? Дело в том, что у моего хостера установлен web-сервер apache и кэширующий сервер nginx, который обменивается данными с apache по HTTP/1.0. А в php-движке Drupal и некоторых модулях разработчики жестко указали протокол HTTP версии 1.1. Пример из common.inc,v 1.756.2.88 2010/06/02:
function drupal_not_found() { drupal_set_header('HTTP/1.1 404 Not Found'); watchdog('page not found', check_plain($_GET['q']), NULL, WATCHDOG_WARNING);
function drupal_site_offline() { drupal_maintenance_theme(); drupal_set_header('HTTP/1.1 503 Service unavailable');
function drupal_access_denied() { drupal_set_header('HTTP/1.1 403 Forbidden');
Решить проблему можно, добавив директиву в .htaccess, которая принуждает apache к использованию HTTP версии 1.0:
BrowserMatch ".*" downgrade-1.0 force-response-1.0
В php коде исправить:
drupal_set_header('HTTP/1.1 404 Not Found');
на:
drupal_set_header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
Нажимая кнопку «Сохранить», я подтверждаю свою дееспособность, согласие на получение информации от NetK, согласие на обработку персональных данных в соответствии с Политикой конфиденциальности и Пользовательским соглашением.