mirror of
https://github.com/gamedig/node-gamedig.git
synced 2024-11-17 09:18:31 +01:00
Add punycode support (2.0.6)
This commit is contained in:
parent
5aaff8e1e0
commit
05619469b7
6 changed files with 141 additions and 64 deletions
|
@ -429,6 +429,9 @@ as well: `--debug`, `--pretty`, `--socketTimeout 5000`, etc.
|
|||
Changelog
|
||||
---
|
||||
|
||||
### 2.0.6
|
||||
* Added support for host domains requiring Punycode encoding (special characters)
|
||||
|
||||
### 2.0.5
|
||||
* 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",
|
||||
"version": "1.0.49",
|
||||
"version": "2.0.5",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -449,9 +449,9 @@
|
|||
"integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw=="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
|
@ -503,6 +503,13 @@
|
|||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"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",
|
||||
"author": "Michael Morrison",
|
||||
"version": "2.0.5",
|
||||
"version": "2.0.6",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sonicsnes/node-gamedig.git"
|
||||
|
@ -31,6 +31,7 @@
|
|||
"long": "^2.4.0",
|
||||
"minimist": "^1.2.0",
|
||||
"moment": "^2.21.0",
|
||||
"punycode": "^2.1.1",
|
||||
"request": "^2.88.0",
|
||||
"request-promise": "^4.2.2",
|
||||
"varint": "^4.0.1"
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
const EventEmitter = require('events').EventEmitter,
|
||||
dns = require('dns'),
|
||||
net = require('net'),
|
||||
Reader = require('../lib/reader'),
|
||||
HexUtil = require('../lib/HexUtil'),
|
||||
util = require('util'),
|
||||
dnsLookupAsync = util.promisify(dns.lookup),
|
||||
dnsResolveAsync = util.promisify(dns.resolve),
|
||||
requestAsync = require('request-promise'),
|
||||
Promises = require('../lib/Promises');
|
||||
Promises = require('../lib/Promises'),
|
||||
Logger = require('../lib/Logger'),
|
||||
DnsResolver = require('../lib/DnsResolver');
|
||||
|
||||
class Core extends EventEmitter {
|
||||
constructor() {
|
||||
|
@ -17,6 +15,8 @@ class Core extends EventEmitter {
|
|||
this.delimiter = '\0';
|
||||
this.srvRecord = null;
|
||||
this.abortedPromise = null;
|
||||
this.logger = new Logger();
|
||||
this.dnsResolver = new DnsResolver(this.logger);
|
||||
|
||||
// Sent to us by QueryRunner
|
||||
this.options = null;
|
||||
|
@ -26,6 +26,10 @@ class Core extends EventEmitter {
|
|||
}
|
||||
|
||||
async runAllAttempts() {
|
||||
if (this.options.debug) {
|
||||
this.logger.debugEnabled = true;
|
||||
}
|
||||
|
||||
let result = null;
|
||||
let lastError = null;
|
||||
for (let attempt = 1; attempt <= this.options.maxAttempts; attempt++) {
|
||||
|
@ -72,7 +76,9 @@ class Core extends EventEmitter {
|
|||
async runOnce() {
|
||||
const options = this.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 = {
|
||||
|
@ -108,44 +114,6 @@ class Core extends EventEmitter {
|
|||
|
||||
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) */
|
||||
registerRtt(param) {
|
||||
if (param.then) {
|
||||
|
@ -383,22 +351,9 @@ class Core extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
debugLog(...args) {
|
||||
if (!this.options.debug) return;
|
||||
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);
|
||||
}
|
||||
this.logger.debug(...args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue