Pull to refresh

Comments 39

Это о каком из указанных в топике продуктов?
Не правильней ли будет исправить ошибки в приложениях?
Правильней, это несомненно!

Однако за много лет их так никто и не исправил.

Более того: в официальной документации по языку PHP употребление функции header() объясняют на примере «header("HTTP/1.0 404 Not Found")», а не «header($_SERVER['SERVER_PROTOCOL']. " 404 Not Found")», поэтому можно с превеликой уверенностию и в будущем ожидать приумножения в числе именно таких приложений.

Стало быть, популяризация быстрого обходного пути, во всяком случае, небесполезна. (Особенно для тех несчастных, на кого давит заказчик или начальство, требуя наладить сайт вот прям щазз; хорошо, что мне не довелось попасть в их число по этому поводу.)

Объяснение же глубинной причины ошибки поспособствует её надлежащему исправлению со временем.
Разработчикам web-приложений на будущее: у функции header() есть третий параметр $http_response_code. Я, например, пользуюсь им таким образом: header('Content-Type:', true, $response->getStatusCode());, тем самым еще и сбрасывая значение заголовка Content-Type, которое устанавливает Apache (например, если это публичный хостинг, и у меня нет прав на редактирование httpd.conf/.htaccess).
Сразу уточню, что значение-то указанного заголовка сбрасывается оттого, что второй параметр равен true, причём по умолчанию он и так равен true (его бы и указывать не пришлось, кабы не необходимость указать третий параметр после него).
Ещё скажу, что я бы не сбрасывал «Content-Type», а задал его нужным (например, 'Content-Type: text/html'), а не то как-то даже и странно. К RFC 2616 надо относиться с уважением.
Ну, и статус-код тогда не от балды брать, а согласно RFC. Но не факт, что все браузеры поймут.
const OK                    = 200;
const CREATED               = 201;
const NO_CONTENT            = 204;
const RESET_CONTENT         = 205;
const PARTIAL_CONTENT       = 206;
const MOVED_PERMANENTLY     = 301;
const FOUND                 = 302;
const SEE_OTHER             = 303;
const NOT_MODIFIED          = 304;
const BAD_REQUEST           = 400;
const UNAUTHORIZED          = 401;
const FORBIDDEN             = 403;
const NOT_FOUND             = 404;
const RANGE_NOT_SATISFIABLE = 416;
const INTERNAL              = 500;
const UNAVAILABLE           = 503;


Я надеюсь, что хотя бы эти коды все браузеры понимают (ну, те, что не поймут, уже пойдут для REST-приложений со своим desktop-клиентом)?
P.S. Я про конкретно статус-коды (числа), а не про сообщения вроде «Not Found», которые, ЕМНИП, не являются строго задекларированными, и клиент их вовсе не обязан парсить.
Проверял (правда давно): 201 с Locatioon не работал (вместо него приходится использовать 303), с 301 и 302 вообще ничего не ясно никому, настолько, что ввели 303 и 307, чтобы не путаться больше, с 503 с Retry-After тоже какие-то проблемы были.
Мне интересно, за что заминусовали комментарий? Если есть аргументы против, то интересно было бы их почитать.
Хей-хей, нефиг на хомячков гнать! (^_^)
Есессено, что потом он задается нужным (вместе с другими заголовками). Просто если контент какой-то левый и неизвестный (мало ли), то посылать Content-Type: text/html как-то неправильно, ИМХО. Тогда уж какой-нить text/plain или application/octet-stream…
Потому что это пример работы процедуры header, и ни к чему его приукрашивать переменной $_SERVER, которая собственно к самой процедуре никак не относится.
Что касается статьи, то на каждого мудреца довольно простоты :) Я например, с таким никогда не сталкивался (потому что не использую друпалы, джумлы и т.д.), но думаю, что многие будут благодарны вам за этот фикс.
> nginx полагается на протокол HTTP версии 1.0 при общении с бэкэндом.
А почему так? Если в заголовке явно указано 1.1?
Новой эту версию не назовешь, ибо лет 10 как приняли 1.1.
Потому что при общении с бекендами возможности http 1.1 не востребованы. А ответ версии 1.1 на запрос версии 1.0 — это явная ошибка. Кстати, начиная с какой-то версии nginx всетаки поддерживает общение с бекндами на http 1.1.
То, что возможности невостребованы — ещё не повод не поддерживать самый популярный протокол вообще. Явно косяк nginx-а, тем более там нет каких-то драматических отличий.
Это не косяк nginx. Он-то как раз никакх соглашений не нарушает. А то, что он обращается к серверу по 1.0 — вполне логично (зачем лишние манипуляции при выполнении запроса?).
Затем, что это ничем, кроме абстрактных перфекционистских рассуждений об идеальном мире, не обоснованное ограничение, жестко накладываемое nginx-ом на бэкенд. Который может быть вообще любым и допустим http 1.0 не держать вообще как класс. Что в данном случае и вылезло.
Нахрена вообще люди протоколы выдумывают, если по вашей логике в ответ все равно может прийти все что угодно?
Стандарт это вещь в себе. Особенно у буржуев, где они являются рекомендацией (в отличие от гостов, имеющих силу закона).
Есть золотое правило: строго придерживаться стандартов при записи и допускать любые имеющие смысл отклонения при чтении. В случае nginx-a оно не выполнено.
Стандарты для того и придуманы чтобы их соблюдать.
Если Apache не следует стандартам при этом заявляя что им соответствует, то нужно его исправлять.
Если предугадывать все возможные криворукости других программистов, то никаких человекочасов не хватит.
Это не касается взаимодействия с потенциально неграмотным пользователем, с которым вы вероятно перепутали данную ситуацию.
не обоснованное ограничение, жестко накладываемое nginx-ом на бэкенд
Ну да, прямо, очень жёсткое ограничение — расчёт на соблюдение стандарта)
может быть вообще любым и допустим http 1.0 не держать вообще как класс
Поддерживает 1.1 и отказывается поддерживать 1.0? Имхо, это экзотический случай, в отличии от поддержки 1.0 и неподдержки 1.1, который редок, конечно, тоже, но по крайней мере логичен.
> Который может быть вообще любым и допустим http 1.0 не держать вообще как класс.
Насколько я понимаю, любой сервер, корректно поддерживающий только http 1.1 — автоматически корректно поддерживает http 1.0 (за вычетом неверной версии протокола в заголовке). Проблема вылезла от того, что apache некорректно поддерживает http 1.1.
> Явно косяк nginx-а.
Апачь отдает ответ чанками клиенту (nginx), который не только не указал в запросе, что он может принимать чанки, но и использовал версию протокола, в которой вообще ничего такого нет. Это не говоря уже о том, что чанки в принципе нужны только при keep-alive соединениях, а nginx явно посылает бекенду Connection: close. И все равно косяк nginx. Ах он сукин сын :)
Апач в данном случае не при чем — его просто так настроили.
Косяк nginx-а в неподдержке http 1.1, которому уже сто лет в обед.
> его просто так настроили.
О каких именно настройках речь?
В чем косяк? Может апачу SMTP на HTTP запросы выдавать? А потом жаловаться, что nginx не поддерживает SMTP?
как-раз, Nginx can proxy IMAP, POP3, and SMTP protocols.
Ок, не релевантно.
Скажем, протокол ICQ, а не SMTP.
Это не имеет значения. Запрос отправлен был в HTTP/1.0 Следовательно ответ должен быть либо в HTTP/1.0, либо HTTP/0.9, НО НЕ ВЫШЕ 1.0
Эта же ошибка была в одной из ранних версий третьей Коханы для всех страниц, не только страниц ошибок.
Я помню как я искал отчего же у меня эти цифры лезут, когда сфинкса настраивал :) то ли думал дело в 5ти утра, то ли в чем :)
Насчет Drupal Вы не правы — только древняя 5-я версия так делает. Распространенная 6-я уже не содержит ошибки:

drupal_set_header($_SERVER['SERVER_PROTOCOL']. ' 404 Not Found');

(http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_not_found/6)
Лучи счастья автору!!! Сколько времени я на это угробил и сколько еще мне его автор сэкономил!
Проблема однозначно на стороне бэк-энда.

В качестве обхода проблемы (особенно если используется не Apache) по идее также должна помочь установка nginx >= 1.1.4 или chunked_transfer_encoding off.
Sign up to leave a comment.

Articles