nginx и непонятные цифры перед

    После установки nginx в качестве frontend к apache встретился проблемой: в начале некоторых html-документов вставлялось шестнадцатеричное число, а в конце- ноль. Проблема проявлялась только на страницах с ошибками CMS Drupal.
    По сути эти документы не что иное, как chuncked-ответы сервера. После недолгого разбирательства выяснил, что такая проблема встречается из-за кривого php-кода. На HTTP/1.0 запрос, php-код отдавал HTTP/1.1 ответ. Лезть в друпаловский код не хотелось, потому я решил немного поднастроить apache (2.2). В httpd.conf добавил следующие строки:

    <IfModule setenvif_module>
    BrowserMatch ".*" downgrade-1.0 force-response-1.0
    </IfModule>
    


    После чего, естественно, перезапустил apache.

    По сути, я точно не знаю что значат эти настройки, но предполагаю, что теперь браузеры для моего сайта будут юзать исключительно HTTP/1.0 протокол. Тщательно проверив работоспособность сайта, убедился, что всё работает хорошо, и успокоился :)

    UPD: Виноватых в произошедшем на самом деле определить очень сложно. Но для меня важно то, что описанная выше настройка апача полностью решает проблему.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 19

      0
      А кто ему посылает http/1.0 запрос? Приличные люди так не делают.
        0
        А что, http/1.0 отменили? Он юзается до сих пор, и очень интенсивно. Так что вопрос не в том, кто посылает, а в том, какого хрена php-код криво отвечает. Так что и Ваш вопрос, и Ваш минус не в тему абсолютно.
          0
          Не отменили, но принудительно отвечать на все запросы 1.0 ответом — тоже не дело.
          А вот разобраться с причиной проблемы, а не делать кривой костыль — это была бы хорошая статья.

          P.S. а минус не мой.
            +1
            Согласно спецификации, на запрос HTTP/1.0 отвечать надо той же версией протокола, HTTP/1.0. Может клиентская сторона и вовсе HTTP/1.1 не поддерживает, потому HTTP/1.0 и запрашивала.
            Причина проблемы выяснена — php-код кривой. По-хорошему его править и надо. Но править код постоянно обновляемого друпала — не вариант.
            При этом посмотрел логи — HTTP/1.1 всё равно работает. Так что сакральный смысл настройки BrowserMatch у апача остаётся неясным.
              0
              Если постоянно править код не вариант — запостите баг или патч :)
            +1
            PHP-код отвечат абсолютно верно и нормально. Это известная проблема именно nginx-а при выполнении 3-х условий:
            1) код ответа 404,
            2) версия протокола HTTP/1.1,
            3) размер тела ответа болье некого значения Х (я просто не помню сейчас точно это значение, но оно константно).

            Это раз. Во-вторых, проблема легко решается просто выдачей ответа из PHP заголовком: «header(»HTTP/1.0 404 Not Found");" вместо «header(»HTTP/1.1 404 Not Found");". Этого абсолютно достаточно, и не важно в каком протоколе идет запрос от пользователя.
              0
              Спасибо! Как-раз столкнулся с такой проблемой, Ваше решение было очень кстати!
          0
          тоже встречался с этим, щас не помню как разруливал… кажется, просто переводил клиента с жиксы на сквид
            0
            А где именно в коде ошибка напишите пожалуйста, чтоб можно было посмотреть/поправить.
              0
              Вот здесь смотрите код функции drupal_not_found
              api.drupal.org/api/function/drupal_not_found/6

              Там жётско прописано «drupal_set_header('HTTP/1.1 404 Not Found');».
              Как фиксить не в курсе — я в php не силён.
              0
              Дело совсем не в Друпале. Поиском по гуглу пользоваться не умеете? Ищите по фразе «nginx цифры вверху страницы».
                0
                Вот как раз ваш случай (Да и мой тоже. )) ).
                  0
                  Попробовал убрать «BrowserMatch ».*" downgrade-1.0 force-response-1.0" и отключить Keep-Alive. Проблема снова проявилась. Вернул BrowserMatch обратно.
                  Так что случай не мой.
                    0
                    Я вам всего лишь написал, что Друпал тут совершенно не при чем.
                      0
                      См. коммент выше. Друпал вызывает жёстко drupal_set_header('HTTP/1.1 404 Not Found'); на 404-ю ошибку. Так что дело в друпале, в его коде. Другой вопрос, что проявляется проблема только в связке nginx с apache.
                        0
                        Фраза «После недолгого разбирательства выяснил, что такая проблема встречается из-за кривого php-кода» некорректна. Тут не код кривой, а особенности работы связки nginx и Apache. Точно такая же ошибка проявляется и на ipb, например.
                          0
                          Да и nginx вроде не причём. Это апач делает chunked ответ на http/1.0 запрос, если php отправляет http/1.1 заголовок.

                          Похоже бага в апаче.
                  0
                  Если неизвестен заголовок «Content-Length» (для HTTP/1.1) Apache передаёт ответ чанками (chunks) и добавляет заголовок «Transfer-Encoding: chunked».

                  Решается в PHP так:
                  header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
                  header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');

                  Или в Apache так:
                  SetEnv force-no-vary
                  SetEnv downgrade-1.0
                    0
                    Спустя два года — очень кстати совет :). Спасибо.

                    Only users with full accounts can post comments. Log in, please.