0

複数のエクスプレス(node.js)サーバーの負荷を分散するnginxサーバーがあります。クエリエクスプレスでエンコードされていない空白を含むリクエストを取得するたびに、接続が閉じられ、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 に答える