mirror of
https://github.com/dawidd6/action-send-mail.git
synced 2026-10-31 01:38:34 +07:00
node_modules: update (#358)
Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com>
This commit is contained in:
1 parent
0d58990203
commit
b6b2177ec4
13 files changed
+154
-34
No files matched your search
+3
-3
@@ -128,9 +128,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.29.0",
|
"version": "6.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.29.1.tgz",
|
||||||
"integrity": "sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==",
|
"integrity": "sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.17"
|
"node": ">=18.17"
|
||||||
|
|||||||
+2
@@ -29,6 +29,8 @@ Returns: `Client`
|
|||||||
* **webSocket** `WebSocketOptions` (optional) - WebSocket-specific configuration options.
|
* **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.
|
* **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.
|
* **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.
|
||||||
|
* **eventSource** `EventSourceOptions` (optional) - EventSource-specific configuration options.
|
||||||
|
* **maxEventSize** `number` (optional) - The maximum total bytes of data and metadata field values retained for a pending EventSource event. Each unfinished line is separately limited to this value plus seven syntax bytes. The number of `data:` lines per event and input chunks buffered for an unfinished line are each limited to `min(131072, max(1024, floor(maxEventSize / 128)))` to bound object overhead. Set to `0` to disable these limits. Default: `buffer.kStringMaxLength`.
|
||||||
* **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.
|
* **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`.
|
* **connect** `ConnectOptions | Function | null` (optional) - Default: `null`.
|
||||||
* **strictContentLength** `Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.
|
* **strictContentLength** `Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.
|
||||||
|
|||||||
+6
-2
@@ -23,7 +23,7 @@ function defaultFactory (origin, opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Agent extends DispatcherBase {
|
class Agent extends DispatcherBase {
|
||||||
constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {
|
constructor ({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) {
|
||||||
if (typeof factory !== 'function') {
|
if (typeof factory !== 'function') {
|
||||||
throw new InvalidArgumentError('factory must be a function.')
|
throw new InvalidArgumentError('factory must be a function.')
|
||||||
}
|
}
|
||||||
@@ -42,11 +42,15 @@ class Agent extends DispatcherBase {
|
|||||||
connect = { ...connect }
|
connect = { ...connect }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tls && typeof tls !== 'function') {
|
||||||
|
tls = { ...tls }
|
||||||
|
}
|
||||||
|
|
||||||
this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent)
|
this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent)
|
||||||
? options.interceptors.Agent
|
? options.interceptors.Agent
|
||||||
: [createRedirectInterceptor({ maxRedirections })]
|
: [createRedirectInterceptor({ maxRedirections })]
|
||||||
|
|
||||||
this[kOptions] = { ...util.deepClone(options), connect }
|
this[kOptions] = { ...util.deepClone(options), connect, tls }
|
||||||
this[kOptions].interceptors = options.interceptors
|
this[kOptions].interceptors = options.interceptors
|
||||||
? { ...options.interceptors }
|
? { ...options.interceptors }
|
||||||
: undefined
|
: undefined
|
||||||
|
|||||||
-2
@@ -727,8 +727,6 @@ async function connectH1 (client, socket) {
|
|||||||
socket[kParser] = new Parser(client, socket, llhttpInstance)
|
socket[kParser] = new Parser(client, socket, llhttpInstance)
|
||||||
|
|
||||||
addListener(socket, 'error', function (err) {
|
addListener(socket, 'error', function (err) {
|
||||||
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
|
||||||
|
|
||||||
const parser = this[kParser]
|
const parser = this[kParser]
|
||||||
|
|
||||||
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
|
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
|
||||||
|
|||||||
-4
@@ -136,8 +136,6 @@ async function connectH2 (client, socket) {
|
|||||||
socket[kHTTP2Session] = session
|
socket[kHTTP2Session] = session
|
||||||
|
|
||||||
util.addListener(socket, 'error', function (err) {
|
util.addListener(socket, 'error', function (err) {
|
||||||
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
|
||||||
|
|
||||||
this[kError] = err
|
this[kError] = err
|
||||||
|
|
||||||
this[kClient][kOnError](err)
|
this[kClient][kOnError](err)
|
||||||
@@ -211,8 +209,6 @@ function resumeH2 (client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onHttp2SessionError (err) {
|
function onHttp2SessionError (err) {
|
||||||
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
|
||||||
|
|
||||||
this[kSocket][kError] = err
|
this[kSocket][kError] = err
|
||||||
this[kClient][kOnError](err)
|
this[kClient][kOnError](err)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -107,9 +107,10 @@ class Client extends DispatcherBase {
|
|||||||
// h2
|
// h2
|
||||||
maxConcurrentStreams,
|
maxConcurrentStreams,
|
||||||
allowH2,
|
allowH2,
|
||||||
webSocket
|
webSocket,
|
||||||
|
eventSource
|
||||||
} = {}) {
|
} = {}) {
|
||||||
super({ webSocket })
|
super({ webSocket, eventSource })
|
||||||
|
|
||||||
if (keepAlive !== undefined) {
|
if (keepAlive !== undefined) {
|
||||||
throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead')
|
throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead')
|
||||||
|
|||||||
+9
@@ -1,5 +1,6 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
|
const buffer = require('node:buffer')
|
||||||
const Dispatcher = require('./dispatcher')
|
const Dispatcher = require('./dispatcher')
|
||||||
const {
|
const {
|
||||||
ClientDestroyedError,
|
ClientDestroyedError,
|
||||||
@@ -12,6 +13,7 @@ const kOnDestroyed = Symbol('onDestroyed')
|
|||||||
const kOnClosed = Symbol('onClosed')
|
const kOnClosed = Symbol('onClosed')
|
||||||
const kInterceptedDispatch = Symbol('Intercepted Dispatch')
|
const kInterceptedDispatch = Symbol('Intercepted Dispatch')
|
||||||
const kWebSocketOptions = Symbol('webSocketOptions')
|
const kWebSocketOptions = Symbol('webSocketOptions')
|
||||||
|
const kEventSourceOptions = Symbol('eventSourceOptions')
|
||||||
|
|
||||||
class DispatcherBase extends Dispatcher {
|
class DispatcherBase extends Dispatcher {
|
||||||
constructor (opts) {
|
constructor (opts) {
|
||||||
@@ -22,6 +24,7 @@ class DispatcherBase extends Dispatcher {
|
|||||||
this[kClosed] = false
|
this[kClosed] = false
|
||||||
this[kOnClosed] = []
|
this[kOnClosed] = []
|
||||||
this[kWebSocketOptions] = opts?.webSocket ?? {}
|
this[kWebSocketOptions] = opts?.webSocket ?? {}
|
||||||
|
this[kEventSourceOptions] = opts?.eventSource ?? {}
|
||||||
}
|
}
|
||||||
|
|
||||||
get webSocketOptions () {
|
get webSocketOptions () {
|
||||||
@@ -31,6 +34,12 @@ class DispatcherBase extends Dispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get eventSourceOptions () {
|
||||||
|
return {
|
||||||
|
maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get destroyed () {
|
get destroyed () {
|
||||||
return this[kDestroyed]
|
return this[kDestroyed]
|
||||||
}
|
}
|
||||||
|
|||||||
+91
-10
@@ -1,4 +1,5 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
const buffer = require('node:buffer')
|
||||||
const { Transform } = require('node:stream')
|
const { Transform } = require('node:stream')
|
||||||
const { isASCIINumber, isValidLastEventId } = require('./util')
|
const { isASCIINumber, isValidLastEventId } = require('./util')
|
||||||
|
|
||||||
@@ -23,11 +24,19 @@ const COLON = 0x3A
|
|||||||
*/
|
*/
|
||||||
const SPACE = 0x20
|
const SPACE = 0x20
|
||||||
|
|
||||||
|
const defaultMaxEventSize = buffer.kStringMaxLength
|
||||||
|
|
||||||
const DATA = Buffer.from('data')
|
const DATA = Buffer.from('data')
|
||||||
const EVENT = Buffer.from('event')
|
const EVENT = Buffer.from('event')
|
||||||
const ID = Buffer.from('id')
|
const ID = Buffer.from('id')
|
||||||
const RETRY = Buffer.from('retry')
|
const RETRY = Buffer.from('retry')
|
||||||
|
|
||||||
|
// Each data field creates a string node, and each unconsumed input chunk keeps
|
||||||
|
// a Buffer wrapper. The absolute ceiling protects the large default byte limit.
|
||||||
|
const minParserItems = 1024
|
||||||
|
const maxParserItems = 131072
|
||||||
|
const bytesPerParserItem = 128
|
||||||
|
|
||||||
function isASCIINumberBytes (buffer, start) {
|
function isASCIINumberBytes (buffer, start) {
|
||||||
if (start >= buffer.length) {
|
if (start >= buffer.length) {
|
||||||
return false
|
return false
|
||||||
@@ -66,6 +75,12 @@ function isFieldName (line, length, field) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createMaxEventSizeExceededError () {
|
||||||
|
const error = new Error('EventSource message size exceeded')
|
||||||
|
error.aborted = false
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {object} EventSourceStreamEvent
|
* @typedef {object} EventSourceStreamEvent
|
||||||
* @type {object}
|
* @type {object}
|
||||||
@@ -114,6 +129,13 @@ class EventSourceStream extends Transform {
|
|||||||
pos = 0
|
pos = 0
|
||||||
lineChunkIndex = 0
|
lineChunkIndex = 0
|
||||||
linePos = 0
|
linePos = 0
|
||||||
|
lineLength = 0
|
||||||
|
eventSize = 0
|
||||||
|
eventFieldSizes = { data: 0, event: 0, id: 0, retry: 0 }
|
||||||
|
dataLineCount = 0
|
||||||
|
maxEventSize
|
||||||
|
maxDataLines
|
||||||
|
maxBufferedChunks
|
||||||
|
|
||||||
event = {
|
event = {
|
||||||
data: undefined,
|
data: undefined,
|
||||||
@@ -124,6 +146,7 @@ class EventSourceStream extends Transform {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {object} options
|
* @param {object} options
|
||||||
|
* @param {number} [options.maxEventSize]
|
||||||
* @param {eventSourceSettings} options.eventSourceSettings
|
* @param {eventSourceSettings} options.eventSourceSettings
|
||||||
* @param {Function} [options.push]
|
* @param {Function} [options.push]
|
||||||
*/
|
*/
|
||||||
@@ -135,6 +158,12 @@ class EventSourceStream extends Transform {
|
|||||||
super(options)
|
super(options)
|
||||||
|
|
||||||
this.state = options.eventSourceSettings || {}
|
this.state = options.eventSourceSettings || {}
|
||||||
|
this.maxEventSize = options.maxEventSize ?? defaultMaxEventSize
|
||||||
|
const parserItemLimit = this.maxEventSize > 0
|
||||||
|
? Math.min(maxParserItems, Math.max(minParserItems, Math.floor(this.maxEventSize / bytesPerParserItem)))
|
||||||
|
: 0
|
||||||
|
this.maxDataLines = parserItemLimit
|
||||||
|
this.maxBufferedChunks = parserItemLimit
|
||||||
if (options.push) {
|
if (options.push) {
|
||||||
this.push = options.push
|
this.push = options.push
|
||||||
}
|
}
|
||||||
@@ -152,6 +181,14 @@ class EventSourceStream extends Transform {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A leading line ending can immediately release the currently buffered
|
||||||
|
// line, even when it uses the final allowed chunk slot.
|
||||||
|
if (this.maxEventSize > 0 &&
|
||||||
|
this.chunks.length >= this.maxBufferedChunks &&
|
||||||
|
chunk[0] !== LF && chunk[0] !== CR) {
|
||||||
|
callback(createMaxEventSizeExceededError())
|
||||||
|
return
|
||||||
|
}
|
||||||
this.chunks.push(chunk)
|
this.chunks.push(chunk)
|
||||||
|
|
||||||
// Strip leading byte-order-mark if we opened the stream and started
|
// Strip leading byte-order-mark if we opened the stream and started
|
||||||
@@ -230,7 +267,12 @@ class EventSourceStream extends Transform {
|
|||||||
|
|
||||||
// In any case, we can process the line as we reached an
|
// In any case, we can process the line as we reached an
|
||||||
// end-of-line character
|
// end-of-line character
|
||||||
this.parseLine(this.readLine(), this.event)
|
try {
|
||||||
|
this.parseLine(this.readLine(), this.event)
|
||||||
|
} catch (error) {
|
||||||
|
callback(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
this.consumeCurrentByte()
|
this.consumeCurrentByte()
|
||||||
// A line was processed and this could be the end of the event. We need
|
// A line was processed and this could be the end of the event. We need
|
||||||
// to check if the next line is empty to determine if the event is
|
// to check if the next line is empty to determine if the event is
|
||||||
@@ -239,15 +281,28 @@ class EventSourceStream extends Transform {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// readLine() is only called after CR or LF. Reject an unfinished line
|
||||||
|
// before it can retain an unbounded number of decoded chunks. The seven
|
||||||
|
// extra bytes allow the longest field prefix ("event: " or "retry: ").
|
||||||
|
if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) {
|
||||||
|
callback(createMaxEventSizeExceededError())
|
||||||
|
return
|
||||||
|
}
|
||||||
this.advanceCursor()
|
this.advanceCursor()
|
||||||
}
|
}
|
||||||
|
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_destroy (error, callback) {
|
||||||
|
this.chunks.length = 0
|
||||||
|
this.clearEvent()
|
||||||
|
super._destroy(error, callback)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Buffer} line
|
* @param {Buffer} line
|
||||||
* @param {EventStreamEvent} event
|
* @param {EventSourceStreamEvent} event
|
||||||
*/
|
*/
|
||||||
parseLine (line, event) {
|
parseLine (line, event) {
|
||||||
// If the line is empty (a blank line)
|
// If the line is empty (a blank line)
|
||||||
@@ -281,6 +336,13 @@ class EventSourceStream extends Transform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isFieldName(line, fieldLength, DATA)) {
|
if (isFieldName(line, fieldLength, DATA)) {
|
||||||
|
if (this.maxEventSize > 0 && this.dataLineCount >= this.maxDataLines) {
|
||||||
|
throw createMaxEventSizeExceededError()
|
||||||
|
}
|
||||||
|
const valueBytes = line.length - valueStart
|
||||||
|
const dataSize = this.eventFieldSizes.data + (event.data === undefined ? 0 : 1) + valueBytes
|
||||||
|
this.setEventFieldSize('data', dataSize)
|
||||||
|
|
||||||
const value = line.toString('utf8', valueStart)
|
const value = line.toString('utf8', valueStart)
|
||||||
|
|
||||||
if (event.data === undefined) {
|
if (event.data === undefined) {
|
||||||
@@ -288,11 +350,13 @@ class EventSourceStream extends Transform {
|
|||||||
} else {
|
} else {
|
||||||
event.data += `\n${value}`
|
event.data += `\n${value}`
|
||||||
}
|
}
|
||||||
|
this.dataLineCount++
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFieldName(line, fieldLength, RETRY)) {
|
if (isFieldName(line, fieldLength, RETRY)) {
|
||||||
if (isASCIINumberBytes(line, valueStart)) {
|
if (isASCIINumberBytes(line, valueStart)) {
|
||||||
|
this.setEventFieldSize('retry', line.length - valueStart)
|
||||||
event.retry = line.toString('utf8', valueStart)
|
event.retry = line.toString('utf8', valueStart)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -300,20 +364,29 @@ class EventSourceStream extends Transform {
|
|||||||
|
|
||||||
if (isFieldName(line, fieldLength, ID)) {
|
if (isFieldName(line, fieldLength, ID)) {
|
||||||
if (isValidLastEventIdBytes(line, valueStart)) {
|
if (isValidLastEventIdBytes(line, valueStart)) {
|
||||||
|
this.setEventFieldSize('id', line.length - valueStart)
|
||||||
event.id = line.toString('utf8', valueStart)
|
event.id = line.toString('utf8', valueStart)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFieldName(line, fieldLength, EVENT)) {
|
if (isFieldName(line, fieldLength, EVENT)) {
|
||||||
const value = line.toString('utf8', valueStart)
|
if (valueStart < line.length) {
|
||||||
|
this.setEventFieldSize('event', line.length - valueStart)
|
||||||
if (value.length > 0) {
|
event.event = line.toString('utf8', valueStart)
|
||||||
event.event = value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setEventFieldSize (field, size) {
|
||||||
|
const eventSize = this.eventSize - this.eventFieldSizes[field] + size
|
||||||
|
if (this.maxEventSize > 0 && eventSize > this.maxEventSize) {
|
||||||
|
throw createMaxEventSizeExceededError()
|
||||||
|
}
|
||||||
|
this.eventSize = eventSize
|
||||||
|
this.eventFieldSizes[field] = size
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {EventSourceStreamEvent} event
|
* @param {EventSourceStreamEvent} event
|
||||||
*/
|
*/
|
||||||
@@ -344,6 +417,12 @@ class EventSourceStream extends Transform {
|
|||||||
this.event.event = undefined
|
this.event.event = undefined
|
||||||
this.event.id = undefined
|
this.event.id = undefined
|
||||||
this.event.retry = undefined
|
this.event.retry = undefined
|
||||||
|
this.eventSize = 0
|
||||||
|
this.dataLineCount = 0
|
||||||
|
this.eventFieldSizes.data = 0
|
||||||
|
this.eventFieldSizes.event = 0
|
||||||
|
this.eventFieldSizes.id = 0
|
||||||
|
this.eventFieldSizes.retry = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPendingEvent () {
|
hasPendingEvent () {
|
||||||
@@ -379,14 +458,16 @@ class EventSourceStream extends Transform {
|
|||||||
syncLineStartToCursor () {
|
syncLineStartToCursor () {
|
||||||
this.lineChunkIndex = this.chunkIndex
|
this.lineChunkIndex = this.chunkIndex
|
||||||
this.linePos = this.pos
|
this.linePos = this.pos
|
||||||
|
this.lineLength = 0
|
||||||
this.dropConsumedChunks()
|
this.dropConsumedChunks()
|
||||||
}
|
}
|
||||||
|
|
||||||
dropConsumedChunks () {
|
dropConsumedChunks () {
|
||||||
while (this.lineChunkIndex > 0) {
|
if (this.lineChunkIndex > 0) {
|
||||||
this.chunks.shift()
|
const consumed = this.lineChunkIndex
|
||||||
this.lineChunkIndex--
|
this.chunks.splice(0, consumed)
|
||||||
this.chunkIndex--
|
this.lineChunkIndex = 0
|
||||||
|
this.chunkIndex -= consumed
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.chunkIndex === this.chunks.length) {
|
if (this.chunkIndex === this.chunks.length) {
|
||||||
|
|||||||
+4
-1
@@ -11,6 +11,7 @@ const { isNetworkError } = require('../fetch/response')
|
|||||||
const { delay } = require('./util')
|
const { delay } = require('./util')
|
||||||
const { kEnumerableProperty } = require('../../core/util')
|
const { kEnumerableProperty } = require('../../core/util')
|
||||||
const { environmentSettingsObject } = require('../fetch/util')
|
const { environmentSettingsObject } = require('../fetch/util')
|
||||||
|
const { getGlobalDispatcher } = require('../../global')
|
||||||
|
|
||||||
let experimentalWarned = false
|
let experimentalWarned = false
|
||||||
|
|
||||||
@@ -292,6 +293,7 @@ class EventSource extends EventTarget {
|
|||||||
|
|
||||||
const eventSourceStream = new EventSourceStream({
|
const eventSourceStream = new EventSourceStream({
|
||||||
eventSourceSettings: this.#state,
|
eventSourceSettings: this.#state,
|
||||||
|
maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize,
|
||||||
push: (event) => {
|
push: (event) => {
|
||||||
this.dispatchEvent(createFastMessageEvent(
|
this.dispatchEvent(createFastMessageEvent(
|
||||||
event.type,
|
event.type,
|
||||||
@@ -470,7 +472,8 @@ webidl.converters.EventSourceInitDict = webidl.dictionaryConverter([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'dispatcher', // undici only
|
key: 'dispatcher', // undici only
|
||||||
converter: webidl.converters.any
|
converter: webidl.converters.any,
|
||||||
|
defaultValue: () => getGlobalDispatcher()
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
+7
-9
@@ -1950,8 +1950,10 @@ async function httpNetworkFetch (
|
|||||||
// 19. Run these steps in parallel:
|
// 19. Run these steps in parallel:
|
||||||
|
|
||||||
// 1. Run these steps, but abort when fetchParams is canceled:
|
// 1. Run these steps, but abort when fetchParams is canceled:
|
||||||
fetchParams.controller.onAborted = onAborted
|
if (!fetchParams.controller.resume) {
|
||||||
fetchParams.controller.on('terminated', onAborted)
|
fetchParams.controller.on('terminated', onAborted)
|
||||||
|
}
|
||||||
|
|
||||||
fetchParams.controller.resume = async () => {
|
fetchParams.controller.resume = async () => {
|
||||||
// 1. While true
|
// 1. While true
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -2120,8 +2122,6 @@ async function httpNetworkFetch (
|
|||||||
}
|
}
|
||||||
location = headersList.get('location', true)
|
location = headersList.get('location', true)
|
||||||
|
|
||||||
this.body = new Readable({ read: resume })
|
|
||||||
|
|
||||||
const decoders = []
|
const decoders = []
|
||||||
|
|
||||||
const willFollow = location && request.redirect === 'follow' &&
|
const willFollow = location && request.redirect === 'follow' &&
|
||||||
@@ -2139,7 +2139,7 @@ async function httpNetworkFetch (
|
|||||||
// CVE fix similar to urllib3 (GHSA-gm62-xv2j-4w53) and curl (CVE-2022-32206).
|
// CVE fix similar to urllib3 (GHSA-gm62-xv2j-4w53) and curl (CVE-2022-32206).
|
||||||
const maxContentEncodings = 5
|
const maxContentEncodings = 5
|
||||||
if (codings.length > maxContentEncodings) {
|
if (codings.length > maxContentEncodings) {
|
||||||
reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`))
|
this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2172,6 +2172,8 @@ async function httpNetworkFetch (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.body = new Readable({ read: resume })
|
||||||
|
|
||||||
const onError = this.onError.bind(this)
|
const onError = this.onError.bind(this)
|
||||||
|
|
||||||
resolve({
|
resolve({
|
||||||
@@ -2218,10 +2220,6 @@ async function httpNetworkFetch (
|
|||||||
fetchParams.controller.off('terminated', this.abort)
|
fetchParams.controller.off('terminated', this.abort)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fetchParams.controller.onAborted) {
|
|
||||||
fetchParams.controller.off('terminated', fetchParams.controller.onAborted)
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchParams.controller.ended = true
|
fetchParams.controller.ended = true
|
||||||
|
|
||||||
this.body.push(null)
|
this.body.push(null)
|
||||||
|
|||||||
+14
@@ -249,6 +249,20 @@ class ByteParser extends Writable {
|
|||||||
if (isControlFrame(this.#info.opcode)) {
|
if (isControlFrame(this.#info.opcode)) {
|
||||||
this.#loop = this.parseControlFrame(body)
|
this.#loop = this.parseControlFrame(body)
|
||||||
this.#state = parserStates.INFO
|
this.#state = parserStates.INFO
|
||||||
|
|
||||||
|
// If the automatic PONG/CLOSE reply filled the socket's write buffer,
|
||||||
|
// stop parsing and resume on drain so a PING flood cannot grow the
|
||||||
|
// outbound queue without bound.
|
||||||
|
const socket = this.ws[kResponse].socket
|
||||||
|
if (this.#loop && socket.writableNeedDrain) {
|
||||||
|
this.#loop = false
|
||||||
|
socket.once('drain', () => {
|
||||||
|
if (this.destroyed) return
|
||||||
|
this.#loop = true
|
||||||
|
this.run(callback)
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!this.#info.compressed) {
|
if (!this.#info.compressed) {
|
||||||
if (!this.writeFragments(body)) {
|
if (!this.writeFragments(body)) {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "undici",
|
"name": "undici",
|
||||||
"version": "6.29.0",
|
"version": "6.29.1",
|
||||||
"description": "An HTTP/1.1 client, written from scratch for Node.js",
|
"description": "An HTTP/1.1 client, written from scratch for Node.js",
|
||||||
"homepage": "https://undici.nodejs.org",
|
"homepage": "https://undici.nodejs.org",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|||||||
+14
@@ -80,6 +80,8 @@ export declare namespace Client {
|
|||||||
maxResponseSize?: number;
|
maxResponseSize?: number;
|
||||||
/** WebSocket-specific options */
|
/** WebSocket-specific options */
|
||||||
webSocket?: Client.WebSocketOptions;
|
webSocket?: Client.WebSocketOptions;
|
||||||
|
/** EventSource-specific options */
|
||||||
|
eventSource?: Client.EventSourceOptions;
|
||||||
/** Enables a family autodetection algorithm that loosely implements section 5 of RFC 8305. */
|
/** Enables a family autodetection algorithm that loosely implements section 5 of RFC 8305. */
|
||||||
autoSelectFamily?: boolean;
|
autoSelectFamily?: boolean;
|
||||||
/** The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. */
|
/** The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. */
|
||||||
@@ -120,6 +122,18 @@ export declare namespace Client {
|
|||||||
*/
|
*/
|
||||||
maxPayloadSize?: number;
|
maxPayloadSize?: number;
|
||||||
}
|
}
|
||||||
|
export interface EventSourceOptions {
|
||||||
|
/**
|
||||||
|
* Maximum total bytes of data and metadata field values retained for a
|
||||||
|
* pending EventSource event. Each unfinished line is separately bounded
|
||||||
|
* to this value plus seven syntax bytes. The number of data lines per
|
||||||
|
* event and buffered input chunks are each limited to
|
||||||
|
* min(131072, max(1024, floor(maxEventSize / 128))).
|
||||||
|
* Set to 0 to disable these limits.
|
||||||
|
* @default buffer.kStringMaxLength
|
||||||
|
*/
|
||||||
|
maxEventSize?: number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Client;
|
export default Client;
|
||||||
Reference in new issue
Block a user