aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/node_modules
diff options
context:
space:
mode:
authorEgor Tensin <egor@tensin.name>2026-06-21 07:49:34 +0200
committerEgor Tensin <egor@tensin.name>2026-06-21 07:49:34 +0200
commit3421d2ed73f43159e8fa04943e13ca9c0f0404d3 (patch)
tree5302ee9ac0ea902e85ec8f600b4f58984576e02b /node_modules
parentMerge pull request #10 from egor-tensin/dependabot/github_actions/actions/che... (diff)
downloadcleanup-path-3421d2ed73f43159e8fa04943e13ca9c0f0404d3.tar.gz
cleanup-path-3421d2ed73f43159e8fa04943e13ca9c0f0404d3.zip
bump dependencies
Diffstat (limited to 'node_modules')
-rw-r--r--node_modules/.package-lock.json6
-rw-r--r--node_modules/undici/docs/docs/api/Client.md1
-rw-r--r--node_modules/undici/lib/dispatcher/agent.js1
-rw-r--r--node_modules/undici/lib/dispatcher/client-h1.js163
-rw-r--r--node_modules/undici/lib/dispatcher/dispatcher-base.js1
-rw-r--r--node_modules/undici/lib/web/cookies/parse.js39
-rw-r--r--node_modules/undici/lib/web/websocket/receiver.js39
-rw-r--r--node_modules/undici/lib/web/websocket/websocket.js5
-rw-r--r--node_modules/undici/package.json2
-rw-r--r--node_modules/undici/types/client.d.ts6
10 files changed, 203 insertions, 60 deletions
diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json
index ae3bf1b..e831dc2 100644
--- a/node_modules/.package-lock.json
+++ b/node_modules/.package-lock.json
@@ -49,9 +49,9 @@
}
},
"node_modules/undici": {
- "version": "6.25.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz",
- "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==",
+ "version": "6.27.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz",
+ "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==",
"license": "MIT",
"engines": {
"node": ">=18.17"
diff --git a/node_modules/undici/docs/docs/api/Client.md b/node_modules/undici/docs/docs/api/Client.md
index fdee5ea..e0d41b4 100644
--- a/node_modules/undici/docs/docs/api/Client.md
+++ b/node_modules/undici/docs/docs/api/Client.md
@@ -27,6 +27,7 @@ Returns: `Client`
* **maxHeaderSize** `number | null` (optional) - Default: `--max-http-header-size` or `16384` - The maximum length of request headers in bytes. Defaults to Node.js' --max-http-header-size or 16KiB.
* **maxResponseSize** `number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable.
* **webSocket** `WebSocketOptions` (optional) - WebSocket-specific configuration options.
+ * **maxFragments** `number` (optional) - Default: `131072` - Maximum number of fragments in a message. Set to 0 to disable the limit.
* **maxPayloadSize** `number` (optional) - Default: `134217728` (128 MB) - Maximum allowed payload size in bytes for WebSocket messages. Applied to uncompressed messages, compressed frame payloads, and decompressed (permessage-deflate) messages. Set to 0 to disable the limit.
* **pipelining** `number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections.
* **connect** `ConnectOptions | Function | null` (optional) - Default: `null`.
diff --git a/node_modules/undici/lib/dispatcher/agent.js b/node_modules/undici/lib/dispatcher/agent.js
index db2f817..90b46fe 100644
--- a/node_modules/undici/lib/dispatcher/agent.js
+++ b/node_modules/undici/lib/dispatcher/agent.js
@@ -24,7 +24,6 @@ function defaultFactory (origin, opts) {
class Agent extends DispatcherBase {
constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {
-
if (typeof factory !== 'function') {
throw new InvalidArgumentError('factory must be a function.')
}
diff --git a/node_modules/undici/lib/dispatcher/client-h1.js b/node_modules/undici/lib/dispatcher/client-h1.js
index 2b8fa05..9455517 100644
--- a/node_modules/undici/lib/dispatcher/client-h1.js
+++ b/node_modules/undici/lib/dispatcher/client-h1.js
@@ -57,6 +57,9 @@ const EMPTY_BUF = Buffer.alloc(0)
const FastBuffer = Buffer[Symbol.species]
const addListener = util.addListener
const removeAllListeners = util.removeAllListeners
+const kIdleSocketValidation = Symbol('kIdleSocketValidation')
+const kIdleSocketValidationTimeout = Symbol('kIdleSocketValidationTimeout')
+const kSocketUsed = Symbol('kSocketUsed')
let extractBody
@@ -279,29 +282,71 @@ class Parser {
const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr
- if (ret === constants.ERROR.PAUSED_UPGRADE) {
- this.onUpgrade(data.slice(offset))
- } else if (ret === constants.ERROR.PAUSED) {
- this.paused = true
- socket.unshift(data.slice(offset))
- } else if (ret !== constants.ERROR.OK) {
- const ptr = llhttp.llhttp_get_error_reason(this.ptr)
- let message = ''
- /* istanbul ignore else: difficult to make a test case for */
- if (ptr) {
- const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
- message =
- 'Response does not match the HTTP/1.1 protocol (' +
- Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
- ')'
+ if (ret !== constants.ERROR.OK) {
+ const body = data.subarray(offset)
+
+ if (ret === constants.ERROR.PAUSED_UPGRADE) {
+ this.onUpgrade(body)
+ } else if (ret === constants.ERROR.PAUSED) {
+ this.paused = true
+ socket.unshift(body)
+ } else {
+ throw this.createError(ret, body)
}
- throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset))
}
} catch (err) {
util.destroy(socket, err)
}
}
+ finish () {
+ assert(currentParser === null)
+ assert(this.ptr != null)
+ assert(!this.paused)
+
+ const { llhttp } = this
+
+ let ret
+
+ try {
+ currentParser = this
+ ret = llhttp.llhttp_finish(this.ptr)
+ } finally {
+ currentParser = null
+ }
+
+ if (ret === constants.ERROR.OK) {
+ return null
+ }
+
+ if (ret === constants.ERROR.PAUSED || ret === constants.ERROR.PAUSED_UPGRADE) {
+ this.paused = true
+ return null
+ }
+
+ return this.createError(ret, EMPTY_BUF)
+ }
+
+ createError (ret, data) {
+ const { llhttp, contentLength, bytesRead } = this
+
+ if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
+ return new ResponseContentLengthMismatchError()
+ }
+
+ const ptr = llhttp.llhttp_get_error_reason(this.ptr)
+ let message = ''
+ if (ptr) {
+ const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
+ message =
+ 'Response does not match the HTTP/1.1 protocol (' +
+ Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
+ ')'
+ }
+
+ return new HTTPParserError(message, constants.ERROR[ret], data)
+ }
+
destroy () {
assert(this.ptr != null)
assert(currentParser == null)
@@ -329,6 +374,11 @@ class Parser {
return -1
}
+ if (client[kRunning] === 0) {
+ util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
+ return -1
+ }
+
const request = client[kQueue][client[kRunningIdx]]
if (!request) {
return -1
@@ -432,6 +482,11 @@ class Parser {
return -1
}
+ if (client[kRunning] === 0) {
+ util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
+ return -1
+ }
+
const request = client[kQueue][client[kRunningIdx]]
/* istanbul ignore next: difficult to make a test case for */
@@ -605,6 +660,7 @@ class Parser {
request.onComplete(headers)
client[kQueue][client[kRunningIdx]++] = null
+ socket[kSocketUsed] = true
if (socket[kWriting]) {
assert(client[kRunning] === 0)
@@ -663,6 +719,9 @@ async function connectH1 (client, socket) {
socket[kWriting] = false
socket[kReset] = false
socket[kBlocking] = false
+ socket[kIdleSocketValidation] = 0
+ socket[kIdleSocketValidationTimeout] = null
+ socket[kSocketUsed] = false
socket[kParser] = new Parser(client, socket, llhttpInstance)
addListener(socket, 'error', function (err) {
@@ -673,8 +732,11 @@ async function connectH1 (client, socket) {
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
// to the user.
if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
- // We treat all incoming data so for as a valid response.
- parser.onMessageComplete()
+ const parserErr = parser.finish()
+ if (parserErr) {
+ this[kError] = parserErr
+ this[kClient][kOnError](parserErr)
+ }
return
}
@@ -693,8 +755,10 @@ async function connectH1 (client, socket) {
const parser = this[kParser]
if (parser.statusCode && !parser.shouldKeepAlive) {
- // We treat all incoming data so far as a valid response.
- parser.onMessageComplete()
+ const parserErr = parser.finish()
+ if (parserErr) {
+ util.destroy(this, parserErr)
+ }
return
}
@@ -704,10 +768,11 @@ async function connectH1 (client, socket) {
const client = this[kClient]
const parser = this[kParser]
+ clearIdleSocketValidation(this)
+
if (parser) {
if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
- // We treat all incoming data so far as a valid response.
- parser.onMessageComplete()
+ this[kError] = parser.finish() || this[kError]
}
this[kParser].destroy()
@@ -770,7 +835,7 @@ async function connectH1 (client, socket) {
return socket.destroyed
},
busy (request) {
- if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
+ if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) {
return true
}
@@ -808,6 +873,31 @@ async function connectH1 (client, socket) {
}
}
+function clearIdleSocketValidation (socket) {
+ if (socket[kIdleSocketValidationTimeout]) {
+ clearTimeout(socket[kIdleSocketValidationTimeout])
+ socket[kIdleSocketValidationTimeout] = null
+ }
+
+ socket[kIdleSocketValidation] = 0
+}
+
+function scheduleIdleSocketValidation (client, socket) {
+ socket[kIdleSocketValidation] = 1
+ socket[kIdleSocketValidationTimeout] = setTimeout(() => {
+ socket[kIdleSocketValidationTimeout] = null
+ socket[kIdleSocketValidation] = 2
+
+ if (client[kSocket] === socket && !socket.destroyed) {
+ client[kResume]()
+ }
+ }, 0)
+ socket[kIdleSocketValidationTimeout].unref?.()
+}
+
+/**
+ * @param {import('./client.js')} client
+ */
function resumeH1 (client) {
const socket = client[kSocket]
@@ -822,6 +912,32 @@ function resumeH1 (client) {
socket[kNoRef] = false
}
+ if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) {
+ if (socket[kIdleSocketValidation] === 0) {
+ scheduleIdleSocketValidation(client, socket)
+ socket[kParser].readMore()
+ if (socket.destroyed) {
+ return
+ }
+ return
+ }
+
+ if (socket[kIdleSocketValidation] === 1) {
+ socket[kParser].readMore()
+ if (socket.destroyed) {
+ return
+ }
+ return
+ }
+ }
+
+ if (client[kRunning] === 0) {
+ socket[kParser].readMore()
+ if (socket.destroyed) {
+ return
+ }
+ }
+
if (client[kSize] === 0) {
if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE)
@@ -915,6 +1031,7 @@ function writeH1 (client, request) {
}
const socket = client[kSocket]
+ clearIdleSocketValidation(socket)
const abort = (err) => {
if (request.aborted || request.completed) {
diff --git a/node_modules/undici/lib/dispatcher/dispatcher-base.js b/node_modules/undici/lib/dispatcher/dispatcher-base.js
index c999b2c..371a3ea 100644
--- a/node_modules/undici/lib/dispatcher/dispatcher-base.js
+++ b/node_modules/undici/lib/dispatcher/dispatcher-base.js
@@ -26,6 +26,7 @@ class DispatcherBase extends Dispatcher {
get webSocketOptions () {
return {
+ maxFragments: this[kWebSocketOptions].maxFragments ?? 131072,
maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024
}
}
diff --git a/node_modules/undici/lib/web/cookies/parse.js b/node_modules/undici/lib/web/cookies/parse.js
index 3c48c26..b3c25fb 100644
--- a/node_modules/undici/lib/web/cookies/parse.js
+++ b/node_modules/undici/lib/web/cookies/parse.js
@@ -275,32 +275,25 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
// If the attribute-name case-insensitively matches the string
// "SameSite", the user agent MUST process the cookie-av as follows:
- // 1. Let enforcement be "Default".
- let enforcement = 'Default'
-
const attributeValueLowercase = attributeValue.toLowerCase()
- // 2. If cookie-av's attribute-value is a case-insensitive match for
- // "None", set enforcement to "None".
- if (attributeValueLowercase.includes('none')) {
- enforcement = 'None'
- }
- // 3. If cookie-av's attribute-value is a case-insensitive match for
- // "Strict", set enforcement to "Strict".
- if (attributeValueLowercase.includes('strict')) {
- enforcement = 'Strict'
+ // 1. If cookie-av's attribute-value is a case-insensitive match for
+ // "None", append an attribute to the cookie-attribute-list with an
+ // attribute-name of "SameSite" and an attribute-value of "None".
+ if (attributeValueLowercase === 'none') {
+ cookieAttributeList.sameSite = 'None'
+ } else if (attributeValueLowercase === 'strict') {
+ // 2. If cookie-av's attribute-value is a case-insensitive match for
+ // "Strict", append an attribute to the cookie-attribute-list with
+ // an attribute-name of "SameSite" and an attribute-value of
+ // "Strict".
+ cookieAttributeList.sameSite = 'Strict'
+ } else if (attributeValueLowercase === 'lax') {
+ // 3. If cookie-av's attribute-value is a case-insensitive match for
+ // "Lax", append an attribute to the cookie-attribute-list with an
+ // attribute-name of "SameSite" and an attribute-value of "Lax".
+ cookieAttributeList.sameSite = 'Lax'
}
-
- // 4. If cookie-av's attribute-value is a case-insensitive match for
- // "Lax", set enforcement to "Lax".
- if (attributeValueLowercase.includes('lax')) {
- enforcement = 'Lax'
- }
-
- // 5. Append an attribute to the cookie-attribute-list with an
- // attribute-name of "SameSite" and an attribute-value of
- // enforcement.
- cookieAttributeList.sameSite = enforcement
} else {
cookieAttributeList.unparsed ??= []
diff --git a/node_modules/undici/lib/web/websocket/receiver.js b/node_modules/undici/lib/web/websocket/receiver.js
index 53e427e..a7dea7f 100644
--- a/node_modules/undici/lib/web/websocket/receiver.js
+++ b/node_modules/undici/lib/web/websocket/receiver.js
@@ -20,6 +20,11 @@ const { closeWebSocketConnection } = require('./connection')
const { PerMessageDeflate } = require('./permessage-deflate')
const { MessageSizeExceededError } = require('../../core/errors')
+function failWebsocketConnectionWithCode (ws, code, reason) {
+ closeWebSocketConnection(ws, code, reason, Buffer.byteLength(reason))
+ failWebsocketConnection(ws, reason)
+}
+
// This code was influenced by ws released under the MIT license.
// Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
// Copyright (c) 2013 Arnout Kazemier and contributors
@@ -40,18 +45,22 @@ class ByteParser extends Writable {
#extensions
/** @type {number} */
+ #maxFragments
+
+ /** @type {number} */
#maxPayloadSize
/**
* @param {import('./websocket').WebSocket} ws
* @param {Map<string, string>|null} extensions
- * @param {{ maxPayloadSize?: number }} [options]
+ * @param {{ maxFragments?: number, maxPayloadSize?: number }} [options]
*/
constructor (ws, extensions, options = {}) {
super()
this.ws = ws
this.#extensions = extensions == null ? new Map() : extensions
+ this.#maxFragments = options.maxFragments ?? 0
this.#maxPayloadSize = options.maxPayloadSize ?? 0
if (this.#extensions.has('permessage-deflate')) {
@@ -75,9 +84,9 @@ class ByteParser extends Writable {
if (
this.#maxPayloadSize > 0 &&
!isControlFrame(this.#info.opcode) &&
- this.#info.payloadLength > this.#maxPayloadSize
+ this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize
) {
- failWebsocketConnection(this.ws, 'Payload size exceeds maximum allowed size')
+ failWebsocketConnectionWithCode(this.ws, 1009, 'Payload size exceeds maximum allowed size')
return false
}
@@ -242,10 +251,12 @@ class ByteParser extends Writable {
this.#state = parserStates.INFO
} else {
if (!this.#info.compressed) {
- this.writeFragments(body)
+ if (!this.writeFragments(body)) {
+ return
+ }
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
- failWebsocketConnection(this.ws, new MessageSizeExceededError().message)
+ failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
return
}
@@ -264,14 +275,17 @@ class ByteParser extends Writable {
this.#info.fin,
(error, data) => {
if (error) {
- failWebsocketConnection(this.ws, error.message)
+ const code = error instanceof MessageSizeExceededError ? 1009 : 1007
+ failWebsocketConnectionWithCode(this.ws, code, error.message)
return
}
- this.writeFragments(data)
+ if (!this.writeFragments(data)) {
+ return
+ }
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
- failWebsocketConnection(this.ws, new MessageSizeExceededError().message)
+ failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
return
}
@@ -341,8 +355,17 @@ class ByteParser extends Writable {
}
writeFragments (fragment) {
+ if (
+ this.#maxFragments > 0 &&
+ this.#fragments.length === this.#maxFragments
+ ) {
+ failWebsocketConnectionWithCode(this.ws, 1008, 'Too many message fragments')
+ return false
+ }
+
this.#fragmentsBytes += fragment.length
this.#fragments.push(fragment)
+ return true
}
consumeFragments () {
diff --git a/node_modules/undici/lib/web/websocket/websocket.js b/node_modules/undici/lib/web/websocket/websocket.js
index ccedb79..80991e9 100644
--- a/node_modules/undici/lib/web/websocket/websocket.js
+++ b/node_modules/undici/lib/web/websocket/websocket.js
@@ -435,9 +435,12 @@ class WebSocket extends EventTarget {
// once this happens, the connection is open
this[kResponse] = response
- const maxPayloadSize = this[kController]?.dispatcher?.webSocketOptions?.maxPayloadSize
+ const webSocketOptions = this[kController]?.dispatcher?.webSocketOptions
+ const maxFragments = webSocketOptions?.maxFragments
+ const maxPayloadSize = webSocketOptions?.maxPayloadSize
const parser = new ByteParser(this, parsedExtensions, {
+ maxFragments,
maxPayloadSize
})
parser.on('drain', onParserDrain)
diff --git a/node_modules/undici/package.json b/node_modules/undici/package.json
index 46cb9a8..3c2001f 100644
--- a/node_modules/undici/package.json
+++ b/node_modules/undici/package.json
@@ -1,6 +1,6 @@
{
"name": "undici",
- "version": "6.25.0",
+ "version": "6.27.0",
"description": "An HTTP/1.1 client, written from scratch for Node.js",
"homepage": "https://undici.nodejs.org",
"bugs": {
diff --git a/node_modules/undici/types/client.d.ts b/node_modules/undici/types/client.d.ts
index 22833ae..c292b9b 100644
--- a/node_modules/undici/types/client.d.ts
+++ b/node_modules/undici/types/client.d.ts
@@ -107,6 +107,12 @@ export declare namespace Client {
}
export interface WebSocketOptions {
/**
+ * Maximum number of fragments in a message.
+ * Set to 0 to disable the limit.
+ * @default 131072
+ */
+ maxFragments?: number;
+ /**
* Maximum allowed payload size in bytes for WebSocket messages.
* Applied to uncompressed messages, compressed frame payloads, and decompressed (permessage-deflate) messages.
* Set to 0 to disable the limit.