mirror of
https://github.com/gamedig/node-gamedig.git
synced 2024-10-31 19:41:04 +01:00
Add punycode support (2.0.6)
This commit is contained in:
parent
5aaff8e1e0
commit
05619469b7
@ -429,6 +429,9 @@ as well: `--debug`, `--pretty`, `--socketTimeout 5000`, etc.
|
|||||||
Changelog
|
Changelog
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 2.0.6
|
||||||
|
* Added support for host domains requiring Punycode encoding (special characters)
|
||||||
|
|
||||||
### 2.0.5
|
### 2.0.5
|
||||||
* Added support for Counter-Strike: 2D
|
* Added support for Counter-Strike: 2D
|
||||||
|
|
||||||
|
71
lib/DnsResolver.js
Normal file
71
lib/DnsResolver.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
const dns = require('dns'),
|
||||||
|
Logger = require('./Logger'),
|
||||||
|
util = require('util'),
|
||||||
|
dnsLookupAsync = util.promisify(dns.lookup),
|
||||||
|
dnsResolveAsync = util.promisify(dns.resolve),
|
||||||
|
punycode = require('punycode');
|
||||||
|
|
||||||
|
class DnsResolver {
|
||||||
|
/**
|
||||||
|
* @param {Logger} logger
|
||||||
|
*/
|
||||||
|
constructor(logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
isIp(host) {
|
||||||
|
return !!host.match(/\d+\.\d+\.\d+\.\d+/);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response port will only be present if srv record was involved.
|
||||||
|
* @param {string} host
|
||||||
|
* @param {string=} srvRecordPrefix
|
||||||
|
* @returns {Promise<{address:string, port:number=}>}
|
||||||
|
*/
|
||||||
|
async resolve(host, srvRecordPrefix) {
|
||||||
|
this.logger.debug("DNS Lookup: " + host);
|
||||||
|
|
||||||
|
if(this.isIp(host)) {
|
||||||
|
this.logger.debug("Raw IP Address: " + host);
|
||||||
|
return {address: host};
|
||||||
|
}
|
||||||
|
|
||||||
|
const asciiForm = punycode.toASCII(host);
|
||||||
|
if (asciiForm !== host) {
|
||||||
|
this.logger.debug("Encoded punycode: " + host + " -> " + asciiForm);
|
||||||
|
host = asciiForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srvRecordPrefix) {
|
||||||
|
this.logger.debug("SRV Resolve: " + srvRecordPrefix + '.' + host);
|
||||||
|
let records;
|
||||||
|
try {
|
||||||
|
records = await dnsResolveAsync(srvRecordPrefix + '.' + host, 'SRV');
|
||||||
|
if (records.length >= 1) {
|
||||||
|
this.logger.debug("Found SRV Records: ", records);
|
||||||
|
const record = records[0];
|
||||||
|
const srvPort = record.port;
|
||||||
|
const srvHost = record.name;
|
||||||
|
if (srvHost === host) {
|
||||||
|
throw new Error('Loop in DNS SRV records');
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
port: srvPort,
|
||||||
|
...await this.resolve(srvHost, srvRecordPrefix)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.logger.debug("No SRV Record");
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.debug(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.debug("Standard Resolve: " + host);
|
||||||
|
const {address,family} = await dnsLookupAsync(host);
|
||||||
|
this.logger.debug("Found address: " + address);
|
||||||
|
return {address: address};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = DnsResolver;
|
40
lib/Logger.js
Normal file
40
lib/Logger.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const HexUtil = require('./HexUtil');
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
constructor() {
|
||||||
|
this.debugEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(...args) {
|
||||||
|
if (!this.debugEnabled) return;
|
||||||
|
this._print(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
_print(...args) {
|
||||||
|
try {
|
||||||
|
const strings = this._convertArgsToStrings(...args);
|
||||||
|
console.log(...strings);
|
||||||
|
} catch(e) {
|
||||||
|
console.log("Error while logging: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_convertArgsToStrings(...args) {
|
||||||
|
const out = [];
|
||||||
|
for (const arg of args) {
|
||||||
|
if (arg instanceof Error) {
|
||||||
|
out.push(arg.stack);
|
||||||
|
} else if (arg instanceof Buffer) {
|
||||||
|
out.push("\n" + HexUtil.debugDump(arg) + "\n");
|
||||||
|
} else if (typeof arg == 'function') {
|
||||||
|
const result = arg.call(undefined, (...args) => out.push(...this._convertArgsToStrings(...args)));
|
||||||
|
if (result !== undefined) out.push(...this._convertArgsToStrings(result));
|
||||||
|
} else {
|
||||||
|
out.push(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Logger;
|
15
package-lock.json
generated
15
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gamedig",
|
"name": "gamedig",
|
||||||
"version": "1.0.49",
|
"version": "2.0.5",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -449,9 +449,9 @@
|
|||||||
"integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw=="
|
"integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw=="
|
||||||
},
|
},
|
||||||
"punycode": {
|
"punycode": {
|
||||||
"version": "1.4.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
|
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||||
},
|
},
|
||||||
"qs": {
|
"qs": {
|
||||||
"version": "6.5.2",
|
"version": "6.5.2",
|
||||||
@ -503,6 +503,13 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"psl": "^1.1.24",
|
"psl": "^1.1.24",
|
||||||
"punycode": "^1.4.1"
|
"punycode": "^1.4.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||||
|
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
],
|
],
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"author": "Michael Morrison",
|
"author": "Michael Morrison",
|
||||||
"version": "2.0.5",
|
"version": "2.0.6",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sonicsnes/node-gamedig.git"
|
"url": "https://github.com/sonicsnes/node-gamedig.git"
|
||||||
@ -31,6 +31,7 @@
|
|||||||
"long": "^2.4.0",
|
"long": "^2.4.0",
|
||||||
"minimist": "^1.2.0",
|
"minimist": "^1.2.0",
|
||||||
"moment": "^2.21.0",
|
"moment": "^2.21.0",
|
||||||
|
"punycode": "^2.1.1",
|
||||||
"request": "^2.88.0",
|
"request": "^2.88.0",
|
||||||
"request-promise": "^4.2.2",
|
"request-promise": "^4.2.2",
|
||||||
"varint": "^4.0.1"
|
"varint": "^4.0.1"
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
const EventEmitter = require('events').EventEmitter,
|
const EventEmitter = require('events').EventEmitter,
|
||||||
dns = require('dns'),
|
|
||||||
net = require('net'),
|
net = require('net'),
|
||||||
Reader = require('../lib/reader'),
|
Reader = require('../lib/reader'),
|
||||||
HexUtil = require('../lib/HexUtil'),
|
HexUtil = require('../lib/HexUtil'),
|
||||||
util = require('util'),
|
|
||||||
dnsLookupAsync = util.promisify(dns.lookup),
|
|
||||||
dnsResolveAsync = util.promisify(dns.resolve),
|
|
||||||
requestAsync = require('request-promise'),
|
requestAsync = require('request-promise'),
|
||||||
Promises = require('../lib/Promises');
|
Promises = require('../lib/Promises'),
|
||||||
|
Logger = require('../lib/Logger'),
|
||||||
|
DnsResolver = require('../lib/DnsResolver');
|
||||||
|
|
||||||
class Core extends EventEmitter {
|
class Core extends EventEmitter {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -17,6 +15,8 @@ class Core extends EventEmitter {
|
|||||||
this.delimiter = '\0';
|
this.delimiter = '\0';
|
||||||
this.srvRecord = null;
|
this.srvRecord = null;
|
||||||
this.abortedPromise = null;
|
this.abortedPromise = null;
|
||||||
|
this.logger = new Logger();
|
||||||
|
this.dnsResolver = new DnsResolver(this.logger);
|
||||||
|
|
||||||
// Sent to us by QueryRunner
|
// Sent to us by QueryRunner
|
||||||
this.options = null;
|
this.options = null;
|
||||||
@ -26,6 +26,10 @@ class Core extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async runAllAttempts() {
|
async runAllAttempts() {
|
||||||
|
if (this.options.debug) {
|
||||||
|
this.logger.debugEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
let result = null;
|
let result = null;
|
||||||
let lastError = null;
|
let lastError = null;
|
||||||
for (let attempt = 1; attempt <= this.options.maxAttempts; attempt++) {
|
for (let attempt = 1; attempt <= this.options.maxAttempts; attempt++) {
|
||||||
@ -72,7 +76,9 @@ class Core extends EventEmitter {
|
|||||||
async runOnce() {
|
async runOnce() {
|
||||||
const options = this.options;
|
const options = this.options;
|
||||||
if (('host' in options) && !('address' in options)) {
|
if (('host' in options) && !('address' in options)) {
|
||||||
options.address = await this.parseDns(options.host);
|
const resolved = await this.dnsResolver.resolve(options.host, this.srvRecord);
|
||||||
|
options.address = resolved.address;
|
||||||
|
if (resolved.port) options.port = resolved.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
@ -108,44 +114,6 @@ class Core extends EventEmitter {
|
|||||||
|
|
||||||
async run(state) {}
|
async run(state) {}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} host
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
async parseDns(host) {
|
|
||||||
const isIp = (host) => {
|
|
||||||
return !!host.match(/\d+\.\d+\.\d+\.\d+/);
|
|
||||||
};
|
|
||||||
const resolveStandard = async (host) => {
|
|
||||||
if(isIp(host)) return host;
|
|
||||||
this.debugLog("Standard DNS Lookup: " + host);
|
|
||||||
const {address,family} = await dnsLookupAsync(host);
|
|
||||||
this.debugLog(address);
|
|
||||||
return address;
|
|
||||||
};
|
|
||||||
const resolveSrv = async (srv,host) => {
|
|
||||||
if(isIp(host)) return host;
|
|
||||||
this.debugLog("SRV DNS Lookup: " + srv+'.'+host);
|
|
||||||
let records;
|
|
||||||
try {
|
|
||||||
records = await dnsResolveAsync(srv + '.' + host, 'SRV');
|
|
||||||
this.debugLog(records);
|
|
||||||
if(records.length >= 1) {
|
|
||||||
const record = records[0];
|
|
||||||
this.options.port = record.port;
|
|
||||||
const srvhost = record.name;
|
|
||||||
return await resolveStandard(srvhost);
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
this.debugLog(e.toString());
|
|
||||||
}
|
|
||||||
return await resolveStandard(host);
|
|
||||||
};
|
|
||||||
|
|
||||||
if(this.srvRecord) return await resolveSrv(this.srvRecord, host);
|
|
||||||
else return await resolveStandard(host);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Param can be a time in ms, or a promise (which will be timed) */
|
/** Param can be a time in ms, or a promise (which will be timed) */
|
||||||
registerRtt(param) {
|
registerRtt(param) {
|
||||||
if (param.then) {
|
if (param.then) {
|
||||||
@ -383,22 +351,9 @@ class Core extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated */
|
||||||
debugLog(...args) {
|
debugLog(...args) {
|
||||||
if (!this.options.debug) return;
|
this.logger.debug(...args);
|
||||||
try {
|
|
||||||
if(args[0] instanceof Buffer) {
|
|
||||||
this.debugLog(HexUtil.debugDump(args[0]));
|
|
||||||
} else if (typeof args[0] == 'function') {
|
|
||||||
const result = args[0].call(undefined, this.debugLog.bind(this));
|
|
||||||
if (result !== undefined) {
|
|
||||||
this.debugLog(result);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log(...args);
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
console.log("Error while debug logging: " + e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user