How to pipe unbuffered data from STDOUT to ServerResponse?

node.js

Solution

This is a common problem that isn't necessarily limited to Node.js.

If you're on Unix, you could use the `unbuffer` script, which is part of Expect. Most GNU systems also provide `stdbuf`, which lets you do the same thing (although I'm admittedly not very familiar with it).

If you want to use `unbuffer`, you just need to change your above example to:

var ping = spawn("unbuffer", ["ping", "127.0.0.1"]);

If you're on Windows, things are quite a bit more difficult, as Windows does not natively provide any sort of equivalent to a `PTY`. Projects such as winpty (and its JavaScript binding, pty.js) attempt to re-create this functionality using the Windows Console API, although I've found their implementation to be somewhat buggy and incomplete.

ActiveState's win32 Expect package isn't the easiest thing to install, and doesn't include the `unbuffer` script in the default distribution. However, if you manage to get everything working and make a few small modifications to the Unix `unbuffer` script, you should be able to compile an `unbuffer` executable, which you can then call from Node.

Problem

How can I pipe the unbuffered output from the child process to HTTP.ServerResponse? The Node.js code below does work for buffered output, but not for unbuffered output. ``` var http = require('http'), spawn = require('child_process').spawn; http.createServer(function (req, res) { req.on('data', function (data) { var ping = spawn("ping", ["127.0.0.1"]); ping.stdout.pipe(res); ping.stderr.pipe(res); req.connection.on('end', function() { ping.kill(); }); }); }); ``` Here is the output from `ping 127.0.0.1`: ``` ping 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes Request timeout for icmp_seq 0 Request timeout for icmp_seq 1 ``` Since `ping` writes request timeouts to STDOUT as unbuffered data, the code above only works if `ping` is successful. I'm using Node.js v0.8.19.

Original source