Uses HTTP/2 to comply with RFC 8484 - section 5.2.
This commit is contained in:
parent
584fa75842
commit
83b4cb269f
1 changed files with 35 additions and 42 deletions
59
src/doh.js
59
src/doh.js
|
|
@ -1,7 +1,5 @@
|
||||||
import dnsPacket from 'dns-packet';
|
import dnsPacket from 'dns-packet';
|
||||||
import https from 'https';
|
import http2 from 'http2';
|
||||||
import http from 'http';
|
|
||||||
import base32Encode from 'base32-encode';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A super lame DNS over HTTPS stub resolver
|
* A super lame DNS over HTTPS stub resolver
|
||||||
|
|
@ -63,56 +61,51 @@ function makeQuery(qname, qtype = 'TXT') {
|
||||||
*/
|
*/
|
||||||
function sendDohMsg(packet, url, timeout) {
|
function sendDohMsg(packet, url, timeout) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const transport = url.startsWith('https://') ? https : http;
|
const client = http2.connect(url);
|
||||||
const buf = dnsPacket.encode(packet);
|
const buf = dnsPacket.encode(packet);
|
||||||
let requestOptions;
|
|
||||||
const headers = {
|
|
||||||
'Accept': 'application/dns-message',
|
|
||||||
'User-Agent': 'domain-forward/1.x'
|
|
||||||
};
|
|
||||||
const dnsQueryParam = buf.toString('base64').toString('utf-8').replace(/=/g, '');
|
const dnsQueryParam = buf.toString('base64').toString('utf-8').replace(/=/g, '');
|
||||||
url = `${url}?dns=${dnsQueryParam}`;
|
url = `${url}?dns=${dnsQueryParam}`;
|
||||||
url = new URL(url);
|
url = new URL(url);
|
||||||
requestOptions = {
|
const req = client.request({
|
||||||
method: 'GET',
|
":path": url.pathname + url.search
|
||||||
hostname: url.hostname,
|
});
|
||||||
port: url.port || 443,
|
|
||||||
path: url.pathname + url.search,
|
|
||||||
headers: headers
|
|
||||||
};
|
|
||||||
let data;
|
let data;
|
||||||
let timer;
|
let timer;
|
||||||
const request = transport.request(requestOptions, (response) => {
|
if (timeout) {
|
||||||
response.on('data', (d) => {
|
timer = setTimeout(() => {
|
||||||
|
req.destroy();
|
||||||
|
return reject(new Error(`Query timed out after ${timeout} milliseconds of inactivity`));
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
|
/*req.on('response', (headers, flags) => {
|
||||||
|
for (const name in headers) {
|
||||||
|
console.log(`${name}: ${headers[name]}`);
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
req.on('data', chunk => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = d;
|
data = chunk;
|
||||||
} else {
|
} else {
|
||||||
data = Buffer.concat([data, d]);
|
data = Buffer.concat([data, chunk]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
response.on('end', () => {
|
req.on('end', () => {
|
||||||
|
client.close();
|
||||||
if (timer) {
|
if (timer) {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const decoded = dnsPacket.decode(data);
|
const decoded = dnsPacket.decode(data);
|
||||||
resolve(decoded);
|
resolve(decoded);
|
||||||
} catch (e) {
|
} catch (err) {
|
||||||
reject(e);
|
return reject(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
req.on('error', (err) => {
|
||||||
request.on('error', (err) => {
|
req.destroy();
|
||||||
request.destroy();
|
|
||||||
return reject(err);
|
return reject(err);
|
||||||
});
|
});
|
||||||
if (timeout) {
|
req.end();
|
||||||
timer = setTimeout(() => {
|
|
||||||
request.destroy();
|
|
||||||
return reject(new Error(`Query timed out after ${timeout} milliseconds of inactivity`));
|
|
||||||
}, timeout);
|
|
||||||
}
|
|
||||||
request.end()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
editor.link_modal.header
Reference in a new issue