Skip to Content
 Русский Русский    English English   

 

Nginx + Apache. Посторонние числа на страницах ошибок

Nginx + Apache. Посторонние числа на страницах ошибок

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

Nginx + Apache. Посторонние числа на страницах ошибок

Сначала решила, что забыла вывод какого-нибудь 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');


 

G
Ваша оценка: Нет Средняя: 4.6 (18 голосов)