From 01a916eb2dc9b40e0705e6f21f716fac18be67a5 Mon Sep 17 00:00:00 2001 From: Jonatan Nilsson Date: Fri, 3 Nov 2023 22:51:51 +0000 Subject: [PATCH] socket: Set time out and forcibly close timed out sockets. Fix tests for different node versions --- flaska.mjs | 23 +++++++++++++++++++---- package.json | 2 +- test/flaska.api.test.mjs | 2 ++ test/helper.mjs | 5 ++++- test/http.test.mjs | 8 ++++---- test/middlewares.test.mjs | 10 +++++----- 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/flaska.mjs b/flaska.mjs index 679df06..1f8d176 100644 --- a/flaska.mjs +++ b/flaska.mjs @@ -1061,6 +1061,22 @@ ctx.state.nonce = nonce; } } + create() { + this.compile() + this.server = this.http.createServer(this.requestStart.bind(this)) + + this.server.on('connection', function (socket) { + // Set socket idle timeout in milliseconds + socket.setTimeout(1000 * 60 * 5) // 5 minutes + + // Wait for timeout event (socket will emit it when idle timeout elapses) + socket.on('timeout', function () { + // Call destroy again + socket.destroy(); + }) + }) + } + listen(port, orgIp, orgcb) { let ip = orgIp let cb = orgcb @@ -1071,8 +1087,8 @@ ctx.state.nonce = nonce; if (typeof(port) !== 'number') { throw new Error('Flaska.listen() called with non-number in port') } - this.compile() - this.server = this.http.createServer(this.requestStart.bind(this)) + + this.create() this.server.listen(port, ip, cb) } @@ -1082,8 +1098,7 @@ ctx.state.nonce = nonce; return Promise.reject(new Error('Flaska.listen() called with non-number in port')) } - this.compile() - this.server = this.http.createServer(this.requestStart.bind(this)) + this.create() if (this.server.listenAsync && typeof(this.server.listenAsync) === 'function') { return this.server.listenAsync(port, ip) diff --git a/package.json b/package.json index 05bd337..ec66df1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flaska", - "version": "1.3.3", + "version": "1.3.4", "description": "Flaska is a micro web-framework for node. It is designed to be fast, simple and lightweight, and is distributed as a single file module with no dependencies.", "main": "flaska.mjs", "scripts": { diff --git a/test/flaska.api.test.mjs b/test/flaska.api.test.mjs index 0d1a1c7..f0af7b9 100644 --- a/test/flaska.api.test.mjs +++ b/test/flaska.api.test.mjs @@ -988,6 +988,7 @@ t.describe('#listenAsync()', function() { createServer: function() { return { listenAsync: stubListenAsync, + on: stub(), } } }) @@ -1011,6 +1012,7 @@ t.describe('#listenAsync()', function() { createServer: function() { return { listenAsync: stubListenAsync, + on: stub(), } } }) diff --git a/test/helper.mjs b/test/helper.mjs index 29b40a6..797f4b9 100644 --- a/test/helper.mjs +++ b/test/helper.mjs @@ -6,7 +6,7 @@ const indexMap = [ 'thirdCall', ] -export function fakeHttp(inj1, inj2) { +export function fakeHttp(inj1, inj2, inj3) { let intermediate = { createServer: function(cb) { if (inj1) inj1(cb) @@ -15,6 +15,9 @@ export function fakeHttp(inj1, inj2) { listen: function(port, ip, cb) { if (inj2) inj2(port, ip, cb) else if (cb) cb() + }, + on: function(name, handler) { + if (inj3) inj3(name, handler) } } } diff --git a/test/http.test.mjs b/test/http.test.mjs index b5bfbae..2d3f52d 100644 --- a/test/http.test.mjs +++ b/test/http.test.mjs @@ -145,15 +145,15 @@ t.describe('/json', function() { t.test('should fail if not a valid json', async function() { reset() - let err = await assert.isRejected(client.customRequest('POST', '/json', 'aaaa')) + let err = await assert.isRejected(client.customRequest('POST', '/json', 'XXXXX')) assert.strictEqual(err.body.status, 400) assert.match(err.body.message, /invalid json/i) - assert.match(err.body.message, /token a/i) - assert.strictEqual(err.body.request, 'aaaa') + assert.match(err.body.message, /token[^X]+X/i) + assert.strictEqual(err.body.request, 'XXXXX') assert.strictEqual(log.error.callCount, 1) assert.match(log.error.firstCall[0].message, /invalid json/i) - assert.match(log.error.firstCall[0].message, /token a/i) + assert.match(log.error.firstCall[0].message, /token[^X]+X/i) }) t.test('should handle incomplete requests correctly', async function() { diff --git a/test/middlewares.test.mjs b/test/middlewares.test.mjs index f67e70d..e365aad 100644 --- a/test/middlewares.test.mjs +++ b/test/middlewares.test.mjs @@ -498,8 +498,8 @@ t.describe('#JsonHandler()', function() { finished = true }) - ctx.req.on.firstCall[1](Buffer.alloc(10, 'a')) - ctx.req.on.firstCall[1](Buffer.alloc(10, 'a')) + ctx.req.on.firstCall[1](Buffer.alloc(10, 'X')) + ctx.req.on.firstCall[1](Buffer.alloc(10, 'X')) ctx.req.on.secondCall[1]() await setTimeout(10) @@ -510,11 +510,11 @@ t.describe('#JsonHandler()', function() { assert.ok(err instanceof HttpError) assert.strictEqual(err.status, 400) assert.match(err.message, /JSON/) - assert.match(err.message, /Unexpected token a in/i) + assert.match(err.message, /Unexpected token[^X]+X/i) assert.strictEqual(err.body.status, 400) assert.match(err.body.message, /Invalid JSON/i) - assert.match(err.body.message, /Unexpected token a in/i) - assert.strictEqual(err.body.request, 'aaaaaaaaaaaaaaaaaaaa') + assert.match(err.body.message, /Unexpected token[^X]+X/i) + assert.strictEqual(err.body.request, 'XXXXXXXXXXXXXXXXXXXX') }) t.test('should not throw if body is empty', async function() {