107 lines
4.1 KiB
JavaScript
107 lines
4.1 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.getDesiredPort = exports.testPortAvailableOnMultipleHosts = void 0;
|
|
const net_1 = __importDefault(require("net"));
|
|
const locks_1 = require("./locks");
|
|
const isPortAvailableOnHost = ({ portToTry, host, }) => {
|
|
return new Promise((resolve) => {
|
|
let status = 'unavailable';
|
|
const socket = new net_1.default.Socket();
|
|
socket.on('connect', () => {
|
|
status = 'unavailable';
|
|
socket.destroy();
|
|
});
|
|
socket.setTimeout(3000);
|
|
socket.on('timeout', () => {
|
|
status = 'unavailable';
|
|
socket.destroy();
|
|
resolve(status);
|
|
});
|
|
socket.on('error', () => {
|
|
status = 'available';
|
|
});
|
|
socket.on('close', () => resolve(status));
|
|
socket.connect(portToTry, host);
|
|
});
|
|
};
|
|
const testPortAvailableOnMultipleHosts = async ({ hosts, port, }) => {
|
|
const results = await Promise.all(hosts.map((host) => {
|
|
return isPortAvailableOnHost({ portToTry: port, host });
|
|
}));
|
|
return results.every((r) => r === 'available') ? 'available' : 'unavailable';
|
|
};
|
|
exports.testPortAvailableOnMultipleHosts = testPortAvailableOnMultipleHosts;
|
|
const getPort = async ({ from, to, hostsToTest, onPortUnavailable, }) => {
|
|
const ports = makeRange(from, to);
|
|
for (const port of ports) {
|
|
if ((await (0, exports.testPortAvailableOnMultipleHosts)({
|
|
port,
|
|
hosts: hostsToTest,
|
|
})) === 'available') {
|
|
return { port, didUsePort: false };
|
|
}
|
|
if (onPortUnavailable) {
|
|
const action = await onPortUnavailable(port);
|
|
if (action === 'stop') {
|
|
return { port, didUsePort: true };
|
|
}
|
|
}
|
|
}
|
|
throw new Error('No available ports found');
|
|
};
|
|
const portLocks = (0, locks_1.createLock)({ timeout: 10000 });
|
|
const getDesiredPort = async ({ desiredPort, from, hostsToTry, to, onPortUnavailable, }) => {
|
|
await portLocks.waitForAllToBeDone();
|
|
const lockPortSelection = portLocks.lock();
|
|
const unlockPort = () => portLocks.unlock(lockPortSelection);
|
|
if (typeof desiredPort !== 'undefined' &&
|
|
(await (0, exports.testPortAvailableOnMultipleHosts)({
|
|
port: desiredPort,
|
|
hosts: hostsToTry,
|
|
})) === 'available') {
|
|
return { port: desiredPort, unlockPort, didUsePort: false };
|
|
}
|
|
if (typeof desiredPort !== 'undefined' && onPortUnavailable) {
|
|
const action = await onPortUnavailable(desiredPort);
|
|
if (action === 'stop') {
|
|
return { port: desiredPort, unlockPort, didUsePort: true };
|
|
}
|
|
}
|
|
const result = await getPort({
|
|
from,
|
|
to,
|
|
hostsToTest: hostsToTry,
|
|
onPortUnavailable,
|
|
});
|
|
if (result.didUsePort) {
|
|
return { port: result.port, unlockPort, didUsePort: true };
|
|
}
|
|
// If did specify a port but did not get that one, fail hard.
|
|
if (desiredPort && desiredPort !== result.port) {
|
|
unlockPort();
|
|
throw new Error(`You specified port ${desiredPort} to be used for the HTTP server, but it is not available. Choose a different port or remove the setting to let Remotion automatically select a free port.`);
|
|
}
|
|
return { port: result.port, unlockPort, didUsePort: false };
|
|
};
|
|
exports.getDesiredPort = getDesiredPort;
|
|
const makeRange = (from, to) => {
|
|
if (!Number.isInteger(from) || !Number.isInteger(to)) {
|
|
throw new TypeError('`from` and `to` must be integer numbers');
|
|
}
|
|
if (from < 1024 || from > 65535) {
|
|
throw new RangeError('`from` must be between 1024 and 65535');
|
|
}
|
|
if (to < 1024 || to > 65536) {
|
|
throw new RangeError('`to` must be between 1024 and 65536');
|
|
}
|
|
if (to < from) {
|
|
throw new RangeError('`to` must be greater than or equal to `from`');
|
|
}
|
|
return new Array(to - from + 1).fill(true).map((_, i) => {
|
|
return i + from;
|
|
});
|
|
};
|