#ruby-on-rails #ruby #apache #http-headers
Вопрос:
У меня есть приложение rails, которое работает нормально, за исключением одной вещи.
Когда я запрашиваю что-то, чего не существует (т. Е. /not_a_controller_or_file.txt) и rails выдает исключение «Маршрут не совпадает…», ответ такой (намеренно пустая строка):
HTTP/1.1 200 OK
Date: Thu, 02 Oct 2008 10:28:02 GMT
Content-Type: text/html
Content-Length: 122
Vary: Accept-Encoding
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Status: 500 Internal Server Error
Content-Type: text/html
<html><body><h1>500 Internal Server Error</h1></body></html>
У меня есть плагин ExceptionLogger в /vendor, хотя, похоже, проблема не в этом. Я не добавил никакой обработки ошибок, кроме пользовательской 500.html публично (хотя ответ не содержит этого HTML), и я понятия не имею, откуда берется этот фрагмент html.
Итак, что-то, где-то добавляет этот код состояния HTTP/1.1 200 слишком рано или статус: 500 слишком поздно. Я подозреваю, что это Apache, потому что я получаю соответствующий заголовок HTTP/1.1 500 (вверху), когда использую Webrick.
Мой производственный стек выглядит следующим образом: Apache 2 Mongrel (5 экземпляров) RubyOnRails 2.1.1 (встречается как в 1.2, так и в 2.1.1)
Я забыл упомянуть, что ошибка вызвана исключением «маршрут не совпадает…»
Комментарии:
1. Другими словами, Ruby выдает исключение, приводящее к сбою, и вы спрашиваете, почему оно отображает ошибку? :/
2. Я не думаю, что это его вопрос… его вопрос в том, почему Apache, похоже, считает, что запрос был успешным.
3. Я ответил и на этот вопрос, как можно лучше, не видя никакого кода. Почему Ruby выводит пустую строку, невозможно ответить, не увидев код. Но именно это происходит и заставляет Apache отправлять неверное сообщение.
4. «Маршрут не совпадает…» происходит во время сопоставления, перед контроллером, поэтому мы не можем использовать rescue_action_in_public. Я нашел строку, которая выводит заголовок состояния в файле actionpack/lib/actioncontroller/dispatcher.rb:59 (rails 2.1.1), Но почему перед кодом состояния есть дополнительная строка? без понятия.
5. какой URL-адрес не соответствует маршруту?
Ответ №1:
Это довольно старая тема, но, как бы то ни было, я нашел отличный ресурс, который включает подробное описание проблемы и ее решения. По-видимому, эта ошибка влияет на рельсы
- Статья, которая помогла мне понять проблему и написать свой собственный патч.
- Официальный билет на ошибку Rails, который включает исправление для Rails 2.2.2.
Ответ №2:
Этот html — файл поступает из Rails. Он сталкивается с какой-то ошибкой (возможно, каким-то исключением или какой-то другой неисправимой ошибкой).
Если есть дополнительная пустая строка между заголовком Status: и фактическими заголовками, а не просто опечатка, то это во многом объясняет, почему Apache сообщает о сообщении 200 OK.
Заголовок состояния-это то, как Rails, PHP или что-то еще сообщает Apache: «Произошла ошибка, пожалуйста, верните этот код вместо 200 ОК». Тот факт, что есть пустая строка, означает, что происходит что-то дополнительное, и Ruby выводит пустую строку перед выводом ошибки по какой-либо причине. Возможно, это предыдущий вывод из вашего сценария. Короче говоря, дополнительная пустая строка означает, что Apache думает: «О, пустая строка, никаких дополнительных заголовков, теперь это все содержимое»., что соответствовало бы заголовку длины содержимого, который вы предоставили.
Мое предположение о том, почему есть пустая строка, было бы предыдущим выводом сценария, возможно, строкой, заканчивающейся в конце страницы с полным сценарием. Что касается того, почему происходит ошибка 500, здесь недостаточно информации, чтобы сказать вам об этом. Возможно, ошибка ввода-вывода файла.
Правка: Учитывая дополнительную информацию, предоставленную Дейвом о внутренних устройствах, я бы сказал, что на самом деле это проблема с проксированием, которое происходит за кулисами… Я не мог бы сказать вам точно, что именно, кроме того, что уже было сказано.
Комментарии:
1. w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14 ^ где определен заголовок Status:?
2. Это потому, что это НЕ заголовок HTTP, это заголовок CGI. Он должен быть пойман и использован сервером, он никогда не должен быть замечен. ietf.org/rfc/rfc3875 , раздел 6.3.3.
3. Но мостом между apache и mongrel является HTTP, а не CGI.
Ответ №3:
Это исходит от самих рельсов.
http://github.com/rails/rails/tree/master/actionpack/lib/action_controller/dispatcher.rb#L60
Диспетчер возвращает страницу с ошибкой с кодом состояния 200 (Успешно).
Комментарии:
1. Смотрите мой ответ на ваш комментарий к моему ответу. Это неверно, поскольку это не то, что он пытается сделать. Статус-это заголовок CGI, и он хорошо сформирован.
2. Но мостом между apache и mongrel является HTTP, а не CGI
3. А как насчет отношений между Дворняжкой и Руби? Где-то где-то происходит CGI, потому что это заголовок CGI, и если бы ruby не запускался через CGI, у него не было бы причин использовать этот заголовок. Во всяком случае, мой ответ все еще остается в силе, потому что заголовки где-то разошлись, поэтому пустая строка и
4. повторяющийся заголовок типа содержимого.
5. Смотрите это письмо, полукровка использует CGI, чтобы поговорить с Рором: rubyforge.org/pipermail/mongrel-users/2006-October/001946.html