tangerine 1.2.1 → 1.2.2
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/README.md +1 -5
- package/index.js +17 -4
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -211,8 +211,7 @@ tangerine.resolve('forwardemail.net').then(console.log);
|
|
|
211
211
|
retry: {
|
|
212
212
|
limit: 0
|
|
213
213
|
}
|
|
214
|
-
}
|
|
215
|
-
requestTimeout: (ms) => ({ timeout: { request: ms } })
|
|
214
|
+
}
|
|
216
215
|
},
|
|
217
216
|
got
|
|
218
217
|
);
|
|
@@ -223,8 +222,6 @@ tangerine.resolve('forwardemail.net').then(console.log);
|
|
|
223
222
|
* The `body` property returned should be either a `Buffer` or `Stream`.
|
|
224
223
|
|
|
225
224
|
* Specify default request options based off the library under `requestOptions` below
|
|
226
|
-
|
|
227
|
-
* See `requestTimeout` function below, as it is required to be set properly if you are using a custom HTTP library function.
|
|
228
225
|
* Instance methods of [dns.promises.Resolver](https://nodejs.org/api/dns.html) are mirrored to :tangerine: Tangerine.
|
|
229
226
|
* Resolver methods accept an optional `abortController` argument, which is an instance of [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). Note that :tangerine: Tangerine manages `AbortController` usage internally – so you most likely won't need to pass your own (see [index.js](https://github.com/forwardemail/tangerine/blob/main/index.js) for more insight).
|
|
230
227
|
* See the complete list of [Options](#options) below.
|
|
@@ -287,7 +284,6 @@ Similar to the `options` argument from `new dns.promises.Resolver(options)` invo
|
|
|
287
284
|
| `requestOptions` | `Object` | Defaults to an Object with `requestOptions.method` and `requestOptions.headers` properties and values below | Default options to pass to [undici](https://github.com/nodejs/undici) (or your custom HTTP library function passed as `request`). |
|
|
288
285
|
| `requestOptions.method` | `String` | Defaults to `"GET"` (must be either `"GET"` or `"POST"`, case-insensitive depending on library you use). | Default HTTP method to use for DNS over HTTP ("DoH") requests. |
|
|
289
286
|
| `requestOptions.headers` | `Object` | Defaults to `{ 'content-type': 'application/dns-message', 'user-agent': pkg.name + "/" + pkg.version, accept: 'application/dns-message', bodyTimeout: timeout }`. | Default HTTP headers to use for DNS over HTTP ("DoH") requests. |
|
|
290
|
-
| `requestTimeout` | `Function` | Defaults to `(ms) => ({ bodyTimeout })` for setting undici timeout properly. | This function accepts an argument `ms` which is the number of milliseconds to wait for the request to timeout (since we use a back-off strategy that mirrors the Node.js DNS module). This function is required to be passed and customized if you are using a custom HTTP library. If you're using a custom HTTP library such as `got`, you'd set this to `requestTimeout: (ms) => ({ timeout: { request: ms } })` |
|
|
291
287
|
| `protocol` | `String` | Defaults to `"https"`. | Default HTTP protocol to use for DNS over HTTPS ("DoH") requests. |
|
|
292
288
|
| `dnsOrder` | `String` | Defaults to `"verbatim"` for Node.js v17.0.0+ and `"ipv4first"` for older versions. | Sets the default result order of `lookup` invocations (see [dns.setDefaultResultOrder](https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder) for more insight). |
|
|
293
289
|
| `logger` | `Object` | `false` | This is the default logger. We recommend using [Cabin](https://github.com/cabinjs) instead of using `console` as your default logger. Set this value to `false` to disable logging entirely (uses noop function). |
|
package/index.js
CHANGED
|
@@ -12,6 +12,7 @@ const getStream = require('get-stream');
|
|
|
12
12
|
const ipaddr = require('ipaddr.js');
|
|
13
13
|
const mergeOptions = require('merge-options');
|
|
14
14
|
const pMap = require('p-map');
|
|
15
|
+
const pTimeout = require('p-timeout');
|
|
15
16
|
const pWaitFor = require('p-wait-for');
|
|
16
17
|
const packet = require('dns-packet');
|
|
17
18
|
const semver = require('semver');
|
|
@@ -69,6 +70,8 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
69
70
|
let err;
|
|
70
71
|
if (errors.length === 1) {
|
|
71
72
|
err = errors[0];
|
|
73
|
+
} else if (errors.every((e) => e instanceof pTimeout.TimeoutError)) {
|
|
74
|
+
err = errors[0];
|
|
72
75
|
} else {
|
|
73
76
|
err = new Error(
|
|
74
77
|
[...new Set(errors.map((e) => e.message).filter(Boolean))].join('; ')
|
|
@@ -76,6 +79,14 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
76
79
|
err.stack = [...new Set(errors.map((e) => e.stack).filter(Boolean))].join(
|
|
77
80
|
'\n\n'
|
|
78
81
|
);
|
|
82
|
+
|
|
83
|
+
// if all errors had `name` and they were all the same then preserve it
|
|
84
|
+
if (
|
|
85
|
+
typeof errors[0].name !== 'undefined' &&
|
|
86
|
+
errors.every((e) => e.name === errors[0].name)
|
|
87
|
+
)
|
|
88
|
+
err.name = errors[0].name;
|
|
89
|
+
|
|
79
90
|
// if all errors had `code` and they were all the same then preserve it
|
|
80
91
|
if (
|
|
81
92
|
typeof errors[0].code !== 'undefined' &&
|
|
@@ -251,7 +262,6 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
251
262
|
accept: 'application/dns-message'
|
|
252
263
|
}
|
|
253
264
|
},
|
|
254
|
-
requestTimeout: (ms) => ({ bodyTimeout: ms }),
|
|
255
265
|
//
|
|
256
266
|
// NOTE: we set the default to "get" since it is faster from `benchmark` results
|
|
257
267
|
//
|
|
@@ -756,7 +766,6 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
756
766
|
|
|
757
767
|
const options = {
|
|
758
768
|
...this.options.requestOptions,
|
|
759
|
-
...this.options.requestTimeout(timeout), // returns `{ bodyTimeout: requestTimeout }`
|
|
760
769
|
signal: abortController.signal
|
|
761
770
|
};
|
|
762
771
|
|
|
@@ -772,7 +781,9 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
772
781
|
}
|
|
773
782
|
|
|
774
783
|
debug('request', { url, options });
|
|
775
|
-
const response = await this.request(url, options)
|
|
784
|
+
const response = await pTimeout(this.request(url, options), timeout, {
|
|
785
|
+
signal: abortController.signal
|
|
786
|
+
});
|
|
776
787
|
return response;
|
|
777
788
|
}
|
|
778
789
|
|
|
@@ -901,7 +912,9 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
901
912
|
const err = this.constructor.createError(
|
|
902
913
|
name,
|
|
903
914
|
rrtype,
|
|
904
|
-
_err.
|
|
915
|
+
_err instanceof pTimeout.TimeoutError || _err.name === 'TimeoutError'
|
|
916
|
+
? dns.TIMEOUT
|
|
917
|
+
: _err.code,
|
|
905
918
|
_err.errno
|
|
906
919
|
);
|
|
907
920
|
// then map it to dns.CONNREFUSED
|
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 via Keyv.",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.2",
|
|
5
5
|
"author": "Forward Email (https://forwardemail.net)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/forwardemail/tangerine/issues"
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"keyv": "^4.5.2",
|
|
18
18
|
"merge-options": "3.0.4",
|
|
19
19
|
"p-map": "4",
|
|
20
|
+
"p-timeout": "4",
|
|
20
21
|
"p-wait-for": "3",
|
|
21
22
|
"port-numbers": "^6.0.1",
|
|
22
23
|
"semver": "^7.3.8"
|