From 93436ab2db8a32cdd320bc3e7e9f55d4aadf9139 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 11 Sep 2015 14:04:26 -0700 Subject: [PATCH 1/3] http_server: fix resume after socket close Socket resume may happen on a next tick, and in following scenario: 1. `socket.resume()` 2. `socket._handle.close()` 3. `socket._handle = null;` The `_resume` will be invoked with empty `._handle` property. There is nothing bad about it, and we should just ignore the `resume`/`pause` events in this case. Same applies to the unconsuming of socket on adding `data` and/or `readable` event listeners. Fix: https://github.com/nodejs/node/issues/2821 --- lib/_http_server.js | 8 +++++--- test/parallel/test-http-regr-gh-2821.js | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 test/parallel/test-http-regr-gh-2821.js diff --git a/lib/_http_server.js b/lib/_http_server.js index 16460fca35705d..7acc1086387880 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -512,11 +512,13 @@ function connectionListener(socket) { exports._connectionListener = connectionListener; function onSocketResume() { - this._handle.readStart(); + if (this._handle) + this._handle.readStart(); } function onSocketPause() { - this._handle.readStop(); + if (this._handle) + this._handle.readStop(); } function socketOnWrap(ev, fn) { @@ -526,7 +528,7 @@ function socketOnWrap(ev, fn) { return res; } - if (ev === 'data' || ev === 'readable') + if (this._handle && (ev === 'data' || ev === 'readable')) this.parser.unconsume(this._handle._externalStream); return res; diff --git a/test/parallel/test-http-regr-gh-2821.js b/test/parallel/test-http-regr-gh-2821.js new file mode 100644 index 00000000000000..3c1cc857d9c688 --- /dev/null +++ b/test/parallel/test-http-regr-gh-2821.js @@ -0,0 +1,23 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer(function(req, res) { + res.writeHead(200); + res.end(); + + server.close(); +}); + +server.listen(common.PORT, function() { + + const req = http.request({ + method: 'POST', + port: common.PORT + }); + + const payload = new Array(1640).join('0123456789'); + req.write(payload); + req.end(); +}); From 214ed2e07dd89496a432368887b8eeaaf2fe3d13 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 11 Sep 2015 14:13:36 -0700 Subject: [PATCH 2/3] ... --- test/parallel/test-http-regr-gh-2821.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-http-regr-gh-2821.js b/test/parallel/test-http-regr-gh-2821.js index 3c1cc857d9c688..d4e58f85ecdf58 100644 --- a/test/parallel/test-http-regr-gh-2821.js +++ b/test/parallel/test-http-regr-gh-2821.js @@ -17,7 +17,7 @@ server.listen(common.PORT, function() { port: common.PORT }); - const payload = new Array(1640).join('0123456789'); + const payload = new Buffer(16390); req.write(payload); req.end(); }); From 5fe0449408780f08bba4d4ec6708c162d63e4268 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 11 Sep 2015 14:21:02 -0700 Subject: [PATCH 3/3] ... --- test/parallel/test-http-regr-gh-2821.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/parallel/test-http-regr-gh-2821.js b/test/parallel/test-http-regr-gh-2821.js index d4e58f85ecdf58..4fdef2369bb168 100644 --- a/test/parallel/test-http-regr-gh-2821.js +++ b/test/parallel/test-http-regr-gh-2821.js @@ -18,6 +18,7 @@ server.listen(common.PORT, function() { }); const payload = new Buffer(16390); + payload.fill('Й'); req.write(payload); req.end(); });