diff --git a/src/stream_base.cc b/src/stream_base.cc index 389aab28c5adff..31cbf8fa199f7f 100644 --- a/src/stream_base.cc +++ b/src/stream_base.cc @@ -583,9 +583,10 @@ void CustomBufferJSListener::OnStreamRead(ssize_t nread, const uv_buf_t& buf) { HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); - // To deal with the case where POLLHUP is received and UV_EOF is returned, as - // libuv returns an empty buffer (on unices only). - if (nread == UV_EOF && buf.base == nullptr) { + // In the case that there's an error and buf is null, return immediately. + // This can happen on unices when POLLHUP is received and UV_EOF is returned + // or when getting an error while performing a UV_HANDLE_ZERO_READ on Windows. + if (buf.base == nullptr && nread < 0) { stream->CallJSOnreadMethod(nread, Local()); return; } diff --git a/test/parallel/test-net-child-process-connect-reset.js b/test/parallel/test-net-child-process-connect-reset.js new file mode 100644 index 00000000000000..228ba8ed57fccc --- /dev/null +++ b/test/parallel/test-net-child-process-connect-reset.js @@ -0,0 +1,47 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { spawn } = require('child_process'); +const net = require('net'); + +if (process.argv[2] === 'child') { + const server = net.createServer(common.mustCall()); + server.listen(0, common.mustCall(() => { + process.send({ type: 'ready', data: { port: server.address().port } }); + })); +} else { + const cp = spawn(process.execPath, + [__filename, 'child'], + { + stdio: ['ipc', 'inherit', 'inherit'] + }); + + cp.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, null); + assert.strictEqual(signal, 'SIGKILL'); + })); + + cp.on('message', common.mustCall((msg) => { + const { type, data } = msg; + assert.strictEqual(type, 'ready'); + const port = data.port; + + const conn = net.createConnection({ + port, + onread: { + buffer: Buffer.alloc(65536), + callback: () => {}, + } + }); + + conn.on('error', (err) => { + // Error emitted on Windows. + assert.strictEqual(err.code, 'ECONNRESET'); + }); + + conn.on('connect', common.mustCall(() => { + cp.kill('SIGKILL'); + })); + })); +}