plantegg 发表于 2015-11-14 09:47:16

Apache Httpd的mod_proxy模块修改了HTTP的响应吗

  前几天,一个开发组开发的一个模块,放到我们的产品环境上去后,发现其中的一个功能没有正常工作。用Fiddler查看HTTP记录,发现那个功能的发出的HTTP请求返回了500错误。查看文档,500代表Internal Server Error,服务器出错了。
  问题抛回给负责开发的组,他们查看了服务器log,没有发现相关的错误。而这个功能在他们自己开发的环境上都是可以的。
  难道和我们产品环境的部署有关?产品环境和开发环境的不同就只有,产品环境上用了Apache Httpd,并使用了mod_proxy做一个反向代理。尝试在产品环境上绕过Apache直接去访问对应的服务器,发现竟然真的是可以的。 用Fiddler一查,发现响应和Apache代理后的几乎没区别,唯一的不同就是返回的是298响应码。298?好像原来没看到过这个码,查文档,RFC确实没有明确的定义这个响应码。猜想,问题应该是因为服务返回了一个不标准的响应吗,Apache的mod_proxy就将它改成了500。
  Google一下,找到了一些:ServerFault上的讨论,貌似Apache的邮件目录。还找到了Apache对这个问题的一个Bug跟踪。总的来说,就是这个问题有些争论:有些人认为不应该随意自己定义响应码;有些人认为按照RFC的规定,响应码是可扩展的,比如2XX都是成功的响应码,那么定义298当然也是合理的。但是Apache还是没有改这个问题,这个问题在2.0以后的所有版本上都存在。
  查找文档,希望能找到一些配置能够绕过这个问题,但是没找到。我们表示很无奈,希望开发组能够不要自定义响应码,如果要自定义,可以通过增加自定义响应头来达到同样效果。开发组表示,他们没法修改了,因为使用了一个很公共的模块,短时间内没法改变。我们表示,我们短时间内也没法去掉Apache Httpd。
  继续研究,查看Apache的源代码,发现:如果服务器在返回298响应码的时候,能够同时返回一个字符串跟在响应码后面,Apache就不会修改响应码。这个很合理,按RFC规定,在200响应码后面应该要跟上字符串OK,在201响应码后面应该要跟上字符串Created等等。那我们响应298的时候,也加上一个字符串,既简单,又不会影响现有的功能,也符合规范。唯一的疑惑是,mod_proxy并没有文档说明,他们以后还会遵守这个行为(当然他们对于会修改响应码的这个行为也没提过)。但是至少对于我们现在来说,可以暂时先这样绕过这个问题。
  网上都没发现对这个问题的解决方法,贴出来希望对大家有帮助。
  紧接着又发现了一个类似的问题。有一个功能在没有Apache的时候是可以的,但是在有Apache的时候,就只有在IE下可以,在Chrome和Firefox上都不行。查看Fiddler,发现这个请求从服务器返回的时候没有"Content-Type"响应头,这个时候可能所有浏览器都默认认为响应内容是HTML,所以能够正常工作;而经过Apache代理后,Apache会加上了一个默认的头"Content-Type:text/plain",这个时候就只有IE会识别出类型是HTML并渲染,Chrome和Firefox就直接当文本显示了。解决方法就是修改Apache配置,将默认响应类型从text/plain改为text/html暂时先绕过这个问题。
  不守规范真可怕~, 看来以后还是有必要用http://validator.w3.org/测试一下服务是否符合规范才行。
  

  关键字:Apache,Httpd,mod_proxy,修改响应码
  

         版权声明:本文为博主原创文章,未经博主允许不得转载。
页: [1]
查看完整版本: Apache Httpd的mod_proxy模块修改了HTTP的响应吗