Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

tangerine

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tangerine - npm Package Compare versions

Comparing version 1.0.4 to 1.1.0

40

index.js

@@ -15,3 +15,2 @@ const dns = require('node:dns');

const pMap = require('p-map');
const pTimeout = require('p-timeout');
const pWaitFor = require('p-wait-for');

@@ -242,3 +241,5 @@ const packet = require('dns-packet');

servers: new Set(['1.1.1.1', '1.0.0.1']),
undici: {
// HTTP library function to use
request,
requestOptions: {
method: 'GET',

@@ -251,2 +252,3 @@ headers: {

},
requestTimeout: (ms) => ({ bodyTimeout: ms }),
//

@@ -297,2 +299,10 @@ // NOTE: we set the default to "get" since it is faster from `benchmark` results

// request option method must be either GET or POST
if (
!['get', 'post'].includes(
this.options.requestOptions.method.toLowerCase()
)
)
throw new Error('Request options method must be either GET or POST');
// perform validation by re-using `setServers` method

@@ -732,8 +742,3 @@ this.setServers([...this.options.servers]);

//
async #request(
pkt,
server,
abortController,
requestTimeout = this.options.timeout
) {
async #request(pkt, server, abortController, timeout = this.options.timeout) {
// safeguard in case aborted

@@ -754,4 +759,5 @@ if (abortController.signal.aborted) return;

const options = {
signal: abortController.signal,
...this.options.undici
...this.options.requestOptions,
...this.options.requestTimeout(timeout), // returns `{ bodyTimeout: requestTimeout }`
signal: abortController.signal
};

@@ -763,3 +769,3 @@

// <https://github.com/hildjj/dohdec/blob/43564118c40f2127af871bdb4d40f615409d4b9c/pkg/dohdec/lib/doh.js#L117-L120>
if (this.options.undici.method === 'GET') {
if (this.options.requestOptions.method.toLowerCase() === 'get') {
if (!dohdec) await pWaitFor(() => Boolean(dohdec));

@@ -771,6 +777,4 @@ url += `?dns=${dohdec.DNSoverHTTPS.base64urlEncode(pkt)}`;

debug('request', { url, options, requestTimeout });
const response = await pTimeout(request(url, options), requestTimeout, {
signal: abortController.signal
});
debug('request', { url, options });
const response = await this.options.request(url, options);
return response;

@@ -823,4 +827,6 @@ }

if (body && statusCode >= 200 && statusCode < 300) {
// eslint-disable-next-line no-await-in-loop
buffer = await getStream.buffer(body);
buffer = Buffer.isBuffer(body)
? body
: // eslint-disable-next-line no-await-in-loop
await getStream.buffer(body);
// eslint-disable-next-line max-depth

@@ -827,0 +833,0 @@ if (!abortController.signal.aborted) abortController.abort();

{
"name": "tangerine",
"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.",
"version": "1.0.4",
"version": "1.1.0",
"author": "Forward Email (https://forwardemail.net)",

@@ -20,3 +20,2 @@ "bugs": {

"p-map": "4",
"p-timeout": "4",
"p-wait-for": "3",

@@ -23,0 +22,0 @@ "port-numbers": "^6.0.1",

@@ -254,23 +254,25 @@ <h1 align="center">

| Property | Type | Default Value | Description |
| ------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `timeout` | `Number` | `5000` | Number of milliseconds for requests to timeout. |
| `tries` | `Number` | `4` | Number of tries per `server` in `servers` to attempt. |
| `servers` | `Set` or `Array` | `new Set(['1.1.1.1', '1.0.0.1'])` | A Set or Array of [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6) formatted addresses for DNS queries (matches default Node.js dns module behavior). Duplicates will be removed as this is converted to a `Set` internally. Defaults to Cloudflare's of `1.1.1.1` and `1.0.0.1`. If an `Array` is passed, then it will be converted to a `Set`. |
| `undici` | `Object` | Defaults to an Object with `undici.method` and `undici.headers` properties and values below | Default options to pass to [undici](https://github.com/nodejs/undici). |
| `undici.method` | `String` | Defaults to `"GET"` (must be either `"GET"` or `"POST"`). | Default HTTP method to use for DNS over HTTP ("DoH") requests. |
| `undici.headers` | `Object` | Defaults to `{ 'content-type': 'application/dns-message', 'user-agent': pkg.name + "/" + pkg.version, accept: 'application/dns-message' }`. | Default HTTP headers to use for DNS over HTTP ("DoH") requests. |
| `protocol` | `String` | Defaults to `"https"`. | Default HTTP protocol to use for DNS over HTTPS ("DoH") requests. |
| `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). |
| `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). |
| `id` | `Number` or `Function` | `0` | Default `id` to be passed for DNS packet creation. This could alternatively be a synchronous or asynchronous function that returns a `Number` (e.g. `id: () => Tangerine.getRandomInt(1, 65534)`). |
| `concurrency` | `Number` | `os.cpus().length` | Default concurrency to use for `resolveAny` lookup via [p-map](https://github.com/sindresorhus/p-map). The default value is the number of CPU's available to the system using the Node.js `os` module [os.cpus()](https://nodejs.org/api/os.html#oscpus) method. |
| `ipv4` | `String` | `"0.0.0.0"` | Default IPv4 address to use for HTTP agent `localAddress` if DNS `server` was an IPv4 address. |
| `ipv6` | `String` | `"::0"` | Default IPv6 address to use for HTTP agent `localAddress` if DNS `server` was an IPv6 address. |
| `ipv4Port` | `Number` | `undefined` | Default port to use for HTTP agent `localPort` if DNS `server` was an IPv4 address. |
| `ipv6Port` | `Number` | `undefined` | Default port to use for HTTP agent `localPort` if DNS `server` was an IPv6 address. |
| `cache` | `Map` or `Boolean` | `new Map()` | Set this to `false` in order to disable caching. Default `Map` instance to use for caching. Entries are by type, e.g. `map.set('TXT', new Keyv({})`). If cache set values are not provided, then they will default to a new instance of `Keyv`. See cache setup and usage in [index.js](https://github.com/forwardemail/tangerine/blob/main/index.js) for more insight. You can iterate over `Tangerine.TYPES` if necessary to create a similar cache setup. |
| `returnHTTPErrors` | `Boolean` | `false` | Whether to return HTTP errors instead of mapping them to corresponding DNS errors. |
| `smartRotate` | `Boolean` | `true` | Whether to do smart server rotation if servers fail. |
| `defaultHTTPErrorMessage` | `String` | `"Unsuccessful HTTP response"` | Default fallback message if `statusCode` returned from HTTP request was not found in [http.STATUS_CODES](https://nodejs.org/api/http.html#httpstatus_codes). |
| Property | Type | Default Value | Description |
| ------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `timeout` | `Number` | `5000` | Number of milliseconds for requests to timeout. |
| `tries` | `Number` | `4` | Number of tries per `server` in `servers` to attempt. |
| `servers` | `Set` or `Array` | `new Set(['1.1.1.1', '1.0.0.1'])` | A Set or Array of [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6) formatted addresses for DNS queries (matches default Node.js dns module behavior). Duplicates will be removed as this is converted to a `Set` internally. Defaults to Cloudflare's of `1.1.1.1` and `1.0.0.1`. If an `Array` is passed, then it will be converted to a `Set`. |
| `request` | `Function` | [undici.request](https://undici.nodejs.org/#/?id=undicirequesturl-options-promise) | HTTP library request async or Promise returning function to be used for making request (defaults to undici's request method). You could alternatively use `got` or any other HTTP library of your choice that accepts `fn(url, options)`. It should return an object with `body`, `headers`, and either a `status` or `statusCode` property. The `body` property returned should be either a `Buffer` or `Stream`. Specify default request options based off the library under `requestOptions` below (e.g. for `got` you'd set `responseType: 'buffer', retry: { limit: 0 }`) since this library already has built-in retries. See `requestTimeout` function below, as it is required to be set properly if you are using a custom HTTP library function. |
| `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`). |
| `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. |
| `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. |
| `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 } })` |
| `protocol` | `String` | Defaults to `"https"`. | Default HTTP protocol to use for DNS over HTTPS ("DoH") requests. |
| `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). |
| `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). |
| `id` | `Number` or `Function` | `0` | Default `id` to be passed for DNS packet creation. This could alternatively be a synchronous or asynchronous function that returns a `Number` (e.g. `id: () => Tangerine.getRandomInt(1, 65534)`). |
| `concurrency` | `Number` | `os.cpus().length` | Default concurrency to use for `resolveAny` lookup via [p-map](https://github.com/sindresorhus/p-map). The default value is the number of CPU's available to the system using the Node.js `os` module [os.cpus()](https://nodejs.org/api/os.html#oscpus) method. |
| `ipv4` | `String` | `"0.0.0.0"` | Default IPv4 address to use for HTTP agent `localAddress` if DNS `server` was an IPv4 address. |
| `ipv6` | `String` | `"::0"` | Default IPv6 address to use for HTTP agent `localAddress` if DNS `server` was an IPv6 address. |
| `ipv4Port` | `Number` | `undefined` | Default port to use for HTTP agent `localPort` if DNS `server` was an IPv4 address. |
| `ipv6Port` | `Number` | `undefined` | Default port to use for HTTP agent `localPort` if DNS `server` was an IPv6 address. |
| `cache` | `Map` or `Boolean` | `new Map()` | Set this to `false` in order to disable caching. Default `Map` instance to use for caching. Entries are by type, e.g. `map.set('TXT', new Keyv({})`). If cache set values are not provided, then they will default to a new instance of `Keyv`. See cache setup and usage in [index.js](https://github.com/forwardemail/tangerine/blob/main/index.js) for more insight. You can iterate over `Tangerine.TYPES` if necessary to create a similar cache setup. |
| `returnHTTPErrors` | `Boolean` | `false` | Whether to return HTTP errors instead of mapping them to corresponding DNS errors. |
| `smartRotate` | `Boolean` | `true` | Whether to do smart server rotation if servers fail. |
| `defaultHTTPErrorMessage` | `String` | `"Unsuccessful HTTP response"` | Default fallback message if `statusCode` returned from HTTP request was not found in [http.STATUS_CODES](https://nodejs.org/api/http.html#httpstatus_codes). |

@@ -277,0 +279,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc