1 | const Packet = require('../packet');
|
2 |
|
3 | const defaultGet = url => new Promise((resolve, reject) => {
|
4 | const headers = {
|
5 | accept: 'application/dns-message',
|
6 | };
|
7 | const base = url.startsWith('https') ? require('https') : require('http');
|
8 | const req = base.get(url, { headers }, resolve);
|
9 | req.on('error', reject);
|
10 | });
|
11 |
|
12 | const readStream = stream => {
|
13 | const buffer = [];
|
14 | return new Promise((resolve, reject) => {
|
15 | stream
|
16 | .on('error', reject)
|
17 | .on('data', chunk => buffer.push(chunk))
|
18 | .on('end', () => resolve(Buffer.concat(buffer)));
|
19 | });
|
20 | };
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | const DOHClient = ({ dns, http, get = defaultGet } = {}) => {
|
27 | return (name, type = 'A', cls = Packet.CLASS.IN, { clientIp, recursive = true } = {}) => {
|
28 | const packet = new Packet();
|
29 |
|
30 | if (recursive) {
|
31 | packet.header.rd = 1;
|
32 | }
|
33 | if (clientIp) {
|
34 | packet.additionals.push(Packet.Resource.EDNS([
|
35 | Packet.Resource.EDNS.ECS(clientIp),
|
36 | ]));
|
37 | }
|
38 | packet.questions.push({
|
39 | name,
|
40 | class : cls,
|
41 | type : Packet.TYPE[type],
|
42 | });
|
43 | const query = packet.toBase64URL();
|
44 | return Promise.resolve(get(`http${http ? '' : 's'}:
|
45 | .then(readStream)
|
46 | .then(Packet.parse);
|
47 | };
|
48 | };
|
49 |
|
50 | module.exports = DOHClient;
|