在节点应用程序上触发许多请求以进行测试导致套接字挂起/ ECONNRESET错误

时间:2014-03-08 17:54:19

标签: node.js express brute-force supertest

我正在尝试为我的应用程序编写测试,我使用express-brute来防止暴力攻击。

我有以下测试:

it('should return 429 status after 1000 attempts', function (done) {
    this.timeout(5000);

    var counter = 0;

    var makeRequest = function (count, done) {
        counter++;
        request(app)
        .post('/login')
        .send({ username: 'a+' + count + '@b.com', password: 'wrong' + count })
        .end(function (err, res) {

            if (err) {
                console.log('failed request #', counter); 
                return done(err);
            }

            if (counter < 1001) {
                makeRequest(counter, done);
            }
            else {
                res.header.location.should.equal('/account/login');
                res.statusCode.should.equal(429);
                done();
            }
        });
    }

    makeRequest(counter, done);
});

会抛出错误:

  

错误:套接字挂断   有时它是   错误:读取ECONNRESET

它始终围绕连接#225

相同的测试(只有20个左右的请求)工作正常(如果我改变我的快速配置)

是什么导致它出错?

我没有正确关闭/处理连接吗?

2 个答案:

答案 0 :(得分:2)

您使用什么操作系统?

可能需要增加允许打开的套接字的数量。

例如,请参阅此处:How to increase limits on sockets on osx for load testing?

答案 1 :(得分:0)

我能够通过使用此代码复制资源耗尽问题,我相信这会复制您问题的基本要素:

var request = require("supertest");
var express = require("express");

var app = express();

app.post('/login',
    function (req, res, next) {
        res.send('Success!');
    }
);

var server = app.listen();

var counter = 0;

function makeRequest(count, done) {
    counter++;
    request(app)
        .post('/login')
        .send({ username: 'a+' + count + '@b.com', password: 'wrong' + count })
        .end(function (err, res) {

            if (err) {
                console.log('failed request #', counter);
                done(err);
            }

            if (counter < 1001) {
                console.log(counter);
                makeRequest(counter, done);
            }
            else {
                console.log(res);
                done();
            }
        });
}

function done(err) {
    process.exit(1);
}

makeRequest(counter, done);

并按照以下方式运行:

$ (ulimit -n 100; node test.js )

我必须使用ulimit,因为无论什么原因导致我的操作系统上没有问题。 ulimit命令将打开文件的数量限制为100.当我像上面那样运行它时,请求号89失败。 (打开一些其他文件来运行脚本,这解释了为什么它在请求89而不是100时失败。)

如果我更改代码以便从我的应用程序创建服务器,我可以让代码运行完成:

var app = express();
// ...
var server = app.listen();

我在server而不是request使用app

request(server)
    .post('/login')
// ...

因此,使用app.listen()返回的内容可以解决问题。