Files
PayDirt/node_modules/tedious/lib/instance-lookup.js
RochesterX 6e820464d5 Initial
2025-11-12 10:13:24 -05:00

91 lines
13 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.instanceLookup = instanceLookup;
exports.parseBrowserResponse = parseBrowserResponse;
var _dns = _interopRequireDefault(require("dns"));
var _sender = require("./sender");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const SQL_SERVER_BROWSER_PORT = 1434;
const TIMEOUT = 2 * 1000;
const RETRIES = 3;
// There are three bytes at the start of the response, whose purpose is unknown.
const MYSTERY_HEADER_LENGTH = 3;
// Most of the functionality has been determined from from jTDS's MSSqlServerInfo class.
async function instanceLookup(options) {
const server = options.server;
if (typeof server !== 'string') {
throw new TypeError('Invalid arguments: "server" must be a string');
}
const instanceName = options.instanceName;
if (typeof instanceName !== 'string') {
throw new TypeError('Invalid arguments: "instanceName" must be a string');
}
const timeout = options.timeout === undefined ? TIMEOUT : options.timeout;
if (typeof timeout !== 'number') {
throw new TypeError('Invalid arguments: "timeout" must be a number');
}
const retries = options.retries === undefined ? RETRIES : options.retries;
if (typeof retries !== 'number') {
throw new TypeError('Invalid arguments: "retries" must be a number');
}
if (options.lookup !== undefined && typeof options.lookup !== 'function') {
throw new TypeError('Invalid arguments: "lookup" must be a function');
}
const lookup = options.lookup ?? _dns.default.lookup;
if (options.port !== undefined && typeof options.port !== 'number') {
throw new TypeError('Invalid arguments: "port" must be a number');
}
const port = options.port ?? SQL_SERVER_BROWSER_PORT;
const signal = options.signal;
signal.throwIfAborted();
let response;
const request = Buffer.from([0x02]);
for (let i = 0; i <= retries; i++) {
const timeoutSignal = AbortSignal.timeout(timeout);
try {
response = await (0, _sender.sendMessage)(options.server, port, lookup, AbortSignal.any([signal, timeoutSignal]), request);
} catch (err) {
// If the current attempt timed out, continue with the next
if (timeoutSignal.aborted) {
continue;
}
throw err;
}
}
if (!response) {
throw new Error('Failed to get response from SQL Server Browser on ' + server);
}
const message = response.toString('ascii', MYSTERY_HEADER_LENGTH);
const foundPort = parseBrowserResponse(message, instanceName);
if (!foundPort) {
throw new Error('Port for ' + instanceName + ' not found in ' + options.server);
}
return foundPort;
}
function parseBrowserResponse(response, instanceName) {
let getPort;
const instances = response.split(';;');
for (let i = 0, len = instances.length; i < len; i++) {
const instance = instances[i];
const parts = instance.split(';');
for (let p = 0, partsLen = parts.length; p < partsLen; p += 2) {
const name = parts[p];
const value = parts[p + 1];
if (name === 'tcp' && getPort) {
const port = parseInt(value, 10);
return port;
}
if (name === 'InstanceName') {
if (value.toUpperCase() === instanceName.toUpperCase()) {
getPort = true;
} else {
getPort = false;
}
}
}
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZG5zIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfc2VuZGVyIiwib2JqIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJTUUxfU0VSVkVSX0JST1dTRVJfUE9SVCIsIlRJTUVPVVQiLCJSRVRSSUVTIiwiTVlTVEVSWV9IRUFERVJfTEVOR1RIIiwiaW5zdGFuY2VMb29rdXAiLCJvcHRpb25zIiwic2VydmVyIiwiVHlwZUVycm9yIiwiaW5zdGFuY2VOYW1lIiwidGltZW91dCIsInVuZGVmaW5lZCIsInJldHJpZXMiLCJsb29rdXAiLCJkbnMiLCJwb3J0Iiwic2lnbmFsIiwidGhyb3dJZkFib3J0ZWQiLCJyZXNwb25zZSIsInJlcXVlc3QiLCJCdWZmZXIiLCJmcm9tIiwiaSIsInRpbWVvdXRTaWduYWwiLCJBYm9ydFNpZ25hbCIsInNlbmRNZXNzYWdlIiwiYW55IiwiZXJyIiwiYWJvcnRlZCIsIkVycm9yIiwibWVzc2FnZSIsInRvU3RyaW5nIiwiZm91bmRQb3J0IiwicGFyc2VCcm93c2VyUmVzcG9uc2UiLCJnZXRQb3J0IiwiaW5zdGFuY2VzIiwic3BsaXQiLCJsZW4iLCJsZW5ndGgiLCJpbnN0YW5jZSIsInBhcnRzIiwicCIsInBhcnRzTGVuIiwibmFtZSIsInZhbHVlIiwicGFyc2VJbnQiLCJ0b1VwcGVyQ2FzZSJdLCJzb3VyY2VzIjpbIi4uL3NyYy9pbnN0YW5jZS1sb29rdXAudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGRucyBmcm9tICdkbnMnO1xuXG5pbXBvcnQgeyBzZW5kTWVzc2FnZSB9IGZyb20gJy4vc2VuZGVyJztcblxuY29uc3QgU1FMX1NFUlZFUl9CUk9XU0VSX1BPUlQgPSAxNDM0O1xuY29uc3QgVElNRU9VVCA9IDIgKiAxMDAwO1xuY29uc3QgUkVUUklFUyA9IDM7XG4vLyBUaGVyZSBhcmUgdGhyZWUgYnl0ZXMgYXQgdGhlIHN0YXJ0IG9mIHRoZSByZXNwb25zZSwgd2hvc2UgcHVycG9zZSBpcyB1bmtub3duLlxuY29uc3QgTVlTVEVSWV9IRUFERVJfTEVOR1RIID0gMztcblxudHlwZSBMb29rdXBGdW5jdGlvbiA9IChob3N0bmFtZTogc3RyaW5nLCBvcHRpb25zOiBkbnMuTG9va3VwQWxsT3B0aW9ucywgY2FsbGJhY2s6IChlcnI6IE5vZGVKUy5FcnJub0V4Y2VwdGlvbiB8IG51bGwsIGFkZHJlc3NlczogZG5zLkxvb2t1cEFkZHJlc3NbXSkgPT4gdm9pZCkgPT4gdm9pZDtcblxuLy8gTW9zdCBvZiB0aGUgZnVuY3Rpb25hbGl0eSBoYXMgYmVlbiBkZXRlcm1pbmVkIGZyb20gZnJvbSBqVERTJ3MgTVNTcWxTZXJ2ZXJJbmZvIGNsYXNzLlxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluc3RhbmNlTG9va3VwKG9wdGlvbnM6IHsgc2VydmVyOiBzdHJpbmcsIGluc3RhbmNlTmFtZTogc3RyaW5nLCB0aW1lb3V0PzogbnVtYmVyLCByZXRyaWVzPzogbnVtYmVyLCBwb3J0PzogbnVtYmVyLCBsb29rdXA/OiBMb29rdXBGdW5jdGlvbiwgc2lnbmFsOiBBYm9ydFNpZ25hbCB9KSB7XG4gIGNvbnN0IHNlcnZlciA9IG9wdGlvbnMuc2VydmVyO1xuICBpZiAodHlwZW9mIHNlcnZlciAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGFyZ3VtZW50czogXCJzZXJ2ZXJcIiBtdXN0IGJlIGEgc3RyaW5nJyk7XG4gIH1cblxuICBjb25zdCBpbnN0YW5jZU5hbWUgPSBvcHRpb25zLmluc3RhbmNlTmFtZTtcbiAgaWYgKHR5cGVvZiBpbnN0YW5jZU5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBhcmd1bWVudHM6IFwiaW5zdGFuY2VOYW1lXCIgbXVzdCBiZSBhIHN0cmluZycpO1xuICB9XG5cbiAgY29uc3QgdGltZW91dCA9IG9wdGlvbnMudGltZW91dCA9PT0gdW5kZWZpbmVkID8gVElNRU9VVCA6IG9wdGlvbnMudGltZW91dDtcbiAgaWYgKHR5cGVvZiB0aW1lb3V0ICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgYXJndW1lbnRzOiBcInRpbWVvdXRcIiBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIH1cblxuICBjb25zdCByZXRyaWVzID0gb3B0aW9ucy5yZXRyaWVzID09PSB1bmRlZmluZWQgPyBSRVRSSUVTIDogb3B0aW9ucy5yZXRyaWVzO1xuICBpZiAodHlwZW9mIHJldHJpZXMgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBhcmd1bWVudHM6IFwicmV0cmllc1wiIG11c3QgYmUgYSBudW1iZXInKTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLmxvb2t1cCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRpb25zLmxvb2t1cCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgYXJndW1lbnRzOiBcImxvb2t1cFwiIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB9XG4gIGNvbnN0IGxvb2t1cCA9IG9wdGlvbnMubG9va3VwID8/IGRucy5sb29rdXA7XG5cbiAgaWYgKG9wdGlvbnMucG9ydCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRpb25zLnBvcnQgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBhcmd1bWVudHM6IFwicG9ydFwiIG11c3QgYmUgYSBudW1iZXInKTtcbiAgfVxuICBjb25zdCBwb3J0ID0gb3B0aW9ucy5wb3J0ID8/IFNRTF9TRVJWRVJfQlJPV1NFUl9QT1JUO1xuXG4gIGNvbnN0IHNpZ25hbCA9IG9wdGlvbnMuc2lnbmFsO1xuXG4gIHNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuXG4gIGxldCByZXNwb25zZTtcblxuICBjb25zdCByZXF1ZXN0ID0gQnVmZmVyLmZyb20oWzB4MDJdKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8PSByZXRyaWVzOyBpKyspIHtcbiAgICBjb25zdCB0aW1lb3V0U2lnbmFsID0gQWJvcnRTaWduYWwudGltZW91dCh0aW1lb3V0KTtcblxuICAgIHRyeSB7XG4gICAgICByZXNwb25zZSA9IGF3YWl0IHNlbmRNZXNzYWdlKG9wdGlvbnMuc2VydmVyLCBwb3J0LCBsb29rdXAsIEFib3J0U2lnbmFsLmFueShbIHNpZ25hbCwgdGltZW91dFNpZ25hbCBdKSwgcmVxdWVzdCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBJZiB0aGUgY3VycmVudCBhdHRlbXB0IHRpbWVkIG91dCwgY29udGludWUgd2l0aCB0aGUgbmV4dFxuICAgICAgaWYgKHRpbWVvdXRTaWduYWwuYWJvcnRlZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIGlmICghcmVzcG9uc2UpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBnZXQgcmVzcG9uc2UgZnJvbSBTUUwgU2VydmVyIEJyb3dzZXIgb24gJyArIHNlcnZlcik7XG4gIH1cblxuICBjb25zdCBtZXNzYWdlID0gcmVzcG9uc2UudG9TdHJpbmcoJ2FzY2lpJywgTVlTVEVSWV9IRUFERVJfTEVOR1RIKTtcbiAgY29uc3QgZm91bmRQb3J0ID0gcGFyc2VCcm93c2VyUmVzcG9uc2UobWVzc2FnZSwgaW5zdGFuY2VOYW1lKTtcblxuICBpZiAoIWZvdW5kUG9ydCkge1xuICAgIHRocm93IG5ldyBFcnJvcignUG9ydCBmb3IgJyArIGluc3RhbmNlTmFtZSArICcgbm90IGZvdW5kIGluICcgKyBvcHRpb25zLnNlcnZlcik7XG4gIH1cblxuICByZXR1cm4gZm91bmRQb3J0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCcm93c2VyUmVzcG9uc2UocmVzcG9uc2U6IHN0cmluZywgaW5zdGFuY2VOYW1lOiBzdHJpbmcpIHtcbiAgbGV0IGdldFBvcnQ7XG5cbiAgY29uc3QgaW5zdGFuY2VzID0gcmVzcG9uc2Uuc3BsaXQoJzs7Jyk7XG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSBpbnN0YW5jZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBjb25zdCBpbnN0YW5jZSA9IGluc3RhbmNlc1tpXTtcbiAgICBjb25zdCBwYXJ0cyA9IGluc3RhbmNlLnNwbGl0KCc7Jyk7XG5cbiAgICBmb3IgKGxldCBwID0gMCwgcGFydHNMZW4gPSBwYXJ0cy5sZW5ndGg7IHAgPCBwYXJ0c0xlbjsgcCArPSAyKSB7XG4gICAgICBjb25zdCBuYW1lID0gcGFydHNbcF07XG4gICAgICBjb25zdCB2YWx1ZSA9IHBhcnRzW3AgKyAxXTtcblxuICAgICAgaWYgKG5hbWUgPT09ICd0Y3AnICYmIGdldFBvcnQpIHtcbiAgICAgICAgY29uc3QgcG9ydCA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgICAgIHJldHVybiBwb3J0O1xuICAgICAgfVxuXG4gICAgICBpZiAobmFtZSA9PT0gJ0luc3RhbmNlTmFtZScpIHtcbiAgICAgICAgaWYgKHZhbHVlLnRvVXBwZXJDYXNlKCkgPT09IGluc3RhbmNlTmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgZ2V0UG9ydCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZ2V0UG9ydCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQSxJQUFBQSxJQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFFQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFBdUMsU0FBQUQsdUJBQUFHLEdBQUEsV0FBQUEsR0FBQSxJQUFBQSxHQUFBLENBQUFDLFVBQUEsR0FBQUQsR0FBQSxLQUFBRSxPQUFBLEVBQUFGLEdBQUE7QUFFdkMsTUFBTUcsdUJBQXVCLEdBQUcsSUFBSTtBQUNwQyxNQUFNQyxPQUFPLEdBQUcsQ0FBQyxHQUFHLElBQUk7QUFDeEIsTUFBTUMsT0FBTyxHQUFHLENBQUM7QUFDakI7QUFD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