Add punycode support (2.0.6)

This commit is contained in:
mmorrison 2019-01-20 03:45:57 -06:00
parent 5aaff8e1e0
commit 05619469b7
6 changed files with 141 additions and 64 deletions

71
lib/DnsResolver.js Normal file
View 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
View 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;