tangerine 1.5.7 → 1.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +31 -35
- package/package.json +1 -2
package/index.js
CHANGED
|
@@ -14,7 +14,6 @@ const ipaddr = require('ipaddr.js');
|
|
|
14
14
|
const isStream = require('is-stream');
|
|
15
15
|
const mergeOptions = require('merge-options');
|
|
16
16
|
const pMap = require('p-map');
|
|
17
|
-
const pTimeout = require('p-timeout');
|
|
18
17
|
const pWaitFor = require('p-wait-for');
|
|
19
18
|
const packet = require('dns-packet');
|
|
20
19
|
const semver = require('semver');
|
|
@@ -109,8 +108,6 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
109
108
|
let err;
|
|
110
109
|
if (errors.length === 1) {
|
|
111
110
|
err = errors[0];
|
|
112
|
-
} else if (errors.every((e) => e instanceof pTimeout.TimeoutError)) {
|
|
113
|
-
err = errors[0];
|
|
114
111
|
} else {
|
|
115
112
|
err = new Error(
|
|
116
113
|
[...new Set(errors.map((e) => e.message).filter(Boolean))].join('; ')
|
|
@@ -1043,7 +1040,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1043
1040
|
//
|
|
1044
1041
|
async #request(pkt, server, abortController, timeout = this.options.timeout) {
|
|
1045
1042
|
// safeguard in case aborted
|
|
1046
|
-
|
|
1043
|
+
abortController?.signal?.throwIfAborted();
|
|
1047
1044
|
|
|
1048
1045
|
let localAddress;
|
|
1049
1046
|
let localPort;
|
|
@@ -1067,15 +1064,17 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1067
1064
|
// <https://github.com/hildjj/dohdec/blob/43564118c40f2127af871bdb4d40f615409d4b9c/pkg/dohdec/lib/doh.js#L117-L120>
|
|
1068
1065
|
if (this.options.requestOptions.method.toLowerCase() === 'get') {
|
|
1069
1066
|
if (!dohdec) await pWaitFor(() => Boolean(dohdec));
|
|
1067
|
+
// safeguard in case aborted
|
|
1068
|
+
abortController?.signal?.throwIfAborted();
|
|
1070
1069
|
url += `?dns=${dohdec.DNSoverHTTPS.base64urlEncode(pkt)}`;
|
|
1071
1070
|
} else {
|
|
1072
1071
|
options.body = pkt;
|
|
1073
1072
|
}
|
|
1074
1073
|
|
|
1075
1074
|
debug('request', { url, options });
|
|
1076
|
-
const
|
|
1077
|
-
|
|
1078
|
-
|
|
1075
|
+
const t = setTimeout(() => abortController.abort(), timeout);
|
|
1076
|
+
const response = await this.request(url, options);
|
|
1077
|
+
clearTimeout(t);
|
|
1079
1078
|
return response;
|
|
1080
1079
|
}
|
|
1081
1080
|
|
|
@@ -1129,31 +1128,33 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1129
1128
|
const statusCode = response.status || response.statusCode;
|
|
1130
1129
|
debug('response', { statusCode, headers });
|
|
1131
1130
|
|
|
1132
|
-
// <https://github.com/nodejs/undici/issues/3353#issuecomment-2184635954>
|
|
1133
|
-
// eslint-disable-next-line max-depth
|
|
1134
|
-
if (body && isStream(body) && typeof body.on === 'function')
|
|
1135
|
-
body.on('error', (err) => {
|
|
1136
|
-
this.options.logger.error(err, { response });
|
|
1137
|
-
});
|
|
1138
|
-
|
|
1139
1131
|
// eslint-disable-next-line max-depth
|
|
1140
1132
|
if (body && statusCode >= 200 && statusCode < 300) {
|
|
1141
1133
|
// <https://sindresorhus.com/blog/goodbye-nodejs-buffer>
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
// eslint-disable-next-line no-await-in-loop
|
|
1148
|
-
if (body
|
|
1149
|
-
|
|
1150
|
-
|
|
1134
|
+
// eslint-disable-next-line max-depth
|
|
1135
|
+
if (Buffer.isBuffer(body)) buffer = body;
|
|
1136
|
+
else if (typeof body.arrayBuffer === 'function')
|
|
1137
|
+
// eslint-disable-next-line no-await-in-loop
|
|
1138
|
+
buffer = Buffer.from(await body.arrayBuffer());
|
|
1139
|
+
// eslint-disable-next-line no-await-in-loop
|
|
1140
|
+
else if (isStream(body)) buffer = await getStream.buffer(body);
|
|
1141
|
+
else {
|
|
1142
|
+
const err = new TypeError('Unsupported body type');
|
|
1143
|
+
err.body = body;
|
|
1144
|
+
throw err;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1151
1147
|
break;
|
|
1152
1148
|
}
|
|
1153
1149
|
|
|
1154
1150
|
// <https://github.com/nodejs/undici/issues/3353>
|
|
1155
|
-
|
|
1156
|
-
|
|
1151
|
+
if (
|
|
1152
|
+
!abortController?.signal?.aborted &&
|
|
1153
|
+
body &&
|
|
1154
|
+
typeof body.dump === 'function'
|
|
1155
|
+
)
|
|
1156
|
+
// eslint-disable-next-line no-await-in-loop
|
|
1157
|
+
await body.dump();
|
|
1157
1158
|
|
|
1158
1159
|
// <https://github.com/nodejs/undici/blob/00dfd0bd41e73782452aecb728395f354585ca94/lib/core/errors.js#L47-L58>
|
|
1159
1160
|
const message =
|
|
@@ -1173,14 +1174,13 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1173
1174
|
// NOTE: if NOTFOUND error occurs then don't attempt further requests
|
|
1174
1175
|
// <https://nodejs.org/api/dns.html#dnssetserversservers>
|
|
1175
1176
|
//
|
|
1176
|
-
|
|
1177
|
+
|
|
1177
1178
|
if (err.code === dns.NOTFOUND) throw err;
|
|
1178
1179
|
|
|
1179
|
-
// eslint-disable-next-line max-depth
|
|
1180
1180
|
if (err.status >= 429) ipErrors.push(err);
|
|
1181
1181
|
|
|
1182
1182
|
// break out of the loop if status code was not retryable
|
|
1183
|
-
|
|
1183
|
+
|
|
1184
1184
|
if (
|
|
1185
1185
|
!(
|
|
1186
1186
|
err.statusCode &&
|
|
@@ -1231,16 +1231,12 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1231
1231
|
// https://github.com/mafintosh/dns-packet/issues/72
|
|
1232
1232
|
return packet.decode(buffer);
|
|
1233
1233
|
} catch (_err) {
|
|
1234
|
-
// NOTE: we don't need to do this (causes uncaught exception)
|
|
1235
|
-
// if (!abortController.signal.aborted) abortController.abort();
|
|
1236
1234
|
debug(_err, { name, rrtype, ecsSubnet });
|
|
1237
1235
|
if (this.options.returnHTTPErrors) throw _err;
|
|
1238
1236
|
const err = this.constructor.createError(
|
|
1239
1237
|
name,
|
|
1240
1238
|
rrtype,
|
|
1241
|
-
_err
|
|
1242
|
-
? dns.TIMEOUT
|
|
1243
|
-
: _err.code,
|
|
1239
|
+
_err.code,
|
|
1244
1240
|
_err.errno
|
|
1245
1241
|
);
|
|
1246
1242
|
// then map it to dns.CONNREFUSED
|
|
@@ -1258,7 +1254,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1258
1254
|
for (const abortController of this.abortControllers) {
|
|
1259
1255
|
if (!abortController.signal.aborted) {
|
|
1260
1256
|
try {
|
|
1261
|
-
abortController.abort();
|
|
1257
|
+
abortController.abort('Cancel invoked');
|
|
1262
1258
|
} catch (err) {
|
|
1263
1259
|
this.options.logger.debug(err);
|
|
1264
1260
|
}
|
|
@@ -1281,7 +1277,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1281
1277
|
'abort',
|
|
1282
1278
|
() => {
|
|
1283
1279
|
try {
|
|
1284
|
-
abortController.abort();
|
|
1280
|
+
abortController.abort('Parent abort controller aborted');
|
|
1285
1281
|
} catch (err) {
|
|
1286
1282
|
this.options.logger.debug(err);
|
|
1287
1283
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tangerine",
|
|
3
3
|
"description": "Tangerine is the best Node.js drop-in replacement for dns.promises.Resolver using DNS over HTTPS (\"DoH\") via undici with built-in retries, timeouts, smart server rotation, AbortControllers, and caching support for multiple backends (with TTL and purge support).",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.9",
|
|
5
5
|
"author": "Forward Email (https://forwardemail.net)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/forwardemail/nodejs-dns-over-https-tangerine/issues"
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"is-stream": "2.0.1",
|
|
21
21
|
"merge-options": "3.0.4",
|
|
22
22
|
"p-map": "4",
|
|
23
|
-
"p-timeout": "4",
|
|
24
23
|
"p-wait-for": "3",
|
|
25
24
|
"port-numbers": "6.0.1",
|
|
26
25
|
"private-ip": "^3.0.2",
|