为什么 Apache + Rails 会为代码 500 吐出两个状态标头



我有一个 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>

我在/vendor 中有 ExceptionLogger 插件,尽管这似乎不是问题所在。 我没有在公共场合添加任何超出自定义 500.html 的错误处理(尽管响应不包含该 HTML),而且我不知道这部分 html 来自哪里。

所以有些东西,某处添加HTTP/1.1 200状态代码太早了,或者状态:500太晚了。 我怀疑这是Apache,因为我在使用Webrick时会得到适当的HTTP/1.1 500标头(在顶部)。

我的生产堆栈如下:阿帕奇 2(5 个实例)RubyOnRails 2.1.1(在 1.2 和 2.1.1 中都有发生)


我忘了提,错误是由"没有路由匹配......"引起的。例外

这是一个相当古老的线程,但就其价值而言,我找到了一个很棒的资源,其中包括对问题和解决方案的详细描述。显然,当与Mongrel一起使用时,此错误会影响Rails <2.3。

  • 这篇文章帮助我理解了问题并编写了自己的补丁。
  • 一个官方的 Rails 错误票证,其中包含 Rails 2.2.2 的补丁。

这个html文件来自Rails。它遇到某种错误(可能是某种异常,或其他一些不可恢复的错误)。

如果 Status: 标头和实际标头之间存在额外的空行,而不仅仅是拼写错误,那么这将大大有助于解释为什么 Apache 报告200 OK消息。

状态标头是 Rails、PHP 或任何内容告诉 Apache "有一个错误,请返回此代码而不是 200 OK"。有一个空行的事实意味着正在发生额外的事情,Ruby 出于任何原因在错误输出之前输出一个空行。也许是脚本的先前输出。长话短说,额外的空行意味着 Apache 认为"哦,空行,没有额外的标题,现在都是内容了",这将与您提供的 Content-Length 标题一致。

我对为什么有一个空行的猜测是以前的脚本输出,也许是在完整脚本页面末尾结束的一行。至于为什么会发生500错误,这里没有足够的信息来告诉您。可能是文件 I/O 错误。

编辑:鉴于戴夫提供的有关内部结构的额外信息,我想说这实际上是幕后代理的问题......除了已经说过的内容之外,我无法确切地告诉你什么。

这是来自轨道本身。

http://github.com/rails/rails/tree/master/actionpack/lib/action_controller/dispatcher.rb#L60

调度程序返回状态代码为 200(成功)的错误页。

最新更新