0

我有一个 nginx 服务器负载平衡几个 express (node.js) 服务器。每次我在查询中收到带有未编码空格的请求时,都会关闭连接,而 nginx 认为它已关闭。然后它向上游的下一个 express 发出相同的请求,得到相同的结果,因此当没有任何事情发生时,整个集群都停止运行。

查看日志,这些请求来自 Mozilla 4 等旧浏览器。我还可以使用 curl 模拟该行为:

curl "http://mysite.com/path/?q=foo bar"

我尝试使用各种正则表达式添加重写规则,以使用 %20 对该空格进行编码:

rewrite     "^(.*)\ (.*)$"  "$1%20$2"    last;
rewrite     "^(.*)\s(.*)$"  "$1 $2"    last;
rewrite     "\s"  "%20"    last;
...

但似乎没有任何效果。是我的正则表达式有问题还是只是 nginx 不允许只切换一个字符?你知道解决问题的其他方法吗?也许在快递/节点级别,以避免它只是关闭连接?

4

1 回答 1

1

仔细看了这个之后,我不认为 nginx 是完成这项任务的最佳工具。如果不使用 perl 模块,您将无法替换所有出现的内容(如果我错了,请纠正我)。

这些请求不符合 HTTP 标准,因此您拒绝它们是正确的。

如果你绝对想接受它们,你仍然可以只使用 node.js:

HTTP 解析器通过http._connectionListener. 该函数采用 TCP 套接字,解析动词、查询和标头并发出request事件(传递给的函数createServer自动侦听)。

在您的情况下,该函数永远不会触发事件,而是在您获得更改以执行其他任何操作之前关闭连接。

您可以在 HTTP 解析器看到它之前劫持它以重写请求:

var util = require('util'),
    http = require('http');

var oldConnectionListener = http._connectionListener;

http._connectionListener = function (connection) {
  var cleaner = new QueryCleaner(connection);

  oldConnectionListener(cleaner);
};

QueryCleaner将是一个流,如果不正确,则重写查询,然后传递流的其余部分。

于 2013-10-14T10:13:43.603 回答