diff --git a/lib/_http_server.js b/lib/_http_server.js index dc7276d0ae..e2221b759b 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 0000000000..05639a2a42 --- /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(); +});