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

时间:2020-03-06 15:01:06  来源:igfitidea点击:

我有一个Rails应用程序,除了一件事以外,它都可以正常工作。

当我请求不存在的内容(即/not_a_controller_or_file.txt)并且rails抛出" No Route match ..."异常时,响应为(有意的空白行):

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状态代码为时过早,或者Status:500为时太晚。我怀疑它是Apache,因为使用Webrick时会得到适当的HTTP / 1.1 500标头(在顶部)。

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

我忘了提,该错误是由"没有路线匹配..."异常引起的

解决方案

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

如果在Status:标头和实际标头之间有多余的空行,而不仅仅是错字,那么这将很长的路要解释Apache为什么报告200 OK消息。

Status标头是Rails,PHP或者告诉Apache"出现错误,请返回此代码而不是200 OK"的方式。空行的事实意味着发生了一些额外的事情,并且Ruby出于某种原因在错误输出之前输出了空行。也许这是脚本的先前输出。不过,总而言之,多余的空白行表示Apache认为"哦,空白行,没有多余的标题,现在就全部内容了。",这与我们提供的Content-Length标题一致。

我的猜测是为什么以前的脚本输出是空白行,而该行可能会在完整脚本页面的结尾处结束。至于为什么发生500错误,这里没有足够的信息告诉我们。可能是文件I / O错误。

编辑:考虑到Dave提供的有关内部的额外信息,我想说这实际上是幕后发生的代理问题...我无法确切地说出什么,除了已经说过的。

这来自Rails本身。

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

调度程序将返回错误页面,状态码为200(成功)。

这是一个相当古老的线程,但值得的是,我找到了一个不错的资源,其中包括对该问题和解决方案的详细说明。显然,与Mongrel一起使用时,此错误会影响Rails <2.3.

  • 这篇文章帮助我了解了问题并编写了自己的补丁。
  • 包含Rails 2.2.2补丁的Rails官方故障单。