You are on the right track; you just need to attach your listeners to the proper object events. In the first case (as written, not as executed):
res.pipe(process.stdout).on('end', () => process.exit(exitCode));
What you said: "Pipe the data from response to stdout, and when stdout ends, exit the process."
What you meant: "Pipe the data from response to stdout. When response ends, exit the process." Codified:
res.pipe(process.stdout);
res.on('end', () => process.exit(exitCode));
The point of clarity here is that unless you specifically close process.stdout
, it will never close/end until you exit the program. The response
however, will end when the HTTP interaction is complete.
It goes similar for the second case:
process.stdin.pipe(req)
.on('end', () => console.log('this does trigger'));
What you said: "Pipe the data from stdin to request, and when request ends, write a message."
What you meant: "Pipe the data from stdin to request. When stdin ends, write a message." Codified:
process.stdin.pipe(req);
process.stdin.on('end', () => console.log('this does trigger'));
It's slightly more nuanced here because you could listen for either stdin's end
event or the request's finish
event:
process.stdin.pipe(req).on('finish', () => console.log('Request has finished writing/sending');
process.stdin.on('end', () => console.log('Stdin has no more data'));
For completeness then, your working client back to you, with some mild text modifications for assumed pedagogical clarity:
var http = require('http');
var options = {
hostname: 'localhost',
port: 32001,
method: 'POST',
headers: {'Content-Type': 'text/plain'}
};
var req = http.request(options, res => {
var exitCode = res.statusCode >= 200 && res.statusCode < 300 ? 0 : 1;
res.pipe(process.stdout);
res.on('end', () => {
console.log('Response (IncomingMessage) has no more data; exiting with code:', exitCode);
process.exit(exitCode);
});
});
req.on('error', error => console.error(error));
process.stdin.on('end', () => console.log('Stdin has no more data.'));
process.stdin.pipe(req).on('finish', () => console.log('Request has finished writing/sending'));
Which outputs at command line:
$ echo Some text from stdin | node test.js; echo $?
Stdin has no more data.
Request has finished writing/sending
Works
Response (IncomingMessage) has no more data; exiting with code: 0
0
And at "the server":
$ nc -l 32001 <<EOF
HTTP/1.1 200 OK
Content-Type: text/plain
Works
EOF
POST / HTTP/1.1
Content-Type: text/plain
Host: localhost:32001
Connection: close
Transfer-Encoding: chunked
15
Some text from stdin
0