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