2016-10-02 20:57:00 +00:00
|
|
|
import dns from 'dns';
|
|
|
|
import {parse as urlParse, format as urlFormat} from 'url';
|
|
|
|
|
2016-10-26 20:19:18 +00:00
|
|
|
/**
|
2016-10-26 20:25:34 +00:00
|
|
|
* Resolve to IP address and prefer IPv6 (only if supported)
|
2016-10-26 20:19:18 +00:00
|
|
|
*
|
|
|
|
* @param url
|
2016-10-26 22:13:16 +00:00
|
|
|
* @param forceIPv4
|
2016-10-26 20:19:18 +00:00
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
2016-10-26 22:13:16 +00:00
|
|
|
function lookup (url, forceIPv4) {
|
2016-10-02 20:57:00 +00:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const {hostname} = urlParse(url);
|
2016-10-26 20:20:26 +00:00
|
|
|
|
2016-10-26 20:19:18 +00:00
|
|
|
const options = {
|
2016-10-26 20:25:34 +00:00
|
|
|
hints: dns.ADDRCONFIG, // Only lookup supported addresses
|
|
|
|
all: true,
|
2016-10-26 20:19:18 +00:00
|
|
|
};
|
2016-10-26 20:20:26 +00:00
|
|
|
|
2016-10-26 22:13:16 +00:00
|
|
|
if (forceIPv4) {
|
|
|
|
options.family = 4;
|
|
|
|
}
|
|
|
|
|
2016-10-26 20:19:18 +00:00
|
|
|
dns.lookup(hostname, options, (err, results) => {
|
|
|
|
if (err) {
|
|
|
|
reject(err);
|
2016-10-26 20:25:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const v6 = results.find(r => r.family === 6);
|
|
|
|
if (v6) {
|
|
|
|
resolve(v6.address);
|
2016-10-26 20:19:18 +00:00
|
|
|
} else {
|
2016-10-27 03:41:30 +00:00
|
|
|
// If no v6, return the first result
|
|
|
|
resolve(results[0].address);
|
2016-10-26 20:19:18 +00:00
|
|
|
}
|
2016-10-02 20:57:00 +00:00
|
|
|
});
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-10-26 22:13:16 +00:00
|
|
|
export async function swapHost (url, forceIPv4) {
|
2016-10-02 20:57:00 +00:00
|
|
|
let ip;
|
|
|
|
|
|
|
|
try {
|
2016-10-26 22:13:16 +00:00
|
|
|
ip = await lookup(url, forceIPv4);
|
2016-10-02 20:57:00 +00:00
|
|
|
const parsedUrl = urlParse(url);
|
|
|
|
delete parsedUrl.host; // So it doesn't build with old host
|
|
|
|
parsedUrl.hostname = ip;
|
|
|
|
return urlFormat(parsedUrl);
|
|
|
|
} catch (e) {
|
|
|
|
// Fail silently. It's OK
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
}
|