Regex 在nginx上重写url查询中的空格(使用express)

Regex 在nginx上重写url查询中的空格(使用express),regex,node.js,nginx,express,Regex,Node.js,Nginx,Express,我有一个nginx服务器,用于平衡几个express(node.js)服务器的负载。每次我收到一个查询express上带有未编码空格的请求时,就会关闭连接,nginx认为它已关闭。然后,它向下一个express上游发出相同的请求,得到相同的结果,并因此在没有真正停机的情况下使整个集群停机 查看日志,这些请求来自Mozilla 4等旧浏览器。我还可以模拟curl的行为: curl "http://mysite.com/path/?q=foo bar" 我尝试使用各种正则表达式添加重写规则,用%2

我有一个nginx服务器,用于平衡几个express(node.js)服务器的负载。每次我收到一个查询express上带有未编码空格的请求时,就会关闭连接,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不允许只切换字符?
你知道解决这个问题的其他方法吗?也许在express/node级别,为了避免只关闭连接?

仔细研究后,我认为nginx不是执行此任务的最佳工具。如果不使用perl模块,就无法替换所有出现的情况(如果我错了,请更正)

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

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

HTTP解析器通过HTTP.\u connectionListener公开。此函数接受TCP套接字,解析谓词、查询和标题,并发出
请求
事件(传递给
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
将是一个流,如果查询不正确,它将重写查询,然后通过流的其余部分。

是的,我这样做了。它也不起作用。问题似乎只是替换url查询部分的字符。例如,如果我尝试替换字符“a”,它将替换路径中的a,而不是查询中的a。它提供了任何线索吗?用%20替换它是行不通的,因为它会在以后对结果进行编码。我的意思是,在应用正则表达式后,它会将%25更改为%2520。好的,我明白了。您可以使用$args变量来执行此操作。仍然不起作用。你能提供一个我如何重写$args本身的例子吗?我返回一个409错误代码。如果您知道如何用%20替换空格,那将是完美的,否则我可以用我的解决方法给出答案。至少它不会破坏整个集群。。。