From 1b3b435e177fb67b91cfa543cef44ad7bfd5a6b2 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Tue, 19 Apr 2016 16:41:13 -0400 Subject: [PATCH] http: unref socket timer on parser execute When underlying `net.Socket` instance is consumed in http server - no `data` events are emitted, and thus `socket.setTimeout` fires the callback even if the data is constantly flowing into the socket. Fix this by calling `socket._unrefTimer()` on every `onParserExecute` call. Fix: #5899 PR-URL: https://github.com/nodejs/node/pull/6286 Reviewed-By: James M Snell --- lib/_http_server.js | 1 + .../test-http-server-consumed-timeout.js | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 test/parallel/test-http-server-consumed-timeout.js diff --git a/lib/_http_server.js b/lib/_http_server.js index dc72d76efccc1e..63ac615e6ebf8c 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -364,6 +364,7 @@ function connectionListener(socket) { } function onParserExecute(ret, d) { + socket._unrefTimer(); debug('SERVER socketOnParserExecute %d', ret); onParserExecuteCommon(ret, undefined); } diff --git a/test/parallel/test-http-server-consumed-timeout.js b/test/parallel/test-http-server-consumed-timeout.js new file mode 100644 index 00000000000000..26110b32e7fba4 --- /dev/null +++ b/test/parallel/test-http-server-consumed-timeout.js @@ -0,0 +1,36 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer((req, res) => { + server.close(); + + res.writeHead(200); + res.flushHeaders(); + + req.setTimeout(common.platformTimeout(200), () => { + assert(false, 'Should not happen'); + }); + req.resume(); + req.once('end', common.mustCall(() => { + res.end(); + })); +}); + +server.listen(common.PORT, common.mustCall(() => { + const req = http.request({ + port: common.PORT, + method: 'POST' + }, (res) => { + const interval = setInterval(() => { + req.write('a'); + }, common.platformTimeout(25)); + setTimeout(() => { + clearInterval(interval); + req.end(); + }, common.platformTimeout(400)); + }); + req.write('.'); +}));