Skip to content

Commit

Permalink
deps: update undici to 7.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
nodejs-github-bot committed Jan 16, 2025
1 parent 0e7ec5e commit 931319e
Show file tree
Hide file tree
Showing 13 changed files with 426 additions and 353 deletions.
29 changes: 17 additions & 12 deletions deps/undici/src/lib/core/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,20 +600,25 @@ function ReadableStreamFrom (iterable) {
async start () {
iterator = iterable[Symbol.asyncIterator]()
},
async pull (controller) {
const { done, value } = await iterator.next()
if (done) {
queueMicrotask(() => {
controller.close()
controller.byobRequest?.respond(0)
})
} else {
const buf = Buffer.isBuffer(value) ? value : Buffer.from(value)
if (buf.byteLength) {
controller.enqueue(new Uint8Array(buf))
pull (controller) {
async function pull () {
const { done, value } = await iterator.next()
if (done) {
queueMicrotask(() => {
controller.close()
controller.byobRequest?.respond(0)
})
} else {
const buf = Buffer.isBuffer(value) ? value : Buffer.from(value)
if (buf.byteLength) {
controller.enqueue(new Uint8Array(buf))
} else {
return await pull()
}
}
}
return controller.desiredSize > 0

return pull()
},
async cancel () {
await iterator.return()
Expand Down
101 changes: 77 additions & 24 deletions deps/undici/src/lib/interceptor/dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class DNSInstance {

// If full, we just return the origin
if (ips == null && this.full) {
cb(null, origin.origin)
cb(null, origin)
return
}

Expand Down Expand Up @@ -74,9 +74,9 @@ class DNSInstance {

cb(
null,
`${origin.protocol}//${
new URL(`${origin.protocol}//${
ip.family === 6 ? `[${ip.address}]` : ip.address
}${port}`
}${port}`)
)
})
} else {
Expand Down Expand Up @@ -105,9 +105,9 @@ class DNSInstance {

cb(
null,
`${origin.protocol}//${
new URL(`${origin.protocol}//${
ip.family === 6 ? `[${ip.address}]` : ip.address
}${port}`
}${port}`)
)
}
}
Expand Down Expand Up @@ -192,6 +192,38 @@ class DNSInstance {
return ip
}

pickFamily (origin, ipFamily) {
const records = this.#records.get(origin.hostname)?.records
if (!records) {
return null
}

const family = records[ipFamily]
if (!family) {
return null
}

if (family.offset == null || family.offset === maxInt) {
family.offset = 0
} else {
family.offset++
}

const position = family.offset % family.ips.length
const ip = family.ips[position] ?? null
if (ip == null) {
return ip
}

if (Date.now() - ip.timestamp > ip.ttl) { // record TTL is already in ms
// We delete expired records
// It is possible that they have different TTL, so we manage them individually
family.ips.splice(position, 1)
}

return ip
}

setRecords (origin, addresses) {
const timestamp = Date.now()
const records = { records: { 4: null, 6: null } }
Expand Down Expand Up @@ -228,10 +260,13 @@ class DNSDispatchHandler extends DecoratorHandler {
#dispatch = null
#origin = null
#controller = null
#newOrigin = null
#firstTry = true

constructor (state, { origin, handler, dispatch }, opts) {
constructor (state, { origin, handler, dispatch, newOrigin }, opts) {
super(handler)
this.#origin = origin
this.#newOrigin = newOrigin
this.#opts = { ...opts }
this.#state = state
this.#dispatch = dispatch
Expand All @@ -242,21 +277,36 @@ class DNSDispatchHandler extends DecoratorHandler {
case 'ETIMEDOUT':
case 'ECONNREFUSED': {
if (this.#state.dualStack) {
// We delete the record and retry
this.#state.runLookup(this.#origin, this.#opts, (err, newOrigin) => {
if (err) {
super.onResponseError(controller, err)
return
}

const dispatchOpts = {
...this.#opts,
origin: newOrigin
}
if (!this.#firstTry) {
super.onResponseError(controller, err)
return
}
this.#firstTry = false

// Pick an ip address from the other family
const otherFamily = this.#newOrigin.hostname[0] === '[' ? 4 : 6
const ip = this.#state.pickFamily(this.#origin, otherFamily)
if (ip == null) {
super.onResponseError(controller, err)
return
}

this.#dispatch(dispatchOpts, this)
})
let port
if (typeof ip.port === 'number') {
port = `:${ip.port}`
} else if (this.#origin.port !== '') {
port = `:${this.#origin.port}`
} else {
port = ''
}

const dispatchOpts = {
...this.#opts,
origin: `${this.#origin.protocol}//${
ip.family === 6 ? `[${ip.address}]` : ip.address
}${port}`
}
this.#dispatch(dispatchOpts, this)
return
}

Expand All @@ -266,7 +316,8 @@ class DNSDispatchHandler extends DecoratorHandler {
}
case 'ENOTFOUND':
this.#state.deleteRecords(this.#origin)
// eslint-disable-next-line no-fallthrough
super.onResponseError(controller, err)
break
default:
super.onResponseError(controller, err)
break
Expand Down Expand Up @@ -356,11 +407,10 @@ module.exports = interceptorOpts => {
return handler.onResponseError(null, err)
}

let dispatchOpts = null
dispatchOpts = {
const dispatchOpts = {
...origDispatchOpts,
servername: origin.hostname, // For SNI on TLS
origin: newOrigin,
origin: newOrigin.origin,
headers: {
host: origin.host,
...origDispatchOpts.headers
Expand All @@ -369,7 +419,10 @@ module.exports = interceptorOpts => {

dispatch(
dispatchOpts,
instance.getHandler({ origin, dispatch, handler }, origDispatchOpts)
instance.getHandler(
{ origin, dispatch, handler, newOrigin },
origDispatchOpts
)
)
})

Expand Down
2 changes: 1 addition & 1 deletion deps/undici/src/lib/llhttp/wasm_build_env.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

> [email protected].1 build:wasm
> [email protected].3 build:wasm
> node build/wasm.js --docker

> docker run --rm --platform=linux/x86_64 --user 1001:128 --mount type=bind,source=/home/runner/work/node/node/deps/undici/src/lib/llhttp,target=/home/node/build/lib/llhttp --mount type=bind,source=/home/runner/work/node/node/deps/undici/src/build,target=/home/node/build/build --mount type=bind,source=/home/runner/work/node/node/deps/undici/src/deps,target=/home/node/build/deps -t ghcr.io/nodejs/wasm-builder@sha256:975f391d907e42a75b8c72eb77c782181e941608687d4d8694c3e9df415a0970 node build/wasm.js
Expand Down
10 changes: 9 additions & 1 deletion deps/undici/src/lib/web/fetch/body.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ const { isErrored, isDisturbed } = require('node:stream')
const { isArrayBuffer } = require('node:util/types')
const { serializeAMimeType } = require('./data-url')
const { multipartFormDataParser } = require('./formdata-parser')
let random

try {
const crypto = require('node:crypto')
random = (max) => crypto.randomInt(0, max)
} catch {
random = (max) => Math.floor(Math.random(max))
}

const textEncoder = new TextEncoder()
function noop () {}
Expand Down Expand Up @@ -110,7 +118,7 @@ function extractBody (object, keepalive = false) {
// Set source to a copy of the bytes held by object.
source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength))
} else if (webidl.is.FormData(object)) {
const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}`
const boundary = `----formdata-undici-0${`${random(1e11)}`.padStart(11, '0')}`
const prefix = `--${boundary}\r\nContent-Disposition: form-data`

/*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */
Expand Down
27 changes: 26 additions & 1 deletion deps/undici/src/lib/web/websocket/connection.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const { uid, states, sentCloseFrameState, emptyBuffer, opcodes } = require('./constants')
const { failWebsocketConnection, parseExtensions, isClosed, isClosing, isEstablished, validateCloseCodeAndReason } = require('./util')
const { parseExtensions, isClosed, isClosing, isEstablished, validateCloseCodeAndReason } = require('./util')
const { channels } = require('../../core/diagnostics')
const { makeRequest } = require('../fetch/request')
const { fetching } = require('../fetch/index')
Expand Down Expand Up @@ -294,7 +294,32 @@ function closeWebSocketConnection (object, code, reason, validate = false) {
}
}

/**
* @param {import('./websocket').Handler} handler
* @param {number} code
* @param {string|undefined} reason
* @returns {void}
*/
function failWebsocketConnection (handler, code, reason) {
// If _The WebSocket Connection is Established_ prior to the point where
// the endpoint is required to _Fail the WebSocket Connection_, the
// endpoint SHOULD send a Close frame with an appropriate status code
// (Section 7.4) before proceeding to _Close the WebSocket Connection_.
if (isEstablished(handler.readyState)) {
closeWebSocketConnection(handler, code, reason, false)
}

handler.controller.abort()

if (handler.socket?.destroyed === false) {
handler.socket.destroy()
}

handler.onFail(code, reason)
}

module.exports = {
establishWebSocketConnection,
failWebsocketConnection,
closeWebSocketConnection
}
2 changes: 1 addition & 1 deletion deps/undici/src/lib/web/websocket/receiver.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ const { channels } = require('../../core/diagnostics')
const {
isValidStatusCode,
isValidOpcode,
failWebsocketConnection,
websocketMessageReceived,
utf8Decode,
isControlFrame,
isTextBinaryFrame,
isContinuationFrame
} = require('./util')
const { failWebsocketConnection } = require('./connection')
const { WebsocketFrameSend } = require('./frame')
const { PerMessageDeflate } = require('./permessage-deflate')

Expand Down
4 changes: 2 additions & 2 deletions deps/undici/src/lib/web/websocket/stream/websocketstream.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
const { createDeferredPromise, environmentSettingsObject } = require('../../fetch/util')
const { states, opcodes, sentCloseFrameState } = require('../constants')
const { webidl } = require('../../fetch/webidl')
const { getURLRecord, isValidSubprotocol, isEstablished, failWebsocketConnection, utf8Decode } = require('../util')
const { establishWebSocketConnection, closeWebSocketConnection } = require('../connection')
const { getURLRecord, isValidSubprotocol, isEstablished, utf8Decode } = require('../util')
const { establishWebSocketConnection, failWebsocketConnection, closeWebSocketConnection } = require('../connection')
const { types } = require('node:util')
const { channels } = require('../../../core/diagnostics')
const { WebsocketFrameSend } = require('../frame')
Expand Down
27 changes: 0 additions & 27 deletions deps/undici/src/lib/web/websocket/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,32 +156,6 @@ function isValidStatusCode (code) {
return code >= 3000 && code <= 4999
}

/**
* @param {import('./websocket').Handler} handler
* @param {number} code
* @param {string|undefined} reason
* @returns {void}
*/
function failWebsocketConnection (handler, code, reason) {
// If _The WebSocket Connection is Established_ prior to the point where
// the endpoint is required to _Fail the WebSocket Connection_, the
// endpoint SHOULD send a Close frame with an appropriate status code
// (Section 7.4) before proceeding to _Close the WebSocket Connection_.
if (isEstablished(handler.readyState)) {
// avoid circular require - performance is not important here
const { closeWebSocketConnection } = require('./connection')
closeWebSocketConnection(handler, code, reason, false)
}

handler.controller.abort()

if (handler.socket?.destroyed === false) {
handler.socket.destroy()
}

handler.onFail(code, reason)
}

/**
* @see https://datatracker.ietf.org/doc/html/rfc6455#section-5.5
* @param {number} opcode
Expand Down Expand Up @@ -350,7 +324,6 @@ module.exports = {
fireEvent,
isValidSubprotocol,
isValidStatusCode,
failWebsocketConnection,
websocketMessageReceived,
utf8Decode,
isControlFrame,
Expand Down
3 changes: 1 addition & 2 deletions deps/undici/src/lib/web/websocket/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ const {
isClosing,
isValidSubprotocol,
fireEvent,
failWebsocketConnection,
utf8Decode,
toArrayBuffer,
getURLRecord
} = require('./util')
const { establishWebSocketConnection, closeWebSocketConnection } = require('./connection')
const { establishWebSocketConnection, closeWebSocketConnection, failWebsocketConnection } = require('./connection')
const { ByteParser } = require('./receiver')
const { kEnumerableProperty } = require('../../core/util')
const { getGlobalDispatcher } = require('../../global')
Expand Down
Loading

0 comments on commit 931319e

Please sign in to comment.