Outlook_Addin_LLM/node_modules/office-addin-debugging/lib/port.js

154 lines
6.0 KiB
JavaScript
Raw Permalink Normal View History

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.randomPortNotInUse = exports.getProcessIdsForPort = exports.isPortInUse = void 0;
const childProcess = require("child_process");
const crypto = require("crypto");
const net = require("net");
const office_addin_usage_data_1 = require("office-addin-usage-data");
/* global process */
/**
* Determines whether a port is in use.
* @param port port number (0 - 65535)
* @returns true if port is in use; false otherwise.
*/
function isPortInUse(port) {
validatePort(port);
return new Promise((resolve) => {
const server = net
.createServer()
.once("error", () => {
resolve(true);
})
.once("listening", () => {
server.close();
resolve(false);
})
.listen(port);
});
}
exports.isPortInUse = isPortInUse;
/**
* Parse the port from a string which ends with colon and a number.
* @param text string to parse
* @example "127.0.0.1:3000" returns 3000
* @example "[::1]:1900" returns 1900
* @example "Local Address" returns undefined
*/
function parsePort(text) {
const result = text.match(/:(\d+)$/);
return result ? parseInt(result[1], 10) : undefined;
}
/**
* Return the process ids using the port.
* @param port port number (0 - 65535)
* @returns Promise to array containing process ids, or empty if none.
*/
function getProcessIdsForPort(port) {
validatePort(port);
return new Promise((resolve, reject) => {
const isWin32 = process.platform === "win32";
const isLinux = process.platform === "linux";
const command = isWin32
? `netstat -ano | findstr :${port}`
: isLinux
? `netstat -tlpna | grep :${port}`
: `lsof -n -i:${port}`;
childProcess.exec(command, (error, stdout) => {
if (error) {
if (error.code === 1) {
// no processes are using the port
resolve([]);
}
else {
reject(error);
}
}
else {
const processIds = new Set();
const lines = stdout.trim().split("\n");
if (isWin32) {
lines.forEach((line) => {
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
const [protocol, localAddress, foreignAddress, status, processId] = line.trim().split(" ").filter((text) => text);
if (processId !== undefined && processId.trim() !== '0') {
const localAddressPort = parsePort(localAddress);
if (localAddressPort === port) {
processIds.add(parseInt(processId, 10));
}
}
});
}
else if (isLinux) {
lines.forEach((line) => {
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
const [proto, recv, send, local_address, remote_address, state, program] = line
.trim()
.split(" ")
.filter((text) => text);
if (local_address !== undefined && local_address.endsWith(`:${port}`) && program !== undefined) {
const pid = parseInt(program, 10);
if (!isNaN(pid)) {
processIds.add(pid);
}
}
});
}
else {
lines.forEach((line) => {
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
const [process, processId, user, fd, type, device, size, node, name] = line
.trim()
.split(" ")
.filter((text) => text);
if (processId !== undefined && processId !== "PID") {
processIds.add(parseInt(processId, 10));
}
});
}
resolve(Array.from(processIds));
}
});
});
}
exports.getProcessIdsForPort = getProcessIdsForPort;
/**
* Returns a random port number which is not in use.
* @returns Promise to number from 0 to 65535
*/
function randomPortNotInUse() {
return __awaiter(this, void 0, void 0, function* () {
let port;
do {
port = randomPortNumber();
} while (yield isPortInUse(port));
return port;
});
}
exports.randomPortNotInUse = randomPortNotInUse;
/**
* Returns a random number between 0 and 65535
*/
function randomPortNumber() {
return crypto.randomBytes(2).readUInt16LE(0);
}
/**
* Throw an error if the port is not a valid number.
* @param port port number
* @throws Error if port is not a number from 0 to 65535.
*/
function validatePort(port) {
if (typeof port !== "number" || port < 0 || port > 65535) {
throw new office_addin_usage_data_1.ExpectedError("Port should be a number from 0 to 65535.");
}
}
//# sourceMappingURL=port.js.map