Skip to content

Commit d50871d

Browse files
nodejs-github-botaduh95
authored andcommitted
deps: update undici to 7.27.0
1 parent df6973e commit d50871d

21 files changed

Lines changed: 1116 additions & 845 deletions

deps/undici/src/lib/api/api-request.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class RequestHandler extends AsyncResource {
2121
throw new InvalidArgumentError('invalid callback')
2222
}
2323

24-
if (highWaterMark && (typeof highWaterMark !== 'number' || highWaterMark < 0)) {
24+
if (highWaterMark != null && (!Number.isFinite(highWaterMark) || highWaterMark < 0)) {
2525
throw new InvalidArgumentError('invalid highWaterMark')
2626
}
2727

deps/undici/src/lib/cache/sqlite-cache-store.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ module.exports = class SqliteCacheStore {
216216
SELECT
217217
id
218218
FROM cacheInterceptorV${VERSION}
219-
ORDER BY cachedAt DESC
219+
ORDER BY cachedAt ASC
220220
LIMIT ?
221221
)
222222
`)
@@ -283,7 +283,6 @@ module.exports = class SqliteCacheStore {
283283
existingValue.id
284284
)
285285
} else {
286-
this.#prune()
287286
// New response, let's insert it
288287
this.#insertValueQuery.run(
289288
url,
@@ -299,6 +298,7 @@ module.exports = class SqliteCacheStore {
299298
value.cachedAt,
300299
value.staleAt
301300
)
301+
this.#prune()
302302
}
303303
}
304304

@@ -409,7 +409,7 @@ module.exports = class SqliteCacheStore {
409409
const now = Date.now()
410410
for (const value of values) {
411411
if (now >= value.deleteAt && !canBeExpired) {
412-
return undefined
412+
continue
413413
}
414414

415415
let matches = true

deps/undici/src/lib/core/connect.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ const SessionCache = class WeakSessionCache {
3838
return
3939
}
4040

41+
if (this._sessionCache.has(sessionKey)) {
42+
this._sessionCache.delete(sessionKey)
43+
} else if (this._sessionCache.size >= this._maxCachedSessions) {
44+
for (const [key, ref] of this._sessionCache) {
45+
if (ref.deref() === undefined) {
46+
this._sessionCache.delete(key)
47+
return
48+
}
49+
}
50+
51+
const oldest = this._sessionCache.keys().next()
52+
if (!oldest.done) {
53+
this._sessionCache.delete(oldest.value)
54+
}
55+
}
56+
4157
this._sessionCache.set(sessionKey, new WeakRef(session))
4258
this._sessionRegistry.register(session, sessionKey)
4359
}

deps/undici/src/lib/core/request.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,21 @@ const { headerNameLowerCasedRecord } = require('./constants')
2727
// Verifies that a given path is valid does not contain control chars \x00 to \x20
2828
const invalidPathRegex = /[^\u0021-\u00ff]/
2929

30+
function isValidContentLengthHeaderValue (val) {
31+
if (typeof val !== 'string' || val.length === 0) {
32+
return false
33+
}
34+
35+
for (let i = 0; i < val.length; i++) {
36+
const charCode = val.charCodeAt(i)
37+
if (charCode < 48 || charCode > 57) {
38+
return false
39+
}
40+
}
41+
42+
return true
43+
}
44+
3045
const kHandler = Symbol('handler')
3146

3247
class Request {
@@ -402,10 +417,10 @@ function processHeader (request, key, val) {
402417
if (request.contentLength !== null) {
403418
throw new InvalidArgumentError('duplicate content-length header')
404419
}
405-
request.contentLength = parseInt(val, 10)
406-
if (!Number.isFinite(request.contentLength)) {
420+
if (!isValidContentLengthHeaderValue(val)) {
407421
throw new InvalidArgumentError('invalid content-length header')
408422
}
423+
request.contentLength = parseInt(val, 10)
409424
} else if (request.contentType === null && headerName === 'content-type') {
410425
request.contentType = val
411426
request.headers.push(key, val)

deps/undici/src/lib/core/socks5-client.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const { debuglog } = require('node:util')
77
const { parseAddress } = require('./socks5-utils')
88

99
const debug = debuglog('undici:socks5')
10+
const EMPTY_BUFFER = Buffer.alloc(0)
1011

1112
// SOCKS5 constants
1213
const SOCKS_VERSION = 0x05
@@ -72,7 +73,10 @@ class Socks5Client extends EventEmitter {
7273
this.socket = socket
7374
this.options = options
7475
this.state = STATES.INITIAL
75-
this.buffer = Buffer.alloc(0)
76+
this.buffer = EMPTY_BUFFER
77+
this.onSocketData = this.onData.bind(this)
78+
this.onSocketError = this.onError.bind(this)
79+
this.onSocketClose = this.onClose.bind(this)
7680

7781
// Authentication settings
7882
this.authMethods = []
@@ -82,9 +86,9 @@ class Socks5Client extends EventEmitter {
8286
this.authMethods.push(AUTH_METHODS.NO_AUTH)
8387

8488
// Socket event handlers
85-
this.socket.on('data', this.onData.bind(this))
86-
this.socket.on('error', this.onError.bind(this))
87-
this.socket.on('close', this.onClose.bind(this))
89+
this.socket.on('data', this.onSocketData)
90+
this.socket.on('error', this.onSocketError)
91+
this.socket.on('close', this.onSocketClose)
8892
}
8993

9094
/**
@@ -363,8 +367,9 @@ class Socks5Client extends EventEmitter {
363367

364368
const boundPort = this.buffer.readUInt16BE(offset)
365369

366-
this.buffer = this.buffer.subarray(responseLength)
370+
this.buffer = EMPTY_BUFFER
367371
this.state = STATES.CONNECTED
372+
this.socket.removeListener('data', this.onSocketData)
368373

369374
debug('connected, bound address:', boundAddress, 'port:', boundPort)
370375
this.emit('connected', { address: boundAddress, port: boundPort })

deps/undici/src/lib/core/socks5-utils.js

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,34 +46,29 @@ function parseAddress (address) {
4646
*/
4747
function parseIPv6 (address) {
4848
const buffer = Buffer.alloc(16)
49-
const parts = address.split(':')
50-
let partIndex = 0
51-
let bufferIndex = 0
5249

5350
// Handle compressed notation (::)
5451
const doubleColonIndex = address.indexOf('::')
5552
if (doubleColonIndex !== -1) {
56-
// Count non-empty parts
57-
const nonEmptyParts = parts.filter(p => p.length > 0).length
58-
const skipParts = 8 - nonEmptyParts
59-
60-
for (let i = 0; i < parts.length; i++) {
61-
if (parts[i] === '' && i === doubleColonIndex / 3) {
62-
// Skip empty parts for ::
63-
bufferIndex += skipParts * 2
64-
} else if (parts[i] !== '') {
65-
const value = parseInt(parts[i], 16)
66-
buffer.writeUInt16BE(value, bufferIndex)
67-
bufferIndex += 2
68-
}
53+
const before = address.slice(0, doubleColonIndex)
54+
const after = address.slice(doubleColonIndex + 2)
55+
const beforeParts = before === '' ? [] : before.split(':')
56+
const afterParts = after === '' ? [] : after.split(':')
57+
58+
let bufferIndex = 0
59+
for (const part of beforeParts) {
60+
buffer.writeUInt16BE(parseInt(part, 16), bufferIndex)
61+
bufferIndex += 2
62+
}
63+
bufferIndex = 16 - afterParts.length * 2
64+
for (const part of afterParts) {
65+
buffer.writeUInt16BE(parseInt(part, 16), bufferIndex)
66+
bufferIndex += 2
6967
}
7068
} else {
71-
// No compression, parse normally
72-
for (const part of parts) {
73-
if (part === '') continue
74-
const value = parseInt(part, 16)
75-
buffer.writeUInt16BE(value, partIndex * 2)
76-
partIndex++
69+
const parts = address.split(':')
70+
for (let i = 0; i < parts.length; i++) {
71+
buffer.writeUInt16BE(parseInt(parts[i], 16), i * 2)
7772
}
7873
}
7974

deps/undici/src/lib/dispatcher/client-h1.js

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ function lazyllhttp () {
6969
let useWasmSIMD = process.arch !== 'ppc64'
7070
// The Env Variable UNDICI_NO_WASM_SIMD allows explicitly overriding the default behavior
7171
if (process.env.UNDICI_NO_WASM_SIMD === '1') {
72-
useWasmSIMD = true
73-
} else if (process.env.UNDICI_NO_WASM_SIMD === '0') {
7472
useWasmSIMD = false
73+
} else if (process.env.UNDICI_NO_WASM_SIMD === '0') {
74+
useWasmSIMD = true
7575
}
7676

7777
if (useWasmSIMD) {
@@ -216,6 +216,7 @@ class Parser {
216216
*/
217217
this.socket = socket
218218
this.timeout = null
219+
this.timeoutWeakRef = new WeakRef(this)
219220
this.timeoutValue = null
220221
this.timeoutType = null
221222
this.statusCode = 0
@@ -253,9 +254,9 @@ class Parser {
253254

254255
if (delay) {
255256
if (type & USE_FAST_TIMER) {
256-
this.timeout = timers.setFastTimeout(onParserTimeout, delay, new WeakRef(this))
257+
this.timeout = timers.setFastTimeout(onParserTimeout, delay, this.timeoutWeakRef)
257258
} else {
258-
this.timeout = setTimeout(onParserTimeout, delay, new WeakRef(this))
259+
this.timeout = setTimeout(onParserTimeout, delay, this.timeoutWeakRef)
259260
this.timeout?.unref()
260261
}
261262
}
@@ -349,23 +350,62 @@ class Parser {
349350
this.paused = true
350351
socket.unshift(data)
351352
} else {
352-
const ptr = llhttp.llhttp_get_error_reason(this.ptr)
353-
let message = ''
354-
if (ptr) {
355-
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
356-
message =
357-
'Response does not match the HTTP/1.1 protocol (' +
358-
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
359-
')'
360-
}
361-
throw new HTTPParserError(message, constants.ERROR[ret], data)
353+
throw this.createError(ret, data)
362354
}
363355
}
364356
} catch (err) {
365357
util.destroy(socket, err)
366358
}
367359
}
368360

361+
finish () {
362+
assert(currentParser === null)
363+
assert(this.ptr != null)
364+
assert(!this.paused)
365+
366+
const { llhttp } = this
367+
368+
let ret
369+
370+
try {
371+
currentParser = this
372+
ret = llhttp.llhttp_finish(this.ptr)
373+
} finally {
374+
currentParser = null
375+
}
376+
377+
if (ret === constants.ERROR.OK) {
378+
return null
379+
}
380+
381+
if (ret === constants.ERROR.PAUSED || ret === constants.ERROR.PAUSED_UPGRADE) {
382+
this.paused = true
383+
return null
384+
}
385+
386+
return this.createError(ret, EMPTY_BUF)
387+
}
388+
389+
createError (ret, data) {
390+
const { llhttp, contentLength, bytesRead } = this
391+
392+
if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
393+
return new ResponseContentLengthMismatchError()
394+
}
395+
396+
const ptr = llhttp.llhttp_get_error_reason(this.ptr)
397+
let message = ''
398+
if (ptr) {
399+
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
400+
message =
401+
'Response does not match the HTTP/1.1 protocol (' +
402+
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
403+
')'
404+
}
405+
406+
return new HTTPParserError(message, constants.ERROR[ret], data)
407+
}
408+
369409
destroy () {
370410
assert(currentParser === null)
371411
assert(this.ptr != null)
@@ -870,8 +910,11 @@ function onHttpSocketError (err) {
870910
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
871911
// to the user.
872912
if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
873-
// We treat all incoming data so for as a valid response.
874-
parser.onMessageComplete()
913+
const parserErr = parser.finish()
914+
if (parserErr) {
915+
this[kError] = parserErr
916+
this[kClient][kOnError](parserErr)
917+
}
875918
return
876919
}
877920

@@ -888,8 +931,10 @@ function onHttpSocketEnd () {
888931
const parser = this[kParser]
889932

890933
if (parser.statusCode && !parser.shouldKeepAlive) {
891-
// We treat all incoming data so far as a valid response.
892-
parser.onMessageComplete()
934+
const parserErr = parser.finish()
935+
if (parserErr) {
936+
util.destroy(this, parserErr)
937+
}
893938
return
894939
}
895940

@@ -901,8 +946,7 @@ function onHttpSocketClose () {
901946

902947
if (parser) {
903948
if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
904-
// We treat all incoming data so far as a valid response.
905-
parser.onMessageComplete()
949+
this[kError] = parser.finish() || this[kError]
906950
}
907951

908952
this[kParser].destroy()

deps/undici/src/lib/dispatcher/client.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,13 @@ class Client extends DispatcherBase {
235235
...(typeof autoSelectFamily === 'boolean' ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined),
236236
...connect
237237
})
238-
} else if (socketPath != null) {
238+
} else {
239239
const customConnect = connect
240-
connect = (opts, callback) => customConnect({ ...opts, socketPath }, callback)
240+
connect = (opts, callback) => customConnect({
241+
...opts,
242+
...(socketPath != null ? { socketPath } : null),
243+
...(allowH2 != null ? { allowH2 } : null)
244+
}, callback)
241245
}
242246

243247
this[kUrl] = util.parseOrigin(url)

deps/undici/src/lib/dispatcher/h2c-client.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class H2CClient extends Client {
1515
)
1616
}
1717

18-
const { connect, maxConcurrentStreams, pipelining, ...opts } =
18+
const { maxConcurrentStreams, pipelining, ...opts } =
1919
clientOpts ?? {}
2020
let defaultMaxConcurrentStreams = 100
2121
let defaultPipelining = 100

deps/undici/src/lib/global.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
// We include a version number for the Dispatcher API. In case of breaking changes,
44
// this version number must be increased to avoid conflicts.
5-
const globalDispatcher = Symbol.for('undici.globalDispatcher.1')
5+
const globalDispatcher = Symbol.for('undici.globalDispatcher.2')
6+
const legacyGlobalDispatcher = Symbol.for('undici.globalDispatcher.1')
67
const { InvalidArgumentError } = require('./core/errors')
78
const Agent = require('./dispatcher/agent')
89

@@ -14,12 +15,20 @@ function setGlobalDispatcher (agent) {
1415
if (!agent || typeof agent.dispatch !== 'function') {
1516
throw new InvalidArgumentError('Argument agent must implement Agent')
1617
}
18+
1719
Object.defineProperty(globalThis, globalDispatcher, {
1820
value: agent,
1921
writable: true,
2022
enumerable: false,
2123
configurable: false
2224
})
25+
26+
Object.defineProperty(globalThis, legacyGlobalDispatcher, {
27+
value: agent,
28+
writable: true,
29+
enumerable: false,
30+
configurable: false
31+
})
2332
}
2433

2534
function getGlobalDispatcher () {

0 commit comments

Comments
 (0)