diff --git a/index.js b/index.js index b51bebc..5534c3b 100644 --- a/index.js +++ b/index.js @@ -250,45 +250,44 @@ function createFastCGIHandler(options) { } }); - var stdoutPushEvent = new EventEmitter(); - function stdoutPush(data) { if(data === null) { stdoutToEnd = true; } else { stdoutBuffer = Buffer.concat([stdoutBuffer, Buffer.from(data)]); } - stdoutPushEvent.emit("ready"); + var hpLength = hp.length; + for(var i = 0; i < hpLength; i++) { + var func = hp.shift(); + if(func) func(); + } emulatedStdout.resume(); } - function stdoutRead(n, callback) { - if(stdoutBuffer.length == 0 && stdoutToEnd) { - callback(Buffer.alloc(0)); - } else if(n != 0) { - var handler = function() { - if(n > stdoutBuffer.length && !stdoutToEnd) { - stdoutPushEvent.once("ready", handler); - fs.writeFileSync("/tmp/fai", ""); + var zeroed = false; + var stdoutBuffer = Buffer.alloc(0); + var stdoutToEnd = false; + var hp = []; + var emulatedStdout = new stream.Readable({ + read: function (n) { + var s = this; + var handler = function () { + if (stdoutBuffer.length == 0) { + if (!stdoutToEnd) { + hp.push(handler); + s.pause(); + } else { + s.push(null); + } } else { var bytesToPush = Math.min(stdoutBuffer.length, n); var bufferToPush = stdoutBuffer.subarray(0, bytesToPush); stdoutBuffer = stdoutBuffer.subarray(bytesToPush); - callback(bufferToPush); + s.push(bufferToPush); + if (stdoutBuffer.length == 0 && !stdoutToEnd) s.pause(); } }; - handler(); - } - } - - var stdoutBuffer = Buffer.alloc(0); - var stdoutToEnd = false; - var emulatedStdout = new stream.Readable({ - read: function (n) { - var s = this; - stdoutRead(n, function(buffer) { - s.push(buffer.length > 0 ? buffer : null); - }); + if (n != 0) handler(); } }); emulatedStdout.pause(); //Reduce backpressure @@ -480,6 +479,7 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e handler.stdout.pipe(res, { end: false }); + dataHandler = function () {}; //Prevent event listener memory leaks } } }; @@ -512,10 +512,12 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e } }); - res.on("close", function() { + res.prependListener("close", function() { if(handler.stdout) handler.stdout.unpipe(res); //Prevent server crashes with write after the end }); + res.on("error", function() {}); //Suppress response stream errors + function handlerConnection() { handler.stdout.on("data", dataHandler); handler.stderr.on("data", function (data) {