mirror of https://github.com/nodejs/node.git
cluster: resolve relative unix socket paths
Relative unix sockets paths were previously interpreted relative to the master's CWD, which was inconsistent with non-cluster behavior. A test case has been added as well. PR-URL: https://github.com/nodejs/node/pull/16749 Fixes: https://github.com/nodejs/node/issues/16387 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>pull/18103/merge
parent
f878f9414e
commit
4e2e7d11e1
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
const assert = require('assert');
|
||||
const util = require('util');
|
||||
const path = require('path');
|
||||
const EventEmitter = require('events');
|
||||
const Worker = require('internal/cluster/worker');
|
||||
const { internal, sendHelper } = require('internal/cluster/utils');
|
||||
|
@ -48,7 +49,14 @@ cluster._setupWorker = function() {
|
|||
|
||||
// obj is a net#Server or a dgram#Socket object.
|
||||
cluster._getServer = function(obj, options, cb) {
|
||||
const indexesKey = [options.address,
|
||||
let address = options.address;
|
||||
|
||||
// Resolve unix socket paths to absolute paths
|
||||
if (options.port < 0 && typeof address === 'string' &&
|
||||
process.platform !== 'win32')
|
||||
address = path.resolve(address);
|
||||
|
||||
const indexesKey = [address,
|
||||
options.port,
|
||||
options.addressType,
|
||||
options.fd ].join(':');
|
||||
|
@ -64,6 +72,8 @@ cluster._getServer = function(obj, options, cb) {
|
|||
data: null
|
||||
}, options);
|
||||
|
||||
message.address = address;
|
||||
|
||||
// Set custom data on handle (i.e. tls tickets key)
|
||||
if (obj._getServerData)
|
||||
message.data = obj._getServerData();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
const assert = require('assert');
|
||||
const { fork } = require('child_process');
|
||||
const util = require('util');
|
||||
const path = require('path');
|
||||
const EventEmitter = require('events');
|
||||
const RoundRobinHandle = require('internal/cluster/round_robin_handle');
|
||||
const SharedHandle = require('internal/cluster/shared_handle');
|
||||
|
@ -276,6 +277,18 @@ function queryServer(worker, message) {
|
|||
var handle = handles[key];
|
||||
|
||||
if (handle === undefined) {
|
||||
let address = message.address;
|
||||
|
||||
// Find shortest path for unix sockets because of the ~100 byte limit
|
||||
if (message.port < 0 && typeof address === 'string' &&
|
||||
process.platform !== 'win32') {
|
||||
|
||||
address = path.relative(process.cwd(), address);
|
||||
|
||||
if (message.address.length < address.length)
|
||||
address = message.address;
|
||||
}
|
||||
|
||||
var constructor = RoundRobinHandle;
|
||||
// UDP is exempt from round-robin connection balancing for what should
|
||||
// be obvious reasons: it's connectionless. There is nothing to send to
|
||||
|
@ -287,7 +300,7 @@ function queryServer(worker, message) {
|
|||
}
|
||||
|
||||
handles[key] = handle = new constructor(key,
|
||||
message.address,
|
||||
address,
|
||||
message.port,
|
||||
message.addressType,
|
||||
message.fd,
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
const net = require('net');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
if (common.isWindows)
|
||||
common.skip('On Windows named pipes live in their own ' +
|
||||
'filesystem and don\'t have a ~100 byte limit');
|
||||
|
||||
// Choose a socket name such that the absolute path would exceed 100 bytes.
|
||||
const socketDir = './unix-socket-dir';
|
||||
const socketName = 'A'.repeat(100 - socketDir.length - 1);
|
||||
|
||||
// Make sure we're not in a weird environment
|
||||
assert.strictEqual(path.resolve(socketDir, socketName).length > 100, true,
|
||||
'absolute socket path should be longer than 100 bytes');
|
||||
|
||||
if (cluster.isMaster) {
|
||||
// ensure that the worker exits peacefully
|
||||
process.chdir(common.tmpDir);
|
||||
fs.mkdirSync(socketDir);
|
||||
cluster.fork().on('exit', common.mustCall(function(statusCode) {
|
||||
assert.strictEqual(statusCode, 0);
|
||||
|
||||
assert.strictEqual(
|
||||
fs.existsSync(path.join(socketDir, socketName)), false,
|
||||
'Socket should be removed when the worker exits');
|
||||
}));
|
||||
} else {
|
||||
process.chdir(socketDir);
|
||||
|
||||
const server = net.createServer(common.mustNotCall());
|
||||
|
||||
server.listen(socketName, common.mustCall(function() {
|
||||
assert.strictEqual(
|
||||
fs.existsSync(socketName), true,
|
||||
'Socket created in CWD');
|
||||
|
||||
process.disconnect();
|
||||
}));
|
||||
}
|
Loading…
Reference in New Issue