From d8b14048fbf45038d907df5b217c3d358ee9d64e Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 29 Oct 2015 14:17:37 -0400 Subject: [PATCH] http: fix pipeline regression Always check that socket still has the parser. It may be destroyed interim, and we may end up with an uncaught exception. Fix: https://github.com/nodejs/node/issues/3508 PR-URL: https://github.com/nodejs/node-private/pull/5 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- lib/_http_server.js | 5 +- test/parallel/test-http-pipeline-regr-3508.js | 57 +++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-http-pipeline-regr-3508.js diff --git a/lib/_http_server.js b/lib/_http_server.js index dc7276d0ae729d..e2221b759bd0c4 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -404,7 +404,7 @@ function connectionListener(socket) { } } - if (socket._paused) { + if (socket._paused && socket.parser) { // onIncoming paused the socket, we should pause the parser as well debug('pause parser'); socket.parser.pause(); @@ -445,7 +445,8 @@ function connectionListener(socket) { // If we previously paused, then start reading again. if (socket._paused && !needPause) { socket._paused = false; - socket.parser.resume(); + if (socket.parser) + socket.parser.resume(); socket.resume(); } } diff --git a/test/parallel/test-http-pipeline-regr-3508.js b/test/parallel/test-http-pipeline-regr-3508.js new file mode 100644 index 00000000000000..05639a2a42c5a7 --- /dev/null +++ b/test/parallel/test-http-pipeline-regr-3508.js @@ -0,0 +1,57 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const net = require('net'); + +var once = false; +var first = null; +var second = null; + +const chunk = new Buffer(1024); +chunk.fill('X'); + +var size = 0; + +var more; +var done; + +var server = http.createServer(function(req, res) { + if (!once) + server.close(); + once = true; + + if (first === null) { + first = res; + return; + } + if (second === null) { + second = res; + res.write(chunk); + } else { + res.end(chunk); + } + size += res.outputSize; + if (size <= req.socket._writableState.highWaterMark) { + more(); + return; + } + done(); +}).on('upgrade', function(req, socket) { + second.end(chunk, function() { + socket.end(); + }); + first.end('hello'); +}).listen(common.PORT, function() { + var s = net.connect(common.PORT); + more = function() { + s.write('GET / HTTP/1.1\r\n\r\n'); + }; + done = function() { + s.write('GET / HTTP/1.1\r\n\r\n' + + 'GET / HTTP/1.1\r\nConnection: upgrade\r\nUpgrade: ws\r\n\r\naaa'); + }; + more(); + more(); + s.resume(); +});