diff --git a/lib/_http_server.js b/lib/_http_server.js index 357400e3501..6d5dbf4584a 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -294,6 +294,11 @@ function connectionListener(socket) { httpSocketSetup(socket); + // Ensure that the server property of the socket is correctly set. + // See https://github.com/nodejs/node/issues/13435 + if (socket.server === null) + socket.server = this; + // If the user has added a listener to the server, // request, or response, then it's their responsibility. // otherwise, destroy on timeout by default diff --git a/test/parallel/test-cluster-send-socket-to-worker-http-server.js b/test/parallel/test-cluster-send-socket-to-worker-http-server.js new file mode 100644 index 00000000000..805603d2c9b --- /dev/null +++ b/test/parallel/test-cluster-send-socket-to-worker-http-server.js @@ -0,0 +1,39 @@ +'use strict'; + +// Regression test for https://github.com/nodejs/node/issues/13435 +// Tests that `socket.server` is correctly set when a socket is sent to a worker +// and the `'connection'` event is emitted manually on an HTTP server. + +const common = require('../common'); +const assert = require('assert'); +const cluster = require('cluster'); +const http = require('http'); +const net = require('net'); + +if (cluster.isMaster) { + const worker = cluster.fork(); + const server = net.createServer(common.mustCall((socket) => { + worker.send('socket', socket); + })); + + worker.on('exit', common.mustCall((code) => { + assert.strictEqual(code, 0); + server.close(); + })); + + server.listen(0, common.mustCall(() => { + net.createConnection(server.address().port); + })); +} else { + const server = http.createServer(); + + server.on('connection', common.mustCall((socket) => { + assert.strictEqual(socket.server, server); + socket.destroy(); + cluster.worker.disconnect(); + })); + + process.on('message', common.mustCall((message, socket) => { + server.emit('connection', socket); + })); +}