insomnia/app/backend/dns.js
2016-10-26 22:37:40 -07:00

59 lines
1.3 KiB
JavaScript

import dns from 'dns';
import {parse as urlParse, format as urlFormat} from 'url';
/**
* Resolve to IP address and prefer IPv6 (only if supported)
*
* @param url
* @param forceIPv4
* @returns {Promise}
*/
function lookup (url, forceIPv4) {
return new Promise((resolve, reject) => {
const {hostname} = urlParse(url);
const options = {
hints: dns.ADDRCONFIG, // Only lookup supported addresses
all: true,
};
if (forceIPv4) {
options.family = 4;
}
dns.lookup(hostname, options, (err, results) => {
if (err) {
reject(err);
return;
}
const v6 = results.find(r => r.family === 6);
if (v6) {
resolve(v6.address);
} else if (results.length) {
// If no v6, return the first result
resolve(results[0].address);
} else {
// The only case I can find that hits this is sending in an IPv6
// address like `::1`
reject(new Error('Could not resolve host'))
}
});
})
}
export async function swapHost (url, forceIPv4) {
let ip;
try {
ip = await lookup(url, forceIPv4);
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;
}
}