142 lines
18 KiB
JavaScript
142 lines
18 KiB
JavaScript
|
|
"use strict";
|
||
|
|
|
||
|
|
Object.defineProperty(exports, "__esModule", {
|
||
|
|
value: true
|
||
|
|
});
|
||
|
|
exports.connectInParallel = connectInParallel;
|
||
|
|
exports.connectInSequence = connectInSequence;
|
||
|
|
exports.lookupAllAddresses = lookupAllAddresses;
|
||
|
|
var _net = _interopRequireDefault(require("net"));
|
||
|
|
var _nodeUrl = _interopRequireDefault(require("node:url"));
|
||
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
|
async function connectInParallel(options, lookup, signal) {
|
||
|
|
signal.throwIfAborted();
|
||
|
|
const addresses = await lookupAllAddresses(options.host, lookup, signal);
|
||
|
|
return await new Promise((resolve, reject) => {
|
||
|
|
const sockets = new Array(addresses.length);
|
||
|
|
const errors = [];
|
||
|
|
function onError(err) {
|
||
|
|
errors.push(err);
|
||
|
|
this.removeListener('error', onError);
|
||
|
|
this.removeListener('connect', onConnect);
|
||
|
|
this.destroy();
|
||
|
|
if (errors.length === addresses.length) {
|
||
|
|
signal.removeEventListener('abort', onAbort);
|
||
|
|
reject(new AggregateError(errors, 'Could not connect (parallel)'));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function onConnect() {
|
||
|
|
signal.removeEventListener('abort', onAbort);
|
||
|
|
for (let j = 0; j < sockets.length; j++) {
|
||
|
|
const socket = sockets[j];
|
||
|
|
if (this === socket) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
socket.removeListener('error', onError);
|
||
|
|
socket.removeListener('connect', onConnect);
|
||
|
|
socket.destroy();
|
||
|
|
}
|
||
|
|
resolve(this);
|
||
|
|
}
|
||
|
|
const onAbort = () => {
|
||
|
|
for (let j = 0; j < sockets.length; j++) {
|
||
|
|
const socket = sockets[j];
|
||
|
|
socket.removeListener('error', onError);
|
||
|
|
socket.removeListener('connect', onConnect);
|
||
|
|
socket.destroy();
|
||
|
|
}
|
||
|
|
reject(signal.reason);
|
||
|
|
};
|
||
|
|
for (let i = 0, len = addresses.length; i < len; i++) {
|
||
|
|
const socket = sockets[i] = _net.default.connect({
|
||
|
|
...options,
|
||
|
|
host: addresses[i].address,
|
||
|
|
family: addresses[i].family
|
||
|
|
});
|
||
|
|
socket.on('error', onError);
|
||
|
|
socket.on('connect', onConnect);
|
||
|
|
}
|
||
|
|
signal.addEventListener('abort', onAbort, {
|
||
|
|
once: true
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
async function connectInSequence(options, lookup, signal) {
|
||
|
|
signal.throwIfAborted();
|
||
|
|
const errors = [];
|
||
|
|
const addresses = await lookupAllAddresses(options.host, lookup, signal);
|
||
|
|
for (const address of addresses) {
|
||
|
|
try {
|
||
|
|
return await new Promise((resolve, reject) => {
|
||
|
|
const socket = _net.default.connect({
|
||
|
|
...options,
|
||
|
|
host: address.address,
|
||
|
|
family: address.family
|
||
|
|
});
|
||
|
|
const onAbort = () => {
|
||
|
|
socket.removeListener('error', onError);
|
||
|
|
socket.removeListener('connect', onConnect);
|
||
|
|
socket.destroy();
|
||
|
|
reject(signal.reason);
|
||
|
|
};
|
||
|
|
const onError = err => {
|
||
|
|
signal.removeEventListener('abort', onAbort);
|
||
|
|
socket.removeListener('error', onError);
|
||
|
|
socket.removeListener('connect', onConnect);
|
||
|
|
socket.destroy();
|
||
|
|
reject(err);
|
||
|
|
};
|
||
|
|
const onConnect = () => {
|
||
|
|
signal.removeEventListener('abort', onAbort);
|
||
|
|
socket.removeListener('error', onError);
|
||
|
|
socket.removeListener('connect', onConnect);
|
||
|
|
resolve(socket);
|
||
|
|
};
|
||
|
|
signal.addEventListener('abort', onAbort, {
|
||
|
|
once: true
|
||
|
|
});
|
||
|
|
socket.on('error', onError);
|
||
|
|
socket.on('connect', onConnect);
|
||
|
|
});
|
||
|
|
} catch (err) {
|
||
|
|
// If the signal was aborted, re-throw the error.
|
||
|
|
signal.throwIfAborted();
|
||
|
|
errors.push(err);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
throw new AggregateError(errors, 'Could not connect (sequence)');
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Look up all addresses for the given hostname.
|
||
|
|
*/
|
||
|
|
async function lookupAllAddresses(host, lookup, signal) {
|
||
|
|
signal.throwIfAborted();
|
||
|
|
if (_net.default.isIPv6(host)) {
|
||
|
|
return [{
|
||
|
|
address: host,
|
||
|
|
family: 6
|
||
|
|
}];
|
||
|
|
} else if (_net.default.isIPv4(host)) {
|
||
|
|
return [{
|
||
|
|
address: host,
|
||
|
|
family: 4
|
||
|
|
}];
|
||
|
|
} else {
|
||
|
|
return await new Promise((resolve, reject) => {
|
||
|
|
const onAbort = () => {
|
||
|
|
reject(signal.reason);
|
||
|
|
};
|
||
|
|
signal.addEventListener('abort', onAbort);
|
||
|
|
const domainInASCII = _nodeUrl.default.domainToASCII(host);
|
||
|
|
lookup(domainInASCII === '' ? host : domainInASCII, {
|
||
|
|
all: true
|
||
|
|
}, (err, addresses) => {
|
||
|
|
signal.removeEventListener('abort', onAbort);
|
||
|
|
err ? reject(err) : resolve(addresses);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbmV0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfbm9kZVVybCIsIm9iaiIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiY29ubmVjdEluUGFyYWxsZWwiLCJvcHRpb25zIiwibG9va3VwIiwic2lnbmFsIiwidGhyb3dJZkFib3J0ZWQiLCJhZGRyZXNzZXMiLCJsb29rdXBBbGxBZGRyZXNzZXMiLCJob3N0IiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJzb2NrZXRzIiwiQXJyYXkiLCJsZW5ndGgiLCJlcnJvcnMiLCJvbkVycm9yIiwiZXJyIiwicHVzaCIsInJlbW92ZUxpc3RlbmVyIiwib25Db25uZWN0IiwiZGVzdHJveSIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJvbkFib3J0IiwiQWdncmVnYXRlRXJyb3IiLCJqIiwic29ja2V0IiwicmVhc29uIiwiaSIsImxlbiIsIm5ldCIsImNvbm5lY3QiLCJhZGRyZXNzIiwiZmFtaWx5Iiwib24iLCJhZGRFdmVudExpc3RlbmVyIiwib25jZSIsImNvbm5lY3RJblNlcXVlbmNlIiwiaXNJUHY2IiwiaXNJUHY0IiwiZG9tYWluSW5BU0NJSSIsInVybCIsImRvbWFpblRvQVNDSUkiLCJhbGwiXSwic291cmNlcyI6WyIuLi9zcmMvY29ubmVjdG9yLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBuZXQgZnJvbSAnbmV0JztcbmltcG9ydCBkbnMsIHsgdHlwZSBMb29rdXBBZGRyZXNzIH0gZnJvbSAnZG5zJztcblxuaW1wb3J0IHVybCBmcm9tICdub2RlOnVybCc7XG5cbnR5cGUgTG9va3VwRnVuY3Rpb24gPSAoaG9zdG5hbWU6IHN0cmluZywgb3B0aW9uczogZG5zLkxvb2t1cEFsbE9wdGlvbnMsIGNhbGxiYWNrOiAoZXJyOiBOb2RlSlMuRXJybm9FeGNlcHRpb24gfCBudWxsLCBhZGRyZXNzZXM6IGRucy5Mb29rdXBBZGRyZXNzW10pID0+IHZvaWQpID0+IHZvaWQ7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb25uZWN0SW5QYXJhbGxlbChvcHRpb25zOiB7IGhvc3Q6IHN0cmluZywgcG9ydDogbnVtYmVyLCBsb2NhbEFkZHJlc3M/OiBzdHJpbmcgfCB1bmRlZmluZWQgfSwgbG9va3VwOiBMb29rdXBGdW5jdGlvbiwgc2lnbmFsOiBBYm9ydFNpZ25hbCkge1xuICBzaWduYWwudGhyb3dJZkFib3J0ZWQoKTtcblxuICBjb25zdCBhZGRyZXNzZXMgPSBhd2FpdCBsb29rdXBBbGxBZGRyZXNzZXMob3B0aW9ucy5ob3N0LCBsb29rdXAsIHNpZ25hbCk7XG5cbiAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlPG5ldC5Tb2NrZXQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzb2NrZXRzID0gbmV3IEFycmF5KGFkZHJlc3Nlcy5sZW5ndGgpO1xuXG4gICAgY29uc3QgZXJyb3JzOiBFcnJvcltdID0gW107XG5cbiAgICBmdW5jdGlvbiBvbkVycm9yKHRoaXM6IG5ldC5Tb2NrZXQsIGVycjogRXJyb3IpIHtcbiAgICAgIGVycm9ycy5wdXNoKGVycik7XG5cbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25FcnJvcik7XG4gICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdjb25uZWN0Jywgb25Db25uZWN0KTtcblxuICAgICAgdGhpcy5kZXN0cm95KCk7XG5cbiAgICAgIGlmIChlcnJvcnMubGVuZ3RoID09PSBhZGRyZXNzZXMubGVuZ3RoKSB7XG4gICAgICAgIHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQpO1xuXG4gICAgICAgIHJlamVjdChuZXcgQWdncmVnYXRlRXJyb3IoZXJyb3JzLCAnQ291bGQgbm90IGNvbm5lY3QgKHBhcmFsbGVsKScpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvbkNvbm5lY3QodGhpczogbmV0LlNvY2tldCkge1xuICAgICAgc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25BYm9ydCk7XG5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgc29ja2V0cy5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBzb2NrZXQgPSBzb2NrZXRzW2pdO1xuXG4gICAgICAgIGlmICh0aGlzID09PSBzb2NrZXQpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbkVycm9yKTtcbiAgICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdjb25uZWN0Jywgb25Db25uZWN0KTtcbiAgICAgICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZSh0aGlzKTtcbiAgICB9XG5cbiAgICBjb25zdCBvbkFib3J0ID0gKCkgPT4ge1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzb2NrZXRzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGNvbnN0IHNvY2tldCA9IHNvY2tldHNbal07XG5cbiAgICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2Nvbm5lY3QnLCBvbkNvbm5lY3QpO1xuXG4gICAgICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgICB9XG5cbiAgICAgIHJlamVjdChzaWduYWwucmVhc29uKTtcbiAgICB9O1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGFkZHJlc3Nlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgY29uc3Qgc29ja2V0ID0gc29ja2V0c1tpXSA9IG5ldC5jb25uZWN0KHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgaG9zdDogYWRkcmVzc2VzW2ldLmFkZHJlc3MsXG4gICAgICAgIGZhbWlseTogYWRkcmVzc2VzW2ldLmZhbWlseVxuICAgICAgfSk7XG5cbiAgICAgIHNvY2tldC5vbignZXJyb3InLCBvbkVycm9yKTtcbiAgICAgIHNvY2tldC5vbignY29ubmVjdCcsIG9uQ29ubmVjdCk7XG4gICAgfVxuXG4gICAgc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25BYm9ydCwgeyBvbmNlOiB0cnVlIH0pO1xuICB9KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbm5lY3RJblNlcXVlbmNlKG9wdGlvbnM6IHsgaG9zdDogc3RyaW5nLCBwb3J0OiBudW1iZXIsIGxvY2FsQWRkcmVzcz86IHN0cmluZyB8IHVuZGVmaW5lZCB9LCBsb29rdXA6IExvb2t1cEZ1bmN0aW9uLCBzaWduYWw6IEFib3J0U2lnbmFsKSB7XG4gIHNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuXG4
|