insomnia/app/backend/dns.js

59 lines
1.3 KiB
JavaScript
Raw Normal View History

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) {
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-27 05:37:40 +00:00
} else if (results.length) {
2016-10-27 03:41:30 +00:00
// If no v6, return the first result
resolve(results[0].address);
2016-10-27 05:37:40 +00:00
} 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'))
2016-10-26 20:19:18 +00:00
}
});
})
}
2016-10-26 22:13:16 +00:00
export async function swapHost (url, forceIPv4) {
let ip;
try {
2016-10-26 22:13:16 +00:00
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;
}
}