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

deps: update undici to 6.17.0 #53034

Merged
merged 2 commits into from
May 20, 2024
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
32 changes: 32 additions & 0 deletions deps/undici/src/docs/docs/api/Dispatcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,38 @@ const client = new Client("http://example.com").compose(
);
```

##### `dump`

The `dump` interceptor enables you to dump the response body from a request upon a given limit.

**Options**
- `maxSize` - The maximum size (in bytes) of the response body to dump. If the size of the request's body exceeds this value then the connection will be closed. Default: `1048576`.

> The `Dispatcher#options` also gets extended with the options `dumpMaxSize`, `abortOnDumped`, and `waitForTrailers` which can be used to configure the interceptor at a request-per-request basis.

**Example - Basic Dump Interceptor**

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

const client = new Client("http://example.com").compose(
dump({
maxSize: 1024,
})
);

// or
client.dispatch(
{
path: "/",
method: "GET",
dumpMaxSize: 1024,
},
handler
);
```

## Instance Events

### Event: `'connect'`
Expand Down
2 changes: 1 addition & 1 deletion deps/undici/src/index-fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const fetchImpl = require('./lib/web/fetch').fetch
module.exports.fetch = function fetch (resource, init = undefined) {
return fetchImpl(resource, init).catch((err) => {
if (err && typeof err === 'object') {
Error.captureStackTrace(err, this)
Error.captureStackTrace(err)
}
throw err
})
Expand Down
5 changes: 3 additions & 2 deletions deps/undici/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ module.exports.RedirectHandler = RedirectHandler
module.exports.createRedirectInterceptor = createRedirectInterceptor
module.exports.interceptors = {
redirect: require('./lib/interceptor/redirect'),
retry: require('./lib/interceptor/retry')
retry: require('./lib/interceptor/retry'),
dump: require('./lib/interceptor/dump')
}

module.exports.buildConnector = buildConnector
Expand Down Expand Up @@ -108,7 +109,7 @@ module.exports.fetch = async function fetch (init, options = undefined) {
return await fetchImpl(init, options)
} catch (err) {
if (err && typeof err === 'object') {
Error.captureStackTrace(err, this)
Error.captureStackTrace(err)
}

throw err
Expand Down
1 change: 0 additions & 1 deletion deps/undici/src/lib/core/symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ module.exports = {
kQueue: Symbol('queue'),
kConnect: Symbol('connect'),
kConnecting: Symbol('connecting'),
kHeadersList: Symbol('headers list'),
kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'),
kKeepAliveMaxTimeout: Symbol('max keep alive timeout'),
kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'),
Expand Down
2 changes: 1 addition & 1 deletion deps/undici/src/lib/dispatcher/client-h1.js
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,7 @@ function writeStream ({ abort, body, client, request, socket, contentLength, hea
}
}

async function writeBuffer ({ abort, body, client, request, socket, contentLength, header, expectsPayload }) {
function writeBuffer ({ abort, body, client, request, socket, contentLength, header, expectsPayload }) {
try {
if (!body) {
if (contentLength === 0) {
Expand Down
123 changes: 123 additions & 0 deletions deps/undici/src/lib/interceptor/dump.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
'use strict'

const util = require('../core/util')
const { InvalidArgumentError, RequestAbortedError } = require('../core/errors')
const DecoratorHandler = require('../handler/decorator-handler')

class DumpHandler extends DecoratorHandler {
#maxSize = 1024 * 1024
#abort = null
#dumped = false
#aborted = false
#size = 0
#reason = null
#handler = null

constructor ({ maxSize }, handler) {
super(handler)

if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) {
throw new InvalidArgumentError('maxSize must be a number greater than 0')
}

this.#maxSize = maxSize ?? this.#maxSize
this.#handler = handler
}

onConnect (abort) {
this.#abort = abort

this.#handler.onConnect(this.#customAbort.bind(this))
}

#customAbort (reason) {
this.#aborted = true
this.#reason = reason
}

// TODO: will require adjustment after new hooks are out
onHeaders (statusCode, rawHeaders, resume, statusMessage) {
const headers = util.parseHeaders(rawHeaders)
const contentLength = headers['content-length']

if (contentLength != null && contentLength > this.#maxSize) {
throw new RequestAbortedError(
`Response size (${contentLength}) larger than maxSize (${
this.#maxSize
})`
)
}

if (this.#aborted) {
return true
}

return this.#handler.onHeaders(
statusCode,
rawHeaders,
resume,
statusMessage
)
}

onError (err) {
if (this.#dumped) {
return
}

err = this.#reason ?? err

this.#handler.onError(err)
}

onData (chunk) {
this.#size = this.#size + chunk.length

if (this.#size >= this.#maxSize) {
this.#dumped = true

if (this.#aborted) {
this.#handler.onError(this.#reason)
} else {
this.#handler.onComplete([])
}
}

return true
}

onComplete (trailers) {
if (this.#dumped) {
return
}

if (this.#aborted) {
this.#handler.onError(this.reason)
return
}

this.#handler.onComplete(trailers)
}
}

function createDumpInterceptor (
{ maxSize: defaultMaxSize } = {
maxSize: 1024 * 1024
}
) {
return dispatch => {
return function Intercept (opts, handler) {
const { dumpMaxSize = defaultMaxSize } =
opts

const dumpHandler = new DumpHandler(
{ maxSize: dumpMaxSize },
handler
)

return dispatch(opts, dumpHandler)
}
}
}

module.exports = createDumpInterceptor
8 changes: 5 additions & 3 deletions deps/undici/src/lib/web/cookies/util.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const assert = require('node:assert')
const { kHeadersList } = require('../../core/symbols')
const { getHeadersList: internalGetHeadersList } = require('../fetch/headers')

/**
* @param {string} value
Expand Down Expand Up @@ -278,8 +278,10 @@ function stringify (cookie) {
let kHeadersListNode

function getHeadersList (headers) {
if (headers[kHeadersList]) {
return headers[kHeadersList]
try {
return internalGetHeadersList(headers)
} catch {
// fall-through
}

if (!kHeadersListNode) {
Expand Down
9 changes: 9 additions & 0 deletions deps/undici/src/lib/web/fetch/body.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,15 @@ function bodyMixinMethods (instance) {
'Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded".'
)
}, instance, false)
},

bytes () {
// The bytes() method steps are to return the result of running consume body
// with this and the following step given a byte sequence bytes: return the
// result of creating a Uint8Array from bytes in this’s relevant realm.
return consumeBody(this, (bytes) => {
return new Uint8Array(bytes.buffer, 0, bytes.byteLength)
}, instance, true)
}
}

Expand Down
Loading