This commit is contained in:
Lukian 2023-06-20 15:25:19 +02:00
parent 13ec9babde
commit 68f4b60012
1429 changed files with 2481 additions and 272836 deletions

119
node_modules/undici/lib/client.js generated vendored
View file

@ -1,3 +1,5 @@
// @ts-check
'use strict'
/* global WebAssembly */
@ -5,6 +7,7 @@
const assert = require('assert')
const net = require('net')
const util = require('./core/util')
const timers = require('./timers')
const Request = require('./core/request')
const DispatcherBase = require('./dispatcher-base')
const {
@ -18,7 +21,8 @@ const {
InformationalError,
BodyTimeoutError,
HTTPParserError,
ResponseExceededMaxSizeError
ResponseExceededMaxSizeError,
ClientDestroyedError
} = require('./core/errors')
const buildConnector = require('./core/connect')
const {
@ -65,6 +69,7 @@ const {
kLocalAddress,
kMaxResponseSize
} = require('./core/symbols')
const FastBuffer = Buffer[Symbol.species]
const kClosedResolve = Symbol('kClosedResolve')
@ -83,7 +88,15 @@ try {
channels.connected = { hasSubscribers: false }
}
/**
* @type {import('../types/client').default}
*/
class Client extends DispatcherBase {
/**
*
* @param {string|URL} url
* @param {import('../types/client').Client.Options} options
*/
constructor (url, {
interceptors,
maxHeaderSize,
@ -107,7 +120,9 @@ class Client extends DispatcherBase {
connect,
maxRequestsPerClient,
localAddress,
maxResponseSize
maxResponseSize,
autoSelectFamily,
autoSelectFamilyAttemptTimeout
} = {}) {
super()
@ -183,12 +198,20 @@ class Client extends DispatcherBase {
throw new InvalidArgumentError('maxResponseSize must be a positive number')
}
if (
autoSelectFamilyAttemptTimeout != null &&
(!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1)
) {
throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number')
}
if (typeof connect !== 'function') {
connect = buildConnector({
...tls,
maxCachedSessions,
socketPath,
timeout: connectTimeout,
...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined),
...connect
})
}
@ -210,8 +233,8 @@ class Client extends DispatcherBase {
this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming
this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming
this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n`
this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 30e3
this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 30e3
this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3
this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3
this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength
this[kMaxRedirections] = maxRedirections
this[kMaxRequests] = maxRequestsPerClient
@ -298,7 +321,7 @@ class Client extends DispatcherBase {
async [kClose] () {
return new Promise((resolve) => {
if (!this[kSize]) {
this.destroy(resolve)
resolve(null)
} else {
this[kClosedResolve] = resolve
}
@ -315,6 +338,7 @@ class Client extends DispatcherBase {
const callback = () => {
if (this[kClosedResolve]) {
// TODO (fix): Should we error here with ClientDestroyedError?
this[kClosedResolve]()
this[kClosedResolve] = null
}
@ -337,11 +361,11 @@ const createRedirectInterceptor = require('./interceptor/redirectInterceptor')
const EMPTY_BUF = Buffer.alloc(0)
async function lazyllhttp () {
const llhttpWasmData = process.env.JEST_WORKER_ID ? require('./llhttp/llhttp.wasm.js') : undefined
const llhttpWasmData = process.env.JEST_WORKER_ID ? require('./llhttp/llhttp-wasm.js') : undefined
let mod
try {
mod = await WebAssembly.compile(Buffer.from(require('./llhttp/llhttp_simd.wasm.js'), 'base64'))
mod = await WebAssembly.compile(Buffer.from(require('./llhttp/llhttp_simd-wasm.js'), 'base64'))
} catch (e) {
/* istanbul ignore next */
@ -349,7 +373,7 @@ async function lazyllhttp () {
// being enabled, but the occurring of this other error
// * https://github.com/emscripten-core/emscripten/issues/11495
// got me to remove that check to avoid breaking Node 12.
mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || require('./llhttp/llhttp.wasm.js'), 'base64'))
mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || require('./llhttp/llhttp-wasm.js'), 'base64'))
}
return await WebAssembly.instantiate(mod, {
@ -362,9 +386,8 @@ async function lazyllhttp () {
},
wasm_on_status: (p, at, len) => {
assert.strictEqual(currentParser.ptr, p)
const start = at - currentBufferPtr
const end = start + len
return currentParser.onStatus(currentBufferRef.slice(start, end)) || 0
const start = at - currentBufferPtr + currentBufferRef.byteOffset
return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0
},
wasm_on_message_begin: (p) => {
assert.strictEqual(currentParser.ptr, p)
@ -372,15 +395,13 @@ async function lazyllhttp () {
},
wasm_on_header_field: (p, at, len) => {
assert.strictEqual(currentParser.ptr, p)
const start = at - currentBufferPtr
const end = start + len
return currentParser.onHeaderField(currentBufferRef.slice(start, end)) || 0
const start = at - currentBufferPtr + currentBufferRef.byteOffset
return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0
},
wasm_on_header_value: (p, at, len) => {
assert.strictEqual(currentParser.ptr, p)
const start = at - currentBufferPtr
const end = start + len
return currentParser.onHeaderValue(currentBufferRef.slice(start, end)) || 0
const start = at - currentBufferPtr + currentBufferRef.byteOffset
return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0
},
wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => {
assert.strictEqual(currentParser.ptr, p)
@ -388,9 +409,8 @@ async function lazyllhttp () {
},
wasm_on_body: (p, at, len) => {
assert.strictEqual(currentParser.ptr, p)
const start = at - currentBufferPtr
const end = start + len
return currentParser.onBody(currentBufferRef.slice(start, end)) || 0
const start = at - currentBufferPtr + currentBufferRef.byteOffset
return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0
},
wasm_on_message_complete: (p) => {
assert.strictEqual(currentParser.ptr, p)
@ -447,9 +467,9 @@ class Parser {
setTimeout (value, type) {
this.timeoutType = type
if (value !== this.timeoutValue) {
clearTimeout(this.timeout)
timers.clearTimeout(this.timeout)
if (value) {
this.timeout = setTimeout(onParserTimeout, value, this)
this.timeout = timers.setTimeout(onParserTimeout, value, this)
// istanbul ignore else: only for jest
if (this.timeout.unref) {
this.timeout.unref()
@ -549,7 +569,10 @@ class Parser {
/* istanbul ignore else: difficult to make a test case for */
if (ptr) {
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
message = Buffer.from(llhttp.memory.buffer, ptr, len).toString()
message =
'Response does not match the HTTP/1.1 protocol (' +
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
')'
}
throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset))
}
@ -565,7 +588,7 @@ class Parser {
this.llhttp.llhttp_free(this.ptr)
this.ptr = null
clearTimeout(this.timeout)
timers.clearTimeout(this.timeout)
this.timeout = null
this.timeoutValue = null
this.timeoutType = null
@ -1064,6 +1087,11 @@ async function connect (client) {
})
})
if (client.destroyed) {
util.destroy(socket.on('error', () => {}), new ClientDestroyedError())
return
}
if (!llhttpInstance) {
llhttpInstance = await llhttpPromise
llhttpPromise = null
@ -1106,6 +1134,10 @@ async function connect (client) {
}
client.emit('connect', client[kUrl], [client])
} catch (err) {
if (client.destroyed) {
return
}
client[kConnecting] = false
if (channels.connectError.hasSubscribers) {
@ -1168,8 +1200,9 @@ function _resume (client, sync) {
return
}
if (client.closed && !client[kSize]) {
client.destroy()
if (client[kClosedResolve] && !client[kSize]) {
client[kClosedResolve]()
client[kClosedResolve] = null
return
}
@ -1421,17 +1454,17 @@ function write (client, request) {
/* istanbul ignore else: assertion */
if (!body) {
if (contentLength === 0) {
socket.write(`${header}content-length: 0\r\n\r\n`, 'ascii')
socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1')
} else {
assert(contentLength === null, 'no body must not have content length')
socket.write(`${header}\r\n`, 'ascii')
socket.write(`${header}\r\n`, 'latin1')
}
request.onRequestSent()
} else if (util.isBuffer(body)) {
assert(contentLength === body.byteLength, 'buffer body must have content length')
socket.cork()
socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'ascii')
socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
socket.write(body)
socket.uncork()
request.onBodySent(body)
@ -1464,9 +1497,11 @@ function writeStream ({ body, client, request, socket, contentLength, header, ex
const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header })
const onData = function (chunk) {
try {
assert(!finished)
if (finished) {
return
}
try {
if (!writer.write(chunk) && this.pause) {
this.pause()
}
@ -1475,7 +1510,9 @@ function writeStream ({ body, client, request, socket, contentLength, header, ex
}
}
const onDrain = function () {
assert(!finished)
if (finished) {
return
}
if (body.resume) {
body.resume()
@ -1546,7 +1583,7 @@ async function writeBlob ({ body, client, request, socket, contentLength, header
const buffer = Buffer.from(await body.arrayBuffer())
socket.cork()
socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'ascii')
socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
socket.write(buffer)
socket.uncork()
@ -1650,26 +1687,30 @@ class AsyncWriter {
process.emitWarning(new RequestContentLengthMismatchError())
}
socket.cork()
if (bytesWritten === 0) {
if (!expectsPayload) {
socket[kReset] = true
}
if (contentLength === null) {
socket.write(`${header}transfer-encoding: chunked\r\n`, 'ascii')
socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1')
} else {
socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'ascii')
socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
}
}
if (contentLength === null) {
socket.write(`\r\n${len.toString(16)}\r\n`, 'ascii')
socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1')
}
this.bytesWritten += len
const ret = socket.write(chunk)
socket.uncork()
request.onBodySent(chunk)
if (!ret) {
@ -1705,12 +1746,12 @@ class AsyncWriter {
// no Transfer-Encoding is sent and the request method defines a meaning
// for an enclosed payload body.
socket.write(`${header}content-length: 0\r\n\r\n`, 'ascii')
socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1')
} else {
socket.write(`${header}\r\n`, 'ascii')
socket.write(`${header}\r\n`, 'latin1')
}
} else if (contentLength === null) {
socket.write('\r\n0\r\n\r\n', 'ascii')
socket.write('\r\n0\r\n\r\n', 'latin1')
}
if (contentLength !== null && bytesWritten !== contentLength) {