Skip to content

Commit

Permalink
deps: update undici to 6.18.2
Browse files Browse the repository at this point in the history
PR-URL: #53255
Reviewed-By: Marco Ippolito <[email protected]>
Reviewed-By: Matthew Aitken <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
  • Loading branch information
nodejs-github-bot authored and marco-ippolito committed Jul 19, 2024
1 parent d02651c commit a6b803a
Show file tree
Hide file tree
Showing 11 changed files with 310 additions and 233 deletions.
3 changes: 3 additions & 0 deletions deps/undici/src/docs/docs/api/RetryHandler.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ It represents the retry state for a given request.
- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every retry.
- **handler** Extends [`Dispatch.DispatchHandlers`](Dispatcher.md#dispatcherdispatchoptions-handler) (required) - Handler function to be called after the request is successful or the retries are exhausted.

>__Note__: The `RetryHandler` does not retry over stateful bodies (e.g. streams, AsyncIterable) as those, once consumed, are left in an state that cannot be reutilized. For these situations the `RetryHandler` will identify
>the body as stateful and will not retry the request rejecting with the error `UND_ERR_REQ_RETRY`.
Examples:

```js
Expand Down
1 change: 1 addition & 0 deletions deps/undici/src/lib/core/symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = {
kHost: Symbol('host'),
kNoRef: Symbol('no ref'),
kBodyUsed: Symbol('used'),
kBody: Symbol('abstracted request body'),
kRunning: Symbol('running'),
kBlocking: Symbol('blocking'),
kPending: Symbol('pending'),
Expand Down
60 changes: 57 additions & 3 deletions deps/undici/src/lib/core/util.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,72 @@
'use strict'

const assert = require('node:assert')
const { kDestroyed, kBodyUsed, kListeners } = require('./symbols')
const { kDestroyed, kBodyUsed, kListeners, kBody } = require('./symbols')
const { IncomingMessage } = require('node:http')
const stream = require('node:stream')
const net = require('node:net')
const { InvalidArgumentError } = require('./errors')
const { Blob } = require('node:buffer')
const nodeUtil = require('node:util')
const { stringify } = require('node:querystring')
const { EventEmitter: EE } = require('node:events')
const { InvalidArgumentError } = require('./errors')
const { headerNameLowerCasedRecord } = require('./constants')
const { tree } = require('./tree')

const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v))

class BodyAsyncIterable {
constructor (body) {
this[kBody] = body
this[kBodyUsed] = false
}

async * [Symbol.asyncIterator] () {
assert(!this[kBodyUsed], 'disturbed')
this[kBodyUsed] = true
yield * this[kBody]
}
}

function wrapRequestBody (body) {
if (isStream(body)) {
// TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
// so that it can be dispatched again?
// TODO (fix): Do we need 100-expect support to provide a way to do this properly?
if (bodyLength(body) === 0) {
body
.on('data', function () {
assert(false)
})
}

if (typeof body.readableDidRead !== 'boolean') {
body[kBodyUsed] = false
EE.prototype.on.call(body, 'data', function () {
this[kBodyUsed] = true
})
}

return body
} else if (body && typeof body.pipeTo === 'function') {
// TODO (fix): We can't access ReadableStream internal state
// to determine whether or not it has been disturbed. This is just
// a workaround.
return new BodyAsyncIterable(body)
} else if (
body &&
typeof body !== 'string' &&
!ArrayBuffer.isView(body) &&
isIterable(body)
) {
// TODO: Should we allow re-using iterable if !this.opts.idempotent
// or through some other flag?
return new BodyAsyncIterable(body)
} else {
return body
}
}

function nop () {}

function isStream (obj) {
Expand Down Expand Up @@ -634,5 +687,6 @@ module.exports = {
isHttpOrHttpsPrefixed,
nodeMajor,
nodeMinor,
safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE']
safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'],
wrapRequestBody
}
15 changes: 11 additions & 4 deletions deps/undici/src/lib/handler/retry-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ const assert = require('node:assert')

const { kRetryHandlerDefaultRetry } = require('../core/symbols')
const { RequestRetryError } = require('../core/errors')
const { isDisturbed, parseHeaders, parseRangeHeader } = require('../core/util')
const {
isDisturbed,
parseHeaders,
parseRangeHeader,
wrapRequestBody
} = require('../core/util')

function calculateRetryAfterHeader (retryAfter) {
const current = Date.now()
Expand All @@ -29,7 +34,7 @@ class RetryHandler {

this.dispatch = handlers.dispatch
this.handler = handlers.handler
this.opts = dispatchOpts
this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) }
this.abort = null
this.aborted = false
this.retryOpts = {
Expand Down Expand Up @@ -174,7 +179,9 @@ class RetryHandler {
this.abort(
new RequestRetryError('Request failed', statusCode, {
headers,
count: this.retryCount
data: {
count: this.retryCount
}
})
)
return false
Expand Down Expand Up @@ -278,7 +285,7 @@ class RetryHandler {

const err = new RequestRetryError('Request failed', statusCode, {
headers,
count: this.retryCount
data: { count: this.retryCount }
})

this.abort(err)
Expand Down
7 changes: 3 additions & 4 deletions deps/undici/src/lib/web/cookies/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const { parseSetCookie } = require('./parse')
const { stringify, getHeadersList } = require('./util')
const { stringify } = require('./util')
const { webidl } = require('../fetch/webidl')
const { Headers } = require('../fetch/headers')

Expand Down Expand Up @@ -78,14 +78,13 @@ function getSetCookies (headers) {

webidl.brandCheck(headers, Headers, { strict: false })

const cookies = getHeadersList(headers).cookies
const cookies = headers.getSetCookie()

if (!cookies) {
return []
}

// In older versions of undici, cookies is a list of name:value.
return cookies.map((pair) => parseSetCookie(Array.isArray(pair) ? pair[1] : pair))
return cookies.map((pair) => parseSetCookie(pair))
}

/**
Expand Down
29 changes: 1 addition & 28 deletions deps/undici/src/lib/web/cookies/util.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
'use strict'

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

/**
* @param {string} value
* @returns {boolean}
Expand Down Expand Up @@ -275,35 +272,11 @@ function stringify (cookie) {
return out.join('; ')
}

let kHeadersListNode

function getHeadersList (headers) {
try {
return internalGetHeadersList(headers)
} catch {
// fall-through
}

if (!kHeadersListNode) {
kHeadersListNode = Object.getOwnPropertySymbols(headers).find(
(symbol) => symbol.description === 'headers list'
)

assert(kHeadersListNode, 'Headers cannot be parsed')
}

const headersList = headers[kHeadersListNode]
assert(headersList)

return headersList
}

module.exports = {
isCTLExcludingHtab,
validateCookieName,
validateCookiePath,
validateCookieValue,
toIMFDate,
stringify,
getHeadersList
stringify
}
8 changes: 0 additions & 8 deletions deps/undici/src/lib/web/fetch/headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -641,14 +641,6 @@ Object.defineProperties(Headers.prototype, {
},
[util.inspect.custom]: {
enumerable: false
},
// Compatibility for global headers
[Symbol('headers list')]: {
configurable: false,
enumerable: false,
get: function () {
return getHeadersList(this)
}
}
})

Expand Down
Loading

0 comments on commit a6b803a

Please sign in to comment.