Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node v20.18.2 nsolid v5.6.1 release #258

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ release.
</tr>
<tr>
<td valign="top">
<b><a href="doc/changelogs/CHANGELOG_V20.md#20.18.1">20.18.1</a></b><br/>
<b><a href="doc/changelogs/CHANGELOG_V20.md#20.18.2">20.18.2</a></b><br/>
<a href="doc/changelogs/CHANGELOG_V20.md#20.18.1">20.18.1</a><br/>
<a href="doc/changelogs/CHANGELOG_V20.md#20.18.0">20.18.0</a><br/>
<a href="doc/changelogs/CHANGELOG_V20.md#20.17.0">20.17.0</a><br/>
<a href="doc/changelogs/CHANGELOG_V20.md#20.16.0">20.16.0</a><br/>
Expand Down
1 change: 1 addition & 0 deletions deps/undici/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ The `body` mixins are the most common way to format the request/response body. M

- [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
- [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
- [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
- [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
- [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)

Expand Down
63 changes: 58 additions & 5 deletions deps/undici/src/docs/docs/api/Dispatcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -488,11 +488,13 @@ The `RequestOptions.method` property should not be value `'CONNECT'`.

`body` contains the following additional [body mixin](https://fetch.spec.whatwg.org/#body-mixin) methods and properties:

- `text()`
- `json()`
- `arrayBuffer()`
- `body`
- `bodyUsed`
* [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
* [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
* [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
* [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
* [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
* `body`
* `bodyUsed`

`body` can not be consumed twice. For example, calling `text()` after `json()` throws `TypeError`.

Expand Down Expand Up @@ -984,6 +986,57 @@ client.dispatch(
);
```

##### `dns`

The `dns` interceptor enables you to cache DNS lookups for a given duration, per origin.

>It is well suited for scenarios where you want to cache DNS lookups to avoid the overhead of resolving the same domain multiple times

**Options**
- `maxTTL` - The maximum time-to-live (in milliseconds) of the DNS cache. It should be a positive integer. Default: `10000`.
- Set `0` to disable TTL.
- `maxItems` - The maximum number of items to cache. It should be a positive integer. Default: `Infinity`.
- `dualStack` - Whether to resolve both IPv4 and IPv6 addresses. Default: `true`.
- It will also attempt a happy-eyeballs-like approach to connect to the available addresses in case of a connection failure.
- `affinity` - Whether to use IPv4 or IPv6 addresses. Default: `4`.
- It can be either `'4` or `6`.
- It will only take effect if `dualStack` is `false`.
- `lookup: (hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, addresses: DNSInterceptorRecord[]) => void) => void` - Custom lookup function. Default: `dns.lookup`.
- For more info see [dns.lookup](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback).
- `pick: (origin: URL, records: DNSInterceptorRecords, affinity: 4 | 6) => DNSInterceptorRecord` - Custom pick function. Default: `RoundRobin`.
- The function should return a single record from the records array.
- By default a simplified version of Round Robin is used.
- The `records` property can be mutated to store the state of the balancing algorithm.

> The `Dispatcher#options` also gets extended with the options `dns.affinity`, `dns.dualStack`, `dns.lookup` and `dns.pick` which can be used to configure the interceptor at a request-per-request basis.


**DNSInterceptorRecord**
It represents a DNS record.
- `family` - (`number`) The IP family of the address. It can be either `4` or `6`.
- `address` - (`string`) The IP address.

**DNSInterceptorOriginRecords**
It represents a map of DNS IP addresses records for a single origin.
- `4.ips` - (`DNSInterceptorRecord[] | null`) The IPv4 addresses.
- `6.ips` - (`DNSInterceptorRecord[] | null`) The IPv6 addresses.

**Example - Basic DNS Interceptor**

```js
const { Client, interceptors } = require("undici");
const { dns } = interceptors;

const client = new Agent().compose([
dns({ ...opts })
])

const response = await client.request({
origin: `http://localhost:3030`,
...requestOpts
})
```

##### `Response Error Interceptor`

**Introduction**
Expand Down
1 change: 1 addition & 0 deletions deps/undici/src/docs/docs/api/Fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This API is implemented as per the standard, you can find documentation on [MDN]

- [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
- [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
- [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
- [`.formData()`](https://fetch.spec.whatwg.org/#dom-body-formdata)
- [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
- [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
Expand Down
3 changes: 2 additions & 1 deletion deps/undici/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ module.exports.createRedirectInterceptor = createRedirectInterceptor
module.exports.interceptors = {
redirect: require('./lib/interceptor/redirect'),
retry: require('./lib/interceptor/retry'),
dump: require('./lib/interceptor/dump')
dump: require('./lib/interceptor/dump'),
dns: require('./lib/interceptor/dns')
}

module.exports.buildConnector = buildConnector
Expand Down
2 changes: 1 addition & 1 deletion deps/undici/src/lib/api/api-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class RequestHandler extends AsyncResource {
this.removeAbortListener = util.addAbortListener(this.signal, () => {
this.reason = this.signal.reason ?? new RequestAbortedError()
if (this.res) {
util.destroy(this.res, this.reason)
util.destroy(this.res.on('error', util.nop), this.reason)
} else if (this.abort) {
this.abort(this.reason)
}
Expand Down
42 changes: 33 additions & 9 deletions deps/undici/src/lib/api/readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ class BodyReadable extends Readable {
return consume(this, 'blob')
}

// https://fetch.spec.whatwg.org/#dom-body-bytes
async bytes () {
return consume(this, 'bytes')
}

// https://fetch.spec.whatwg.org/#dom-body-arraybuffer
async arrayBuffer () {
return consume(this, 'arrayBuffer')
Expand Down Expand Up @@ -306,6 +311,31 @@ function chunksDecode (chunks, length) {
return buffer.utf8Slice(start, bufferLength)
}

/**
* @param {Buffer[]} chunks
* @param {number} length
* @returns {Uint8Array}
*/
function chunksConcat (chunks, length) {
if (chunks.length === 0 || length === 0) {
return new Uint8Array(0)
}
if (chunks.length === 1) {
// fast-path
return new Uint8Array(chunks[0])
}
const buffer = new Uint8Array(Buffer.allocUnsafeSlow(length).buffer)

let offset = 0
for (let i = 0; i < chunks.length; ++i) {
const chunk = chunks[i]
buffer.set(chunk, offset)
offset += chunk.length
}

return buffer
}

function consumeEnd (consume) {
const { type, body, resolve, stream, length } = consume

Expand All @@ -315,17 +345,11 @@ function consumeEnd (consume) {
} else if (type === 'json') {
resolve(JSON.parse(chunksDecode(body, length)))
} else if (type === 'arrayBuffer') {
const dst = new Uint8Array(length)

let pos = 0
for (const buf of body) {
dst.set(buf, pos)
pos += buf.byteLength
}

resolve(dst.buffer)
resolve(chunksConcat(body, length).buffer)
} else if (type === 'blob') {
resolve(new Blob(body, { type: stream[kContentType] }))
} else if (type === 'bytes') {
resolve(chunksConcat(body, length))
}

consumeFinish(consume)
Expand Down
5 changes: 5 additions & 0 deletions deps/undici/src/lib/core/connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ const setupConnectTimeout = process.platform === 'win32'
* @param {number} opts.port
*/
function onConnectTimeout (socket, opts) {
// The socket could be already garbage collected
if (socket == null) {
return
}

let message = 'Connect Timeout Error'
if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) {
message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(', ')},`
Expand Down
11 changes: 7 additions & 4 deletions deps/undici/src/lib/dispatcher/client-h1.js
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,10 @@ function writeH1 (client, request) {
const expectsPayload = (
method === 'PUT' ||
method === 'POST' ||
method === 'PATCH'
method === 'PATCH' ||
method === 'QUERY' ||
method === 'PROPFIND' ||
method === 'PROPPATCH'
)

if (util.isFormDataLike(body)) {
Expand Down Expand Up @@ -1139,7 +1142,7 @@ function writeBuffer (abort, body, client, request, socket, contentLength, heade
socket.uncork()
request.onBodySent(body)

if (!expectsPayload) {
if (!expectsPayload && request.reset !== false) {
socket[kReset] = true
}
}
Expand Down Expand Up @@ -1169,7 +1172,7 @@ async function writeBlob (abort, body, client, request, socket, contentLength, h
request.onBodySent(buffer)
request.onRequestSent()

if (!expectsPayload) {
if (!expectsPayload && request.reset !== false) {
socket[kReset] = true
}

Expand Down Expand Up @@ -1270,7 +1273,7 @@ class AsyncWriter {
socket.cork()

if (bytesWritten === 0) {
if (!expectsPayload) {
if (!expectsPayload && request.reset !== false) {
socket[kReset] = true
}

Expand Down
Loading
Loading