nginx可以处理重复的HTTP标头吗?

时间:2015-04-01 17:08:05

标签: nginx httpserver http-status-code-400

客户端正在向服务器发送带有重复标头的请求。像这样:

GET /somefile.txt HTTP/1.1
Host: example.com
Accept: */*
If-Modified-Since: Tue, 31 Mar 2016 20:00:12 GMT
If-Modified-Since: Tue, 31 Mar 2016 20:00:12 GMT
If-Modified-Since: Tue, 31 Mar 2016 20:00:12 GMT

Apache通过将所有重复标头与“,”连接来处理此请求。因此,生成的(已处理的)请求将如下:

GET /somefile.txt HTTP/1.1
Host: example.com
Accept: */*
If-Modified-Since: Tue, 31 Mar 2016 20:00:12 GMT, Tue, 31 Mar 2016 20:00:12 GMT, Tue, 31 Mar 2016 20:00:12 GMT

但是nginx返回代码400(错误请求)。现在我无法修改客户端的行为。我需要在nginx服务器上使用tmp解决方案来处理这些请求(例如Apache)

感谢。

1 个答案:

答案 0 :(得分:1)

标题“If-Unmodified-Since”的唯一性检查是硬编码的(请参阅[1] [2])。它不能被禁用或解除,因为Nginx在解析期间验证头,即在任何其他处理程序或配置选项可以拦截进程之前的请求处理的早期阶段。所以,正确的答案是否定的,遗憾的是没有正确的方法让Nginx忽略这个问题。

然而,有一个肮脏的解决方法。它利用了Nginx仅解析请求标头一次并且在内部重定向后不重新验证它们的事实。这意味着您可以使用error_page拦截400错误,然后在内部将请求重定向到同一位置:

# = is important here!
error_page 400 = @workaround;

location @workaround {
    rewrite ^(.*)$ $1 break;
}

但要注意,因为这不是Nginx的工作方式,这种解决方法有几个严重的缺点:

1)只有“If-Unmodified-Since”的第一个值将传递给后端。

2)由于Nginx在遇到错误后停止解析请求标头,因此“If-Unmodified-Since”之后的标题根本不会传递给后端。

第二个缺点实际上非常关键,所以我个人不建议使用这种方法。