whois
Version:
A WHOIS client for NodeJS
197 lines (186 loc) • 5.39 kB
JavaScript
// Generated by CoffeeScript 2.5.1
(function() {
var SocksClient, _, cleanParsingErrors, net, punycode, url, util;
_ = require('underscore');
net = require('net');
SocksClient = require('socks').SocksClient;
url = require('url');
punycode = require('punycode/');
util = require('util');
this.SERVERS = require('./servers.json');
cleanParsingErrors = (string) => {
return string.replace(/^[:\s]+/, '').replace(/^https?[:\/]+/, '') || string;
};
this.lookup = (addr, options, done) => {
var _lookup, parts, proxy, server, sockOpts, socket, timeout, tld;
if (typeof done === 'undefined' && typeof options === 'function') {
done = options;
options = {};
if (addr === '__proto__') {
done(new Error('lookup: __proto__ is not allowed to lookup'));
return;
}
}
_.defaults(options, {
follow: 2,
timeout: 60000 // 60 seconds in ms
});
done = _.once(done);
server = options.server;
proxy = options.proxy;
timeout = options.timeout;
if (!server) {
switch (true) {
case _.contains(addr, '@'):
done(new Error('lookup: email addresses not supported'));
return;
case net.isIP(addr) !== 0:
server = this.SERVERS['_']['ip'];
break;
default:
tld = url.domainToASCII(addr);
while (true) {
server = this.SERVERS[tld];
if (!tld || server) {
break;
}
tld = tld.replace(/^.+?(\.|$)/, '');
}
}
}
if (!server) {
done(new Error('lookup: no whois server is known for this kind of object'));
return;
}
if (typeof server === 'string') {
parts = server.split(':');
server = {
host: parts[0],
port: parts[1]
};
}
if (typeof proxy === 'string') {
parts = proxy.split(':');
proxy = {
ipaddress: parts[0],
port: parseInt(parts[1])
};
}
_.defaults(server, {
port: 43,
query: "$addr\r\n"
});
if (proxy) {
_.defaults(proxy, {
type: 5
});
}
_lookup = (socket, done) => {
var data, idn;
idn = addr;
if (server.punycode !== false && options.punycode !== false) {
idn = url.domainToASCII(addr);
}
if (options.encoding) {
socket.setEncoding(options.encoding);
}
socket.write(server.query.replace('$addr', idn));
data = '';
socket.on('data', (chunk) => {
return data += chunk;
});
socket.on('timeout', () => {
socket.destroy();
return done(new Error('lookup: timeout'));
});
socket.on('error', (err) => {
return done(err);
});
return socket.on('close', (err) => {
var match;
if (options.follow > 0) {
match = data.replace(/\r/gm, '').match(/(ReferralServer|Registrar Whois|Whois Server|WHOIS Server|Registrar WHOIS Server|refer):[^\S\n]*((?:r?whois|https?):\/\/)?([0-9A-Za-z\.\-_]*)/);
if ((match != null) && match[3] !== server.host) {
options = _.extend({}, options, {
follow: options.follow - 1,
server: match[3].trim()
});
options.server = cleanParsingErrors(options.server);
this.lookup(addr, options, (err, parts) => {
if (err != null) {
if (options.verbose) {
return done(err, [
{
server: ('object' === typeof server) ? server.host.trim() : server.trim(),
data: data
}
]);
}
return done(err);
}
if (options.verbose) {
return done(null, [
{
server: ('object' === typeof server) ? server.host.trim() : server.trim(),
data: data
}
].concat(parts));
} else {
return done(null, parts);
}
});
return;
}
}
if (options.verbose) {
return done(null, [
{
server: ('object' === typeof server) ? server.host.trim() : server.trim(),
data: data
}
]);
} else {
return done(null, data);
}
});
};
if (!Number.isInteger(server.port)) {
server.port = 43;
}
if (proxy) {
return SocksClient.createConnection({
proxy: proxy,
destination: {
host: server.host,
port: server.port
},
command: 'connect',
timeout: timeout
}, (err, info) => {
var socket;
if (err != null) {
return done(err);
}
({socket} = info);
if (timeout) {
socket.setTimeout(timeout);
}
_lookup(socket, done);
return socket.resume();
});
} else {
sockOpts = {
host: server.host,
port: server.port
};
if (options.bind) {
sockOpts.localAddress = options.bind;
}
socket = net.connect(sockOpts);
if (timeout) {
socket.setTimeout(timeout);
}
return _lookup(socket, done);
}
};
}).call(this);