doh-js-client
Version:
DNS-over-HTTPS/DNS-over-TLS client for nodejs.
77 lines (76 loc) • 2.67 kB
JavaScript
;
exports.__esModule = true;
var XHR2 = require("xhr2");
var Packet = require("native-dns-packet");
var Util = require("./util");
function DoH(provider) {
Object.defineProperties(this, {
providers: {
value: {
google: 'https://dns.google/dns-query',
cloudflare: 'https://cloudflare-dns.com/dns-query',
cleanbrowsing: 'https://doh.cleanbrowsing.org/doh/family-filter',
quad9: 'https://dns9.quad9.net/dns-query'
},
writable: false
}
});
if (typeof this.providers[provider] === 'undefined') {
throw new Error('We only support these provider: google, cleanbrowsing, cloudflare');
}
this.provider = provider;
this.uri = this.providers[this.provider];
}
DoH.prototype.getProviders = function () {
return Object.keys(this.providers);
};
DoH.prototype.setProvider = function (provider) {
if (this.provider === provider) {
return;
}
if (typeof this.providers[provider] === 'undefined') {
throw new Error('We only support these provider: ' + this.getProviders().join(', '));
}
this.provider = provider;
this.uri = this.providers[this.provider];
};
DoH.prototype.resolve = function (domainName, domainType) {
var type = Util.getDomainType(domainType);
var dnsPacket = new Packet();
var dnsBuf = Util.newBuffer(128);
dnsPacket.question.push({
name: domainName,
type: type,
"class": 1
});
Packet.write(dnsBuf, dnsPacket);
var provider = this.provider;
var query = this.uri + "?dns=" + dnsBuf.toString('base64').replace(/=+/, '');
return new Promise(function (resolve, reject) {
var xhr = new XHR2();
xhr.open('GET', query, true);
xhr.setRequestHeader('Accept', 'application/dns-message');
xhr.setRequestHeader('Content-type', 'application/dns-message');
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
if (xhr.status === 200 && this.response) {
try {
var dnsResult = Buffer.from(this.response);
var result = Packet.parse(dnsResult);
resolve(result.answer);
}
catch (err) {
reject(err);
}
}
else {
reject(new Error("Cannot find the domain, provider: " + provider + ", xhr status: " + xhr.status + "."));
}
};
xhr.onerror = function (err) {
reject(err);
};
xhr.send(null);
});
};
module.exports = DoH;