mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 12:20:27 +01:00
deps: update undici to 7.12.0
PR-URL: https://github.com/nodejs/node/pull/59135 Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Matthew Aitken <maitken033380023@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
parent
2a17346cc4
commit
5fe16bc6bf
4
deps/undici/src/.gitignore
vendored
4
deps/undici/src/.gitignore
vendored
|
|
@ -88,3 +88,7 @@ undici-fetch.js
|
|||
|
||||
# File generated by /test/request-timeout.js
|
||||
test/request-timeout.10mb.bin
|
||||
|
||||
# Claude files
|
||||
CLAUDE.md
|
||||
.claude
|
||||
|
|
|
|||
6
deps/undici/src/README.md
vendored
6
deps/undici/src/README.md
vendored
|
|
@ -114,8 +114,10 @@ const response = await fetch('https://api.example.com/data');
|
|||
#### Use Built-in Fetch When:
|
||||
- You want zero dependencies
|
||||
- Building isomorphic code that runs in browsers and Node.js
|
||||
- Publishing to npm and want to maximize compatibility with JS runtimes
|
||||
- Simple HTTP requests without advanced configuration
|
||||
- You're okay with the undici version bundled in your Node.js version
|
||||
- You're publishing to npm and you want to maximize compatiblity
|
||||
- You don't depend on features from a specific version of undici
|
||||
|
||||
#### Use Undici Module When:
|
||||
- You need the latest undici features and performance improvements
|
||||
|
|
@ -209,7 +211,7 @@ The `install()` function adds the following classes to `globalThis`:
|
|||
- `fetch` - The fetch function
|
||||
- `Headers` - HTTP headers management
|
||||
- `Response` - HTTP response representation
|
||||
- `Request` - HTTP request representation
|
||||
- `Request` - HTTP request representation
|
||||
- `FormData` - Form data handling
|
||||
- `WebSocket` - WebSocket client
|
||||
- `CloseEvent`, `ErrorEvent`, `MessageEvent` - WebSocket events
|
||||
|
|
|
|||
|
|
@ -169,10 +169,11 @@ This message is published after the client has successfully connected to a serve
|
|||
```js
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:websocket:open').subscribe(({ address, protocol, extensions }) => {
|
||||
diagnosticsChannel.channel('undici:websocket:open').subscribe(({ address, protocol, extensions, websocket }) => {
|
||||
console.log(address) // address, family, and port
|
||||
console.log(protocol) // negotiated subprotocols
|
||||
console.log(extensions) // negotiated extensions
|
||||
console.log(websocket) // the WebSocket instance
|
||||
})
|
||||
```
|
||||
|
||||
|
|
@ -184,7 +185,7 @@ This message is published after the connection has closed.
|
|||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:websocket:close').subscribe(({ websocket, code, reason }) => {
|
||||
console.log(websocket) // the WebSocket object
|
||||
console.log(websocket) // the WebSocket instance
|
||||
console.log(code) // the closing status code
|
||||
console.log(reason) // the closing reason
|
||||
})
|
||||
|
|
@ -209,9 +210,10 @@ This message is published after the client receives a ping frame, if the connect
|
|||
```js
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:websocket:ping').subscribe(({ payload }) => {
|
||||
diagnosticsChannel.channel('undici:websocket:ping').subscribe(({ payload, websocket }) => {
|
||||
// a Buffer or undefined, containing the optional application data of the frame
|
||||
console.log(payload)
|
||||
console.log(websocket) // the WebSocket instance
|
||||
})
|
||||
```
|
||||
|
||||
|
|
@ -222,8 +224,9 @@ This message is published after the client receives a pong frame.
|
|||
```js
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:websocket:pong').subscribe(({ payload }) => {
|
||||
diagnosticsChannel.channel('undici:websocket:pong').subscribe(({ payload, websocket }) => {
|
||||
// a Buffer or undefined, containing the optional application data of the frame
|
||||
console.log(payload)
|
||||
console.log(websocket) // the WebSocket instance
|
||||
})
|
||||
```
|
||||
|
|
|
|||
4
deps/undici/src/docs/docs/api/Dispatcher.md
vendored
4
deps/undici/src/docs/docs/api/Dispatcher.md
vendored
|
|
@ -1103,8 +1103,8 @@ The `cache` interceptor implements client-side response caching as described in
|
|||
|
||||
- `store` - The [`CacheStore`](/docs/docs/api/CacheStore.md) to store and retrieve responses from. Default is [`MemoryCacheStore`](/docs/docs/api/CacheStore.md#memorycachestore).
|
||||
- `methods` - The [**safe** HTTP methods](https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1) to cache the response of.
|
||||
- `cacheByDefault` - The default expiration time to cache responses by if they don't have an explicit expiration. If this isn't present, responses without explicit expiration will not be cached. Default `undefined`.
|
||||
- `type` - The type of cache for Undici to act as. Can be `shared` or `private`. Default `shared`.
|
||||
- `cacheByDefault` - The default expiration time to cache responses by if they don't have an explicit expiration and cannot have an heuristic expiry computed. If this isn't present, responses neither with an explicit expiration nor heuristically cacheable will not be cached. Default `undefined`.
|
||||
- `type` - The [type of cache](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching#types_of_caches) for Undici to act as. Can be `shared` or `private`. Default `shared`. `private` implies privately cacheable responses will be cached and potentially shared with other users of your application.
|
||||
|
||||
## Instance Events
|
||||
|
||||
|
|
|
|||
27
deps/undici/src/docs/docs/api/WebSocket.md
vendored
27
deps/undici/src/docs/docs/api/WebSocket.md
vendored
|
|
@ -78,6 +78,33 @@ setInterval(() => write(), 5000)
|
|||
|
||||
```
|
||||
|
||||
## ping(websocket, payload)
|
||||
Arguments:
|
||||
|
||||
* **websocket** `WebSocket` - The WebSocket instance to send the ping frame on
|
||||
* **payload** `Buffer|undefined` (optional) - Optional payload data to include with the ping frame. Must not exceed 125 bytes.
|
||||
|
||||
Sends a ping frame to the WebSocket server. The server must respond with a pong frame containing the same payload data. This can be used for keepalive purposes or to verify that the connection is still active.
|
||||
|
||||
### Example:
|
||||
|
||||
```js
|
||||
import { WebSocket, ping } from 'undici'
|
||||
|
||||
const ws = new WebSocket('wss://echo.websocket.events')
|
||||
|
||||
ws.addEventListener('open', () => {
|
||||
// Send ping with no payload
|
||||
ping(ws)
|
||||
|
||||
// Send ping with payload
|
||||
const payload = Buffer.from('hello')
|
||||
ping(ws, payload)
|
||||
})
|
||||
```
|
||||
|
||||
**Note**: A ping frame cannot have a payload larger than 125 bytes. The ping will only be sent if the WebSocket connection is in the OPEN state.
|
||||
|
||||
## Read More
|
||||
|
||||
- [MDN - WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
|
||||
|
|
|
|||
4
deps/undici/src/index.js
vendored
4
deps/undici/src/index.js
vendored
|
|
@ -157,10 +157,12 @@ module.exports.parseMIMEType = parseMIMEType
|
|||
module.exports.serializeAMimeType = serializeAMimeType
|
||||
|
||||
const { CloseEvent, ErrorEvent, MessageEvent } = require('./lib/web/websocket/events')
|
||||
module.exports.WebSocket = require('./lib/web/websocket/websocket').WebSocket
|
||||
const { WebSocket, ping } = require('./lib/web/websocket/websocket')
|
||||
module.exports.WebSocket = WebSocket
|
||||
module.exports.CloseEvent = CloseEvent
|
||||
module.exports.ErrorEvent = ErrorEvent
|
||||
module.exports.MessageEvent = MessageEvent
|
||||
module.exports.ping = ping
|
||||
|
||||
module.exports.WebSocketStream = require('./lib/web/websocket/stream/websocketstream').WebSocketStream
|
||||
module.exports.WebSocketError = require('./lib/web/websocket/stream/websocketerror').WebSocketError
|
||||
|
|
|
|||
4
deps/undici/src/lib/api/readable.js
vendored
4
deps/undici/src/lib/api/readable.js
vendored
|
|
@ -89,9 +89,7 @@ class BodyReadable extends Readable {
|
|||
// promise (i.e micro tick) for installing an 'error' listener will
|
||||
// never get a chance and will always encounter an unhandled exception.
|
||||
if (!this[kUsed]) {
|
||||
setImmediate(() => {
|
||||
callback(err)
|
||||
})
|
||||
setImmediate(callback, err)
|
||||
} else {
|
||||
callback(err)
|
||||
}
|
||||
|
|
|
|||
7
deps/undici/src/lib/core/request.js
vendored
7
deps/undici/src/lib/core/request.js
vendored
|
|
@ -42,7 +42,8 @@ class Request {
|
|||
reset,
|
||||
expectContinue,
|
||||
servername,
|
||||
throwOnError
|
||||
throwOnError,
|
||||
maxRedirections
|
||||
}, handler) {
|
||||
if (typeof path !== 'string') {
|
||||
throw new InvalidArgumentError('path must be a string')
|
||||
|
|
@ -86,6 +87,10 @@ class Request {
|
|||
throw new InvalidArgumentError('invalid throwOnError')
|
||||
}
|
||||
|
||||
if (maxRedirections != null && maxRedirections !== 0) {
|
||||
throw new InvalidArgumentError('maxRedirections is not supported, use the redirect interceptor')
|
||||
}
|
||||
|
||||
this.headersTimeout = headersTimeout
|
||||
|
||||
this.bodyTimeout = bodyTimeout
|
||||
|
|
|
|||
2
deps/undici/src/lib/core/tree.js
vendored
2
deps/undici/src/lib/core/tree.js
vendored
|
|
@ -86,7 +86,7 @@ class TstNode {
|
|||
|
||||
/**
|
||||
* @param {Uint8Array} key
|
||||
* @return {TstNode | null}
|
||||
* @returns {TstNode | null}
|
||||
*/
|
||||
search (key) {
|
||||
const keylength = key.length
|
||||
|
|
|
|||
25
deps/undici/src/lib/dispatcher/client-h1.js
vendored
25
deps/undici/src/lib/dispatcher/client-h1.js
vendored
|
|
@ -60,12 +60,12 @@ const removeAllListeners = util.removeAllListeners
|
|||
|
||||
let extractBody
|
||||
|
||||
async function lazyllhttp () {
|
||||
function lazyllhttp () {
|
||||
const llhttpWasmData = process.env.JEST_WORKER_ID ? require('../llhttp/llhttp-wasm.js') : undefined
|
||||
|
||||
let mod
|
||||
try {
|
||||
mod = await WebAssembly.compile(require('../llhttp/llhttp_simd-wasm.js'))
|
||||
mod = new WebAssembly.Module(require('../llhttp/llhttp_simd-wasm.js'))
|
||||
} catch (e) {
|
||||
/* istanbul ignore next */
|
||||
|
||||
|
|
@ -73,10 +73,10 @@ 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(llhttpWasmData || require('../llhttp/llhttp-wasm.js'))
|
||||
mod = new WebAssembly.Module(llhttpWasmData || require('../llhttp/llhttp-wasm.js'))
|
||||
}
|
||||
|
||||
return await WebAssembly.instantiate(mod, {
|
||||
return new WebAssembly.Instance(mod, {
|
||||
env: {
|
||||
/**
|
||||
* @param {number} p
|
||||
|
|
@ -165,11 +165,6 @@ async function lazyllhttp () {
|
|||
}
|
||||
|
||||
let llhttpInstance = null
|
||||
/**
|
||||
* @type {Promise<WebAssembly.Instance>|null}
|
||||
*/
|
||||
let llhttpPromise = lazyllhttp()
|
||||
llhttpPromise.catch()
|
||||
|
||||
/**
|
||||
* @type {Parser|null}
|
||||
|
|
@ -732,7 +727,7 @@ class Parser {
|
|||
// We must wait a full event loop cycle to reuse this socket to make sure
|
||||
// that non-spec compliant servers are not closing the connection even if they
|
||||
// said they won't.
|
||||
setImmediate(() => client[kResume]())
|
||||
setImmediate(client[kResume])
|
||||
} else {
|
||||
client[kResume]()
|
||||
}
|
||||
|
|
@ -769,11 +764,7 @@ async function connectH1 (client, socket) {
|
|||
client[kSocket] = socket
|
||||
|
||||
if (!llhttpInstance) {
|
||||
const noop = () => {}
|
||||
socket.on('error', noop)
|
||||
llhttpInstance = await llhttpPromise
|
||||
llhttpPromise = null
|
||||
socket.off('error', noop)
|
||||
llhttpInstance = lazyllhttp()
|
||||
}
|
||||
|
||||
if (socket.errored) {
|
||||
|
|
@ -1297,9 +1288,9 @@ function writeStream (abort, body, client, request, socket, contentLength, heade
|
|||
.on('error', onFinished)
|
||||
|
||||
if (body.errorEmitted ?? body.errored) {
|
||||
setImmediate(() => onFinished(body.errored))
|
||||
setImmediate(onFinished, body.errored)
|
||||
} else if (body.endEmitted ?? body.readableEnded) {
|
||||
setImmediate(() => onFinished(null))
|
||||
setImmediate(onFinished, null)
|
||||
}
|
||||
|
||||
if (body.closeEmitted ?? body.closed) {
|
||||
|
|
|
|||
5
deps/undici/src/lib/handler/cache-handler.js
vendored
5
deps/undici/src/lib/handler/cache-handler.js
vendored
|
|
@ -241,7 +241,10 @@ class CacheHandler {
|
|||
* @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives
|
||||
*/
|
||||
function canCacheResponse (cacheType, statusCode, resHeaders, cacheControlDirectives) {
|
||||
if (statusCode !== 200 && statusCode !== 307) {
|
||||
// Allow caching for status codes 200 and 307 (original behavior)
|
||||
// Also allow caching for other status codes that are heuristically cacheable
|
||||
// when they have explicit cache directives
|
||||
if (statusCode !== 200 && statusCode !== 307 && !HEURISTICALLY_CACHEABLE_STATUS_CODES.includes(statusCode)) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ class RedirectHandler {
|
|||
|
||||
this.dispatch = dispatch
|
||||
this.location = null
|
||||
this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy
|
||||
const { maxRedirections: _, ...cleanOpts } = opts
|
||||
this.opts = cleanOpts // opts must be a copy, exclude maxRedirections
|
||||
this.maxRedirections = maxRedirections
|
||||
this.handler = handler
|
||||
this.history = []
|
||||
|
|
@ -138,7 +139,6 @@ class RedirectHandler {
|
|||
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin)
|
||||
this.opts.path = path
|
||||
this.opts.origin = origin
|
||||
this.opts.maxRedirections = 0
|
||||
this.opts.query = null
|
||||
}
|
||||
|
||||
|
|
|
|||
4
deps/undici/src/lib/interceptor/cache.js
vendored
4
deps/undici/src/lib/interceptor/cache.js
vendored
|
|
@ -301,11 +301,11 @@ module.exports = (opts = {}) => {
|
|||
assertCacheMethods(methods, 'opts.methods')
|
||||
|
||||
if (typeof cacheByDefault !== 'undefined' && typeof cacheByDefault !== 'number') {
|
||||
throw new TypeError(`exepcted opts.cacheByDefault to be number or undefined, got ${typeof cacheByDefault}`)
|
||||
throw new TypeError(`expected opts.cacheByDefault to be number or undefined, got ${typeof cacheByDefault}`)
|
||||
}
|
||||
|
||||
if (typeof type !== 'undefined' && type !== 'shared' && type !== 'private') {
|
||||
throw new TypeError(`exepcted opts.type to be shared, private, or undefined, got ${typeof type}`)
|
||||
throw new TypeError(`expected opts.type to be shared, private, or undefined, got ${typeof type}`)
|
||||
}
|
||||
|
||||
const globalOpts = {
|
||||
|
|
|
|||
2
deps/undici/src/lib/interceptor/redirect.js
vendored
2
deps/undici/src/lib/interceptor/redirect.js
vendored
|
|
@ -11,7 +11,7 @@ function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections }
|
|||
return dispatch(opts, handler)
|
||||
}
|
||||
|
||||
const dispatchOpts = { ...rest, maxRedirections: 0 } // Stop sub dispatcher from also redirecting.
|
||||
const dispatchOpts = { ...rest } // Stop sub dispatcher from also redirecting.
|
||||
const redirectHandler = new RedirectHandler(dispatch, maxRedirections, dispatchOpts, handler)
|
||||
return dispatch(dispatchOpts, redirectHandler)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
> undici@7.11.0 build:wasm
|
||||
> undici@7.12.0 build:wasm
|
||||
> node build/wasm.js --docker
|
||||
|
||||
> docker run --rm --platform=linux/x86_64 --user 1001:118 --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
|
||||
|
|
|
|||
2
deps/undici/src/lib/util/cache.js
vendored
2
deps/undici/src/lib/util/cache.js
vendored
|
|
@ -32,7 +32,7 @@ function makeCacheKey (opts) {
|
|||
|
||||
/**
|
||||
* @param {Record<string, string[] | string>}
|
||||
* @return {Record<string, string[] | string>}
|
||||
* @returns {Record<string, string[] | string>}
|
||||
*/
|
||||
function normaliseHeaders (opts) {
|
||||
let headers
|
||||
|
|
|
|||
28
deps/undici/src/lib/util/promise.js
vendored
Normal file
28
deps/undici/src/lib/util/promise.js
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* @template {*} T
|
||||
* @typedef {Object} DeferredPromise
|
||||
* @property {Promise<T>} promise
|
||||
* @property {(value?: T) => void} resolve
|
||||
* @property {(reason?: any) => void} reject
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {*} T
|
||||
* @returns {DeferredPromise<T>} An object containing a promise and its resolve/reject methods.
|
||||
*/
|
||||
function createDeferredPromise () {
|
||||
let res
|
||||
let rej
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
res = resolve
|
||||
rej = reject
|
||||
})
|
||||
|
||||
return { promise, resolve: res, reject: rej }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createDeferredPromise
|
||||
}
|
||||
18
deps/undici/src/lib/web/cache/cache.js
vendored
18
deps/undici/src/lib/web/cache/cache.js
vendored
|
|
@ -1,5 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const assert = require('node:assert')
|
||||
|
||||
const { kConstruct } = require('../../core/symbols')
|
||||
const { urlEquals, getFieldValues } = require('./util')
|
||||
const { kEnumerableProperty, isDisturbed } = require('../../core/util')
|
||||
|
|
@ -7,8 +9,8 @@ const { webidl } = require('../webidl')
|
|||
const { cloneResponse, fromInnerResponse, getResponseState } = require('../fetch/response')
|
||||
const { Request, fromInnerRequest, getRequestState } = require('../fetch/request')
|
||||
const { fetching } = require('../fetch/index')
|
||||
const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = require('../fetch/util')
|
||||
const assert = require('node:assert')
|
||||
const { urlIsHttpHttpsScheme, readAllBytes } = require('../fetch/util')
|
||||
const { createDeferredPromise } = require('../../util/promise')
|
||||
|
||||
/**
|
||||
* @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation
|
||||
|
|
@ -46,7 +48,7 @@ class Cache {
|
|||
const prefix = 'Cache.match'
|
||||
webidl.argumentLengthCheck(arguments, 1, prefix)
|
||||
|
||||
request = webidl.converters.RequestInfo(request, prefix, 'request')
|
||||
request = webidl.converters.RequestInfo(request)
|
||||
options = webidl.converters.CacheQueryOptions(options, prefix, 'options')
|
||||
|
||||
const p = this.#internalMatchAll(request, options, 1)
|
||||
|
|
@ -62,7 +64,7 @@ class Cache {
|
|||
webidl.brandCheck(this, Cache)
|
||||
|
||||
const prefix = 'Cache.matchAll'
|
||||
if (request !== undefined) request = webidl.converters.RequestInfo(request, prefix, 'request')
|
||||
if (request !== undefined) request = webidl.converters.RequestInfo(request)
|
||||
options = webidl.converters.CacheQueryOptions(options, prefix, 'options')
|
||||
|
||||
return this.#internalMatchAll(request, options)
|
||||
|
|
@ -74,7 +76,7 @@ class Cache {
|
|||
const prefix = 'Cache.add'
|
||||
webidl.argumentLengthCheck(arguments, 1, prefix)
|
||||
|
||||
request = webidl.converters.RequestInfo(request, prefix, 'request')
|
||||
request = webidl.converters.RequestInfo(request)
|
||||
|
||||
// 1.
|
||||
const requests = [request]
|
||||
|
|
@ -262,7 +264,7 @@ class Cache {
|
|||
const prefix = 'Cache.put'
|
||||
webidl.argumentLengthCheck(arguments, 2, prefix)
|
||||
|
||||
request = webidl.converters.RequestInfo(request, prefix, 'request')
|
||||
request = webidl.converters.RequestInfo(request)
|
||||
response = webidl.converters.Response(response, prefix, 'response')
|
||||
|
||||
// 1.
|
||||
|
|
@ -393,7 +395,7 @@ class Cache {
|
|||
const prefix = 'Cache.delete'
|
||||
webidl.argumentLengthCheck(arguments, 1, prefix)
|
||||
|
||||
request = webidl.converters.RequestInfo(request, prefix, 'request')
|
||||
request = webidl.converters.RequestInfo(request)
|
||||
options = webidl.converters.CacheQueryOptions(options, prefix, 'options')
|
||||
|
||||
/**
|
||||
|
|
@ -458,7 +460,7 @@ class Cache {
|
|||
|
||||
const prefix = 'Cache.keys'
|
||||
|
||||
if (request !== undefined) request = webidl.converters.RequestInfo(request, prefix, 'request')
|
||||
if (request !== undefined) request = webidl.converters.RequestInfo(request)
|
||||
options = webidl.converters.CacheQueryOptions(options, prefix, 'options')
|
||||
|
||||
// 1.
|
||||
|
|
|
|||
58
deps/undici/src/lib/web/fetch/body.js
vendored
58
deps/undici/src/lib/web/fetch/body.js
vendored
|
|
@ -4,7 +4,6 @@ const util = require('../../core/util')
|
|||
const {
|
||||
ReadableStreamFrom,
|
||||
readableStreamClose,
|
||||
createDeferredPromise,
|
||||
fullyReadBody,
|
||||
extractMimeType,
|
||||
utf8DecodeBytes
|
||||
|
|
@ -17,6 +16,8 @@ const { isErrored, isDisturbed } = require('node:stream')
|
|||
const { isArrayBuffer } = require('node:util/types')
|
||||
const { serializeAMimeType } = require('./data-url')
|
||||
const { multipartFormDataParser } = require('./formdata-parser')
|
||||
const { createDeferredPromise } = require('../../util/promise')
|
||||
|
||||
let random
|
||||
|
||||
try {
|
||||
|
|
@ -29,19 +30,22 @@ try {
|
|||
const textEncoder = new TextEncoder()
|
||||
function noop () {}
|
||||
|
||||
const hasFinalizationRegistry = globalThis.FinalizationRegistry
|
||||
let streamRegistry
|
||||
const streamRegistry = new FinalizationRegistry((weakRef) => {
|
||||
const stream = weakRef.deref()
|
||||
if (stream && !stream.locked && !isDisturbed(stream) && !isErrored(stream)) {
|
||||
stream.cancel('Response object has been garbage collected').catch(noop)
|
||||
}
|
||||
})
|
||||
|
||||
if (hasFinalizationRegistry) {
|
||||
streamRegistry = new FinalizationRegistry((weakRef) => {
|
||||
const stream = weakRef.deref()
|
||||
if (stream && !stream.locked && !isDisturbed(stream) && !isErrored(stream)) {
|
||||
stream.cancel('Response object has been garbage collected').catch(noop)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-bodyinit-extract
|
||||
/**
|
||||
* Extract a body with type from a byte sequence or BodyInit object
|
||||
*
|
||||
* @param {import('../../../types').BodyInit} object - The BodyInit object to extract from
|
||||
* @param {boolean} [keepalive=false] - If true, indicates that the body
|
||||
* @returns {[{stream: ReadableStream, source: any, length: number | null}, string | null]} - Returns a tuple containing the body and its type
|
||||
*
|
||||
* @see https://fetch.spec.whatwg.org/#concept-bodyinit-extract
|
||||
*/
|
||||
function extractBody (object, keepalive = false) {
|
||||
// 1. Let stream be null.
|
||||
let stream = null
|
||||
|
|
@ -267,7 +271,22 @@ function extractBody (object, keepalive = false) {
|
|||
return [body, type]
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#bodyinit-safely-extract
|
||||
/**
|
||||
* @typedef {object} ExtractBodyResult
|
||||
* @property {ReadableStream<Uint8Array<ArrayBuffer>>} stream - The ReadableStream containing the body data
|
||||
* @property {any} source - The original source of the body data
|
||||
* @property {number | null} length - The length of the body data, or null
|
||||
*/
|
||||
|
||||
/**
|
||||
* Safely extract a body with type from a byte sequence or BodyInit object.
|
||||
*
|
||||
* @param {import('../../../types').BodyInit} object - The BodyInit object to extract from
|
||||
* @param {boolean} [keepalive=false] - If true, indicates that the body
|
||||
* @returns {[ExtractBodyResult, string | null]} - Returns a tuple containing the body and its type
|
||||
*
|
||||
* @see https://fetch.spec.whatwg.org/#bodyinit-safely-extract
|
||||
*/
|
||||
function safelyExtractBody (object, keepalive = false) {
|
||||
// To safely extract a body and a `Content-Type` value from
|
||||
// a byte sequence or BodyInit object object, run these steps:
|
||||
|
|
@ -275,9 +294,7 @@ function safelyExtractBody (object, keepalive = false) {
|
|||
// 1. If object is a ReadableStream object, then:
|
||||
if (webidl.is.ReadableStream(object)) {
|
||||
// Assert: object is neither disturbed nor locked.
|
||||
// istanbul ignore next
|
||||
assert(!util.isDisturbed(object), 'The body has already been consumed.')
|
||||
// istanbul ignore next
|
||||
assert(!object.locked, 'The stream is locked.')
|
||||
}
|
||||
|
||||
|
|
@ -285,17 +302,13 @@ function safelyExtractBody (object, keepalive = false) {
|
|||
return extractBody(object, keepalive)
|
||||
}
|
||||
|
||||
function cloneBody (instance, body) {
|
||||
function cloneBody (body) {
|
||||
// To clone a body body, run these steps:
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-body-clone
|
||||
|
||||
// 1. Let « out1, out2 » be the result of teeing body’s stream.
|
||||
const [out1, out2] = body.stream.tee()
|
||||
|
||||
if (hasFinalizationRegistry) {
|
||||
streamRegistry.register(instance, new WeakRef(out1))
|
||||
}
|
||||
const { 0: out1, 1: out2 } = body.stream.tee()
|
||||
|
||||
// 2. Set body’s stream to out1.
|
||||
body.stream = out1
|
||||
|
|
@ -527,6 +540,5 @@ module.exports = {
|
|||
cloneBody,
|
||||
mixinBody,
|
||||
streamRegistry,
|
||||
hasFinalizationRegistry,
|
||||
bodyUnusable
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
module.exports = function () {
|
||||
return { WeakRef, FinalizationRegistry }
|
||||
}
|
||||
464
deps/undici/src/lib/web/fetch/index.js
vendored
464
deps/undici/src/lib/web/fetch/index.js
vendored
|
|
@ -30,7 +30,6 @@ const {
|
|||
crossOriginResourcePolicyCheck,
|
||||
determineRequestsReferrer,
|
||||
coarsenedSharedCurrentTime,
|
||||
createDeferredPromise,
|
||||
sameOrigin,
|
||||
isCancelled,
|
||||
isAborted,
|
||||
|
|
@ -63,6 +62,7 @@ const { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = requ
|
|||
const { getGlobalDispatcher } = require('../../global')
|
||||
const { webidl } = require('../webidl')
|
||||
const { STATUS_CODES } = require('node:http')
|
||||
const { createDeferredPromise } = require('../../util/promise')
|
||||
const GET_OR_HEAD = ['GET', 'HEAD']
|
||||
|
||||
const defaultUserAgent = typeof __UNDICI_IS_NODE__ !== 'undefined' || typeof esbuildDetection !== 'undefined'
|
||||
|
|
@ -507,257 +507,258 @@ function fetching ({
|
|||
}
|
||||
|
||||
// 16. Run main fetch given fetchParams.
|
||||
mainFetch(fetchParams)
|
||||
.catch(err => {
|
||||
fetchParams.controller.terminate(err)
|
||||
})
|
||||
mainFetch(fetchParams, false)
|
||||
|
||||
// 17. Return fetchParam's controller
|
||||
return fetchParams.controller
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-main-fetch
|
||||
async function mainFetch (fetchParams, recursive = false) {
|
||||
// 1. Let request be fetchParams’s request.
|
||||
const request = fetchParams.request
|
||||
async function mainFetch (fetchParams, recursive) {
|
||||
try {
|
||||
// 1. Let request be fetchParams’s request.
|
||||
const request = fetchParams.request
|
||||
|
||||
// 2. Let response be null.
|
||||
let response = null
|
||||
// 2. Let response be null.
|
||||
let response = null
|
||||
|
||||
// 3. If request’s local-URLs-only flag is set and request’s current URL is
|
||||
// not local, then set response to a network error.
|
||||
if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) {
|
||||
response = makeNetworkError('local URLs only')
|
||||
}
|
||||
// 3. If request’s local-URLs-only flag is set and request’s current URL is
|
||||
// not local, then set response to a network error.
|
||||
if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) {
|
||||
response = makeNetworkError('local URLs only')
|
||||
}
|
||||
|
||||
// 4. Run report Content Security Policy violations for request.
|
||||
// TODO
|
||||
// 4. Run report Content Security Policy violations for request.
|
||||
// TODO
|
||||
|
||||
// 5. Upgrade request to a potentially trustworthy URL, if appropriate.
|
||||
tryUpgradeRequestToAPotentiallyTrustworthyURL(request)
|
||||
// 5. Upgrade request to a potentially trustworthy URL, if appropriate.
|
||||
tryUpgradeRequestToAPotentiallyTrustworthyURL(request)
|
||||
|
||||
// 6. If should request be blocked due to a bad port, should fetching request
|
||||
// be blocked as mixed content, or should request be blocked by Content
|
||||
// Security Policy returns blocked, then set response to a network error.
|
||||
if (requestBadPort(request) === 'blocked') {
|
||||
response = makeNetworkError('bad port')
|
||||
}
|
||||
// TODO: should fetching request be blocked as mixed content?
|
||||
// TODO: should request be blocked by Content Security Policy?
|
||||
// 6. If should request be blocked due to a bad port, should fetching request
|
||||
// be blocked as mixed content, or should request be blocked by Content
|
||||
// Security Policy returns blocked, then set response to a network error.
|
||||
if (requestBadPort(request) === 'blocked') {
|
||||
response = makeNetworkError('bad port')
|
||||
}
|
||||
// TODO: should fetching request be blocked as mixed content?
|
||||
// TODO: should request be blocked by Content Security Policy?
|
||||
|
||||
// 7. If request’s referrer policy is the empty string, then set request’s
|
||||
// referrer policy to request’s policy container’s referrer policy.
|
||||
if (request.referrerPolicy === '') {
|
||||
request.referrerPolicy = request.policyContainer.referrerPolicy
|
||||
}
|
||||
// 7. If request’s referrer policy is the empty string, then set request’s
|
||||
// referrer policy to request’s policy container’s referrer policy.
|
||||
if (request.referrerPolicy === '') {
|
||||
request.referrerPolicy = request.policyContainer.referrerPolicy
|
||||
}
|
||||
|
||||
// 8. If request’s referrer is not "no-referrer", then set request’s
|
||||
// referrer to the result of invoking determine request’s referrer.
|
||||
if (request.referrer !== 'no-referrer') {
|
||||
request.referrer = determineRequestsReferrer(request)
|
||||
}
|
||||
// 8. If request’s referrer is not "no-referrer", then set request’s
|
||||
// referrer to the result of invoking determine request’s referrer.
|
||||
if (request.referrer !== 'no-referrer') {
|
||||
request.referrer = determineRequestsReferrer(request)
|
||||
}
|
||||
|
||||
// 9. Set request’s current URL’s scheme to "https" if all of the following
|
||||
// conditions are true:
|
||||
// - request’s current URL’s scheme is "http"
|
||||
// - request’s current URL’s host is a domain
|
||||
// - Matching request’s current URL’s host per Known HSTS Host Domain Name
|
||||
// Matching results in either a superdomain match with an asserted
|
||||
// includeSubDomains directive or a congruent match (with or without an
|
||||
// asserted includeSubDomains directive). [HSTS]
|
||||
// TODO
|
||||
// 9. Set request’s current URL’s scheme to "https" if all of the following
|
||||
// conditions are true:
|
||||
// - request’s current URL’s scheme is "http"
|
||||
// - request’s current URL’s host is a domain
|
||||
// - Matching request’s current URL’s host per Known HSTS Host Domain Name
|
||||
// Matching results in either a superdomain match with an asserted
|
||||
// includeSubDomains directive or a congruent match (with or without an
|
||||
// asserted includeSubDomains directive). [HSTS]
|
||||
// TODO
|
||||
|
||||
// 10. If recursive is false, then run the remaining steps in parallel.
|
||||
// TODO
|
||||
// 10. If recursive is false, then run the remaining steps in parallel.
|
||||
// TODO
|
||||
|
||||
// 11. If response is null, then set response to the result of running
|
||||
// the steps corresponding to the first matching statement:
|
||||
if (response === null) {
|
||||
const currentURL = requestCurrentURL(request)
|
||||
if (
|
||||
// - request’s current URL’s origin is same origin with request’s origin,
|
||||
// and request’s response tainting is "basic"
|
||||
(sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') ||
|
||||
// request’s current URL’s scheme is "data"
|
||||
(currentURL.protocol === 'data:') ||
|
||||
// - request’s mode is "navigate" or "websocket"
|
||||
(request.mode === 'navigate' || request.mode === 'websocket')
|
||||
) {
|
||||
// 1. Set request’s response tainting to "basic".
|
||||
request.responseTainting = 'basic'
|
||||
// 11. If response is null, then set response to the result of running
|
||||
// the steps corresponding to the first matching statement:
|
||||
if (response === null) {
|
||||
const currentURL = requestCurrentURL(request)
|
||||
if (
|
||||
// - request’s current URL’s origin is same origin with request’s origin,
|
||||
// and request’s response tainting is "basic"
|
||||
(sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') ||
|
||||
// request’s current URL’s scheme is "data"
|
||||
(currentURL.protocol === 'data:') ||
|
||||
// - request’s mode is "navigate" or "websocket"
|
||||
(request.mode === 'navigate' || request.mode === 'websocket')
|
||||
) {
|
||||
// 1. Set request’s response tainting to "basic".
|
||||
request.responseTainting = 'basic'
|
||||
|
||||
// 2. Return the result of running scheme fetch given fetchParams.
|
||||
response = await schemeFetch(fetchParams)
|
||||
|
||||
// request’s mode is "same-origin"
|
||||
} else if (request.mode === 'same-origin') {
|
||||
// 1. Return a network error.
|
||||
response = makeNetworkError('request mode cannot be "same-origin"')
|
||||
|
||||
// request’s mode is "no-cors"
|
||||
} else if (request.mode === 'no-cors') {
|
||||
// 1. If request’s redirect mode is not "follow", then return a network
|
||||
// error.
|
||||
if (request.redirect !== 'follow') {
|
||||
response = makeNetworkError(
|
||||
'redirect mode cannot be "follow" for "no-cors" request'
|
||||
)
|
||||
} else {
|
||||
// 2. Set request’s response tainting to "opaque".
|
||||
request.responseTainting = 'opaque'
|
||||
|
||||
// 3. Return the result of running scheme fetch given fetchParams.
|
||||
// 2. Return the result of running scheme fetch given fetchParams.
|
||||
response = await schemeFetch(fetchParams)
|
||||
|
||||
// request’s mode is "same-origin"
|
||||
} else if (request.mode === 'same-origin') {
|
||||
// 1. Return a network error.
|
||||
response = makeNetworkError('request mode cannot be "same-origin"')
|
||||
|
||||
// request’s mode is "no-cors"
|
||||
} else if (request.mode === 'no-cors') {
|
||||
// 1. If request’s redirect mode is not "follow", then return a network
|
||||
// error.
|
||||
if (request.redirect !== 'follow') {
|
||||
response = makeNetworkError(
|
||||
'redirect mode cannot be "follow" for "no-cors" request'
|
||||
)
|
||||
} else {
|
||||
// 2. Set request’s response tainting to "opaque".
|
||||
request.responseTainting = 'opaque'
|
||||
|
||||
// 3. Return the result of running scheme fetch given fetchParams.
|
||||
response = await schemeFetch(fetchParams)
|
||||
}
|
||||
// request’s current URL’s scheme is not an HTTP(S) scheme
|
||||
} else if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) {
|
||||
// Return a network error.
|
||||
response = makeNetworkError('URL scheme must be a HTTP(S) scheme')
|
||||
|
||||
// - request’s use-CORS-preflight flag is set
|
||||
// - request’s unsafe-request flag is set and either request’s method is
|
||||
// not a CORS-safelisted method or CORS-unsafe request-header names with
|
||||
// request’s header list is not empty
|
||||
// 1. Set request’s response tainting to "cors".
|
||||
// 2. Let corsWithPreflightResponse be the result of running HTTP fetch
|
||||
// given fetchParams and true.
|
||||
// 3. If corsWithPreflightResponse is a network error, then clear cache
|
||||
// entries using request.
|
||||
// 4. Return corsWithPreflightResponse.
|
||||
// TODO
|
||||
|
||||
// Otherwise
|
||||
} else {
|
||||
// 1. Set request’s response tainting to "cors".
|
||||
request.responseTainting = 'cors'
|
||||
|
||||
// 2. Return the result of running HTTP fetch given fetchParams.
|
||||
response = await httpFetch(fetchParams)
|
||||
}
|
||||
// request’s current URL’s scheme is not an HTTP(S) scheme
|
||||
} else if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) {
|
||||
// Return a network error.
|
||||
response = makeNetworkError('URL scheme must be a HTTP(S) scheme')
|
||||
|
||||
// - request’s use-CORS-preflight flag is set
|
||||
// - request’s unsafe-request flag is set and either request’s method is
|
||||
// not a CORS-safelisted method or CORS-unsafe request-header names with
|
||||
// request’s header list is not empty
|
||||
// 1. Set request’s response tainting to "cors".
|
||||
// 2. Let corsWithPreflightResponse be the result of running HTTP fetch
|
||||
// given fetchParams and true.
|
||||
// 3. If corsWithPreflightResponse is a network error, then clear cache
|
||||
// entries using request.
|
||||
// 4. Return corsWithPreflightResponse.
|
||||
// TODO
|
||||
|
||||
// Otherwise
|
||||
} else {
|
||||
// 1. Set request’s response tainting to "cors".
|
||||
request.responseTainting = 'cors'
|
||||
|
||||
// 2. Return the result of running HTTP fetch given fetchParams.
|
||||
response = await httpFetch(fetchParams)
|
||||
}
|
||||
}
|
||||
|
||||
// 12. If recursive is true, then return response.
|
||||
if (recursive) {
|
||||
return response
|
||||
}
|
||||
|
||||
// 13. If response is not a network error and response is not a filtered
|
||||
// response, then:
|
||||
if (response.status !== 0 && !response.internalResponse) {
|
||||
// If request’s response tainting is "cors", then:
|
||||
if (request.responseTainting === 'cors') {
|
||||
// 1. Let headerNames be the result of extracting header list values
|
||||
// given `Access-Control-Expose-Headers` and response’s header list.
|
||||
// TODO
|
||||
// 2. If request’s credentials mode is not "include" and headerNames
|
||||
// contains `*`, then set response’s CORS-exposed header-name list to
|
||||
// all unique header names in response’s header list.
|
||||
// TODO
|
||||
// 3. Otherwise, if headerNames is not null or failure, then set
|
||||
// response’s CORS-exposed header-name list to headerNames.
|
||||
// TODO
|
||||
}
|
||||
|
||||
// Set response to the following filtered response with response as its
|
||||
// internal response, depending on request’s response tainting:
|
||||
if (request.responseTainting === 'basic') {
|
||||
response = filterResponse(response, 'basic')
|
||||
} else if (request.responseTainting === 'cors') {
|
||||
response = filterResponse(response, 'cors')
|
||||
} else if (request.responseTainting === 'opaque') {
|
||||
response = filterResponse(response, 'opaque')
|
||||
} else {
|
||||
assert(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 14. Let internalResponse be response, if response is a network error,
|
||||
// and response’s internal response otherwise.
|
||||
let internalResponse =
|
||||
response.status === 0 ? response : response.internalResponse
|
||||
|
||||
// 15. If internalResponse’s URL list is empty, then set it to a clone of
|
||||
// request’s URL list.
|
||||
if (internalResponse.urlList.length === 0) {
|
||||
internalResponse.urlList.push(...request.urlList)
|
||||
}
|
||||
|
||||
// 16. If request’s timing allow failed flag is unset, then set
|
||||
// internalResponse’s timing allow passed flag.
|
||||
if (!request.timingAllowFailed) {
|
||||
response.timingAllowPassed = true
|
||||
}
|
||||
|
||||
// 17. If response is not a network error and any of the following returns
|
||||
// blocked
|
||||
// - should internalResponse to request be blocked as mixed content
|
||||
// - should internalResponse to request be blocked by Content Security Policy
|
||||
// - should internalResponse to request be blocked due to its MIME type
|
||||
// - should internalResponse to request be blocked due to nosniff
|
||||
// TODO
|
||||
|
||||
// 18. If response’s type is "opaque", internalResponse’s status is 206,
|
||||
// internalResponse’s range-requested flag is set, and request’s header
|
||||
// list does not contain `Range`, then set response and internalResponse
|
||||
// to a network error.
|
||||
if (
|
||||
response.type === 'opaque' &&
|
||||
internalResponse.status === 206 &&
|
||||
internalResponse.rangeRequested &&
|
||||
!request.headers.contains('range', true)
|
||||
) {
|
||||
response = internalResponse = makeNetworkError()
|
||||
}
|
||||
|
||||
// 19. If response is not a network error and either request’s method is
|
||||
// `HEAD` or `CONNECT`, or internalResponse’s status is a null body status,
|
||||
// set internalResponse’s body to null and disregard any enqueuing toward
|
||||
// it (if any).
|
||||
if (
|
||||
response.status !== 0 &&
|
||||
(request.method === 'HEAD' ||
|
||||
request.method === 'CONNECT' ||
|
||||
nullBodyStatus.includes(internalResponse.status))
|
||||
) {
|
||||
internalResponse.body = null
|
||||
fetchParams.controller.dump = true
|
||||
}
|
||||
|
||||
// 20. If request’s integrity metadata is not the empty string, then:
|
||||
if (request.integrity) {
|
||||
// 1. Let processBodyError be this step: run fetch finale given fetchParams
|
||||
// and a network error.
|
||||
const processBodyError = (reason) =>
|
||||
fetchFinale(fetchParams, makeNetworkError(reason))
|
||||
|
||||
// 2. If request’s response tainting is "opaque", or response’s body is null,
|
||||
// then run processBodyError and abort these steps.
|
||||
if (request.responseTainting === 'opaque' || response.body == null) {
|
||||
processBodyError(response.error)
|
||||
return
|
||||
// 12. If recursive is true, then return response.
|
||||
if (recursive) {
|
||||
return response
|
||||
}
|
||||
|
||||
// 3. Let processBody given bytes be these steps:
|
||||
const processBody = (bytes) => {
|
||||
// 1. If bytes do not match request’s integrity metadata,
|
||||
// then run processBodyError and abort these steps. [SRI]
|
||||
if (!bytesMatch(bytes, request.integrity)) {
|
||||
processBodyError('integrity mismatch')
|
||||
// 13. If response is not a network error and response is not a filtered
|
||||
// response, then:
|
||||
if (response.status !== 0 && !response.internalResponse) {
|
||||
// If request’s response tainting is "cors", then:
|
||||
if (request.responseTainting === 'cors') {
|
||||
// 1. Let headerNames be the result of extracting header list values
|
||||
// given `Access-Control-Expose-Headers` and response’s header list.
|
||||
// TODO
|
||||
// 2. If request’s credentials mode is not "include" and headerNames
|
||||
// contains `*`, then set response’s CORS-exposed header-name list to
|
||||
// all unique header names in response’s header list.
|
||||
// TODO
|
||||
// 3. Otherwise, if headerNames is not null or failure, then set
|
||||
// response’s CORS-exposed header-name list to headerNames.
|
||||
// TODO
|
||||
}
|
||||
|
||||
// Set response to the following filtered response with response as its
|
||||
// internal response, depending on request’s response tainting:
|
||||
if (request.responseTainting === 'basic') {
|
||||
response = filterResponse(response, 'basic')
|
||||
} else if (request.responseTainting === 'cors') {
|
||||
response = filterResponse(response, 'cors')
|
||||
} else if (request.responseTainting === 'opaque') {
|
||||
response = filterResponse(response, 'opaque')
|
||||
} else {
|
||||
assert(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 14. Let internalResponse be response, if response is a network error,
|
||||
// and response’s internal response otherwise.
|
||||
let internalResponse =
|
||||
response.status === 0 ? response : response.internalResponse
|
||||
|
||||
// 15. If internalResponse’s URL list is empty, then set it to a clone of
|
||||
// request’s URL list.
|
||||
if (internalResponse.urlList.length === 0) {
|
||||
internalResponse.urlList.push(...request.urlList)
|
||||
}
|
||||
|
||||
// 16. If request’s timing allow failed flag is unset, then set
|
||||
// internalResponse’s timing allow passed flag.
|
||||
if (!request.timingAllowFailed) {
|
||||
response.timingAllowPassed = true
|
||||
}
|
||||
|
||||
// 17. If response is not a network error and any of the following returns
|
||||
// blocked
|
||||
// - should internalResponse to request be blocked as mixed content
|
||||
// - should internalResponse to request be blocked by Content Security Policy
|
||||
// - should internalResponse to request be blocked due to its MIME type
|
||||
// - should internalResponse to request be blocked due to nosniff
|
||||
// TODO
|
||||
|
||||
// 18. If response’s type is "opaque", internalResponse’s status is 206,
|
||||
// internalResponse’s range-requested flag is set, and request’s header
|
||||
// list does not contain `Range`, then set response and internalResponse
|
||||
// to a network error.
|
||||
if (
|
||||
response.type === 'opaque' &&
|
||||
internalResponse.status === 206 &&
|
||||
internalResponse.rangeRequested &&
|
||||
!request.headers.contains('range', true)
|
||||
) {
|
||||
response = internalResponse = makeNetworkError()
|
||||
}
|
||||
|
||||
// 19. If response is not a network error and either request’s method is
|
||||
// `HEAD` or `CONNECT`, or internalResponse’s status is a null body status,
|
||||
// set internalResponse’s body to null and disregard any enqueuing toward
|
||||
// it (if any).
|
||||
if (
|
||||
response.status !== 0 &&
|
||||
(request.method === 'HEAD' ||
|
||||
request.method === 'CONNECT' ||
|
||||
nullBodyStatus.includes(internalResponse.status))
|
||||
) {
|
||||
internalResponse.body = null
|
||||
fetchParams.controller.dump = true
|
||||
}
|
||||
|
||||
// 20. If request’s integrity metadata is not the empty string, then:
|
||||
if (request.integrity) {
|
||||
// 1. Let processBodyError be this step: run fetch finale given fetchParams
|
||||
// and a network error.
|
||||
const processBodyError = (reason) =>
|
||||
fetchFinale(fetchParams, makeNetworkError(reason))
|
||||
|
||||
// 2. If request’s response tainting is "opaque", or response’s body is null,
|
||||
// then run processBodyError and abort these steps.
|
||||
if (request.responseTainting === 'opaque' || response.body == null) {
|
||||
processBodyError(response.error)
|
||||
return
|
||||
}
|
||||
|
||||
// 2. Set response’s body to bytes as a body.
|
||||
response.body = safelyExtractBody(bytes)[0]
|
||||
// 3. Let processBody given bytes be these steps:
|
||||
const processBody = (bytes) => {
|
||||
// 1. If bytes do not match request’s integrity metadata,
|
||||
// then run processBodyError and abort these steps. [SRI]
|
||||
if (!bytesMatch(bytes, request.integrity)) {
|
||||
processBodyError('integrity mismatch')
|
||||
return
|
||||
}
|
||||
|
||||
// 3. Run fetch finale given fetchParams and response.
|
||||
// 2. Set response’s body to bytes as a body.
|
||||
response.body = safelyExtractBody(bytes)[0]
|
||||
|
||||
// 3. Run fetch finale given fetchParams and response.
|
||||
fetchFinale(fetchParams, response)
|
||||
}
|
||||
|
||||
// 4. Fully read response’s body given processBody and processBodyError.
|
||||
fullyReadBody(response.body, processBody, processBodyError)
|
||||
} else {
|
||||
// 21. Otherwise, run fetch finale given fetchParams and response.
|
||||
fetchFinale(fetchParams, response)
|
||||
}
|
||||
|
||||
// 4. Fully read response’s body given processBody and processBodyError.
|
||||
await fullyReadBody(response.body, processBody, processBodyError)
|
||||
} else {
|
||||
// 21. Otherwise, run fetch finale given fetchParams and response.
|
||||
fetchFinale(fetchParams, response)
|
||||
} catch (err) {
|
||||
fetchParams.controller.terminate(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1909,15 +1910,11 @@ async function httpNetworkFetch (
|
|||
// cancelAlgorithm set to cancelAlgorithm.
|
||||
const stream = new ReadableStream(
|
||||
{
|
||||
async start (controller) {
|
||||
start (controller) {
|
||||
fetchParams.controller.controller = controller
|
||||
},
|
||||
async pull (controller) {
|
||||
await pullAlgorithm(controller)
|
||||
},
|
||||
async cancel (reason) {
|
||||
await cancelAlgorithm(reason)
|
||||
},
|
||||
pull: pullAlgorithm,
|
||||
cancel: cancelAlgorithm,
|
||||
type: 'bytes'
|
||||
}
|
||||
)
|
||||
|
|
@ -2055,7 +2052,7 @@ async function httpNetworkFetch (
|
|||
|
||||
function dispatch ({ body }) {
|
||||
const url = requestCurrentURL(request)
|
||||
/** @type {import('../..').Agent} */
|
||||
/** @type {import('../../..').Agent} */
|
||||
const agent = fetchParams.controller.dispatcher
|
||||
|
||||
return new Promise((resolve, reject) => agent.dispatch(
|
||||
|
|
@ -2104,12 +2101,11 @@ async function httpNetworkFetch (
|
|||
|
||||
onHeaders (status, rawHeaders, resume, statusText) {
|
||||
if (status < 200) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
/** @type {string[]} */
|
||||
let codings = []
|
||||
let location = ''
|
||||
|
||||
const headersList = new HeadersList()
|
||||
|
||||
|
|
@ -2122,7 +2118,7 @@ async function httpNetworkFetch (
|
|||
// "All content-coding values are case-insensitive..."
|
||||
codings = contentEncoding.toLowerCase().split(',').map((x) => x.trim())
|
||||
}
|
||||
location = headersList.get('location', true)
|
||||
const location = headersList.get('location', true)
|
||||
|
||||
this.body = new Readable({ read: resume })
|
||||
|
||||
|
|
|
|||
22
deps/undici/src/lib/web/fetch/request.js
vendored
22
deps/undici/src/lib/web/fetch/request.js
vendored
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
const { extractBody, mixinBody, cloneBody, bodyUnusable } = require('./body')
|
||||
const { Headers, fill: fillHeaders, HeadersList, setHeadersGuard, getHeadersGuard, setHeadersList, getHeadersList } = require('./headers')
|
||||
const { FinalizationRegistry } = require('./dispatcher-weakref')()
|
||||
const util = require('../../core/util')
|
||||
const nodeUtil = require('node:util')
|
||||
const {
|
||||
|
|
@ -109,8 +108,8 @@ class Request {
|
|||
const prefix = 'Request constructor'
|
||||
webidl.argumentLengthCheck(arguments, 1, prefix)
|
||||
|
||||
input = webidl.converters.RequestInfo(input, prefix, 'input')
|
||||
init = webidl.converters.RequestInit(init, prefix, 'init')
|
||||
input = webidl.converters.RequestInfo(input)
|
||||
init = webidl.converters.RequestInit(init)
|
||||
|
||||
// 1. Let request be null.
|
||||
let request = null
|
||||
|
|
@ -937,7 +936,7 @@ function cloneRequest (request) {
|
|||
// 2. If request’s body is non-null, set newRequest’s body to the
|
||||
// result of cloning request’s body.
|
||||
if (request.body != null) {
|
||||
newRequest.body = cloneBody(newRequest, request.body)
|
||||
newRequest.body = cloneBody(request.body)
|
||||
}
|
||||
|
||||
// 3. Return newRequest.
|
||||
|
|
@ -993,8 +992,13 @@ Object.defineProperties(Request.prototype, {
|
|||
|
||||
webidl.is.Request = webidl.util.MakeTypeAssertion(Request)
|
||||
|
||||
// https://fetch.spec.whatwg.org/#requestinfo
|
||||
webidl.converters.RequestInfo = function (V, prefix, argument) {
|
||||
/**
|
||||
* @param {*} V
|
||||
* @returns {import('../../../types/fetch').Request|string}
|
||||
*
|
||||
* @see https://fetch.spec.whatwg.org/#requestinfo
|
||||
*/
|
||||
webidl.converters.RequestInfo = function (V) {
|
||||
if (typeof V === 'string') {
|
||||
return webidl.converters.USVString(V)
|
||||
}
|
||||
|
|
@ -1006,7 +1010,11 @@ webidl.converters.RequestInfo = function (V, prefix, argument) {
|
|||
return webidl.converters.USVString(V)
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#requestinit
|
||||
/**
|
||||
* @param {*} V
|
||||
* @returns {import('../../../types/fetch').RequestInit}
|
||||
* @see https://fetch.spec.whatwg.org/#requestinit
|
||||
*/
|
||||
webidl.converters.RequestInit = webidl.dictionaryConverter([
|
||||
{
|
||||
key: 'method',
|
||||
|
|
|
|||
8
deps/undici/src/lib/web/fetch/response.js
vendored
8
deps/undici/src/lib/web/fetch/response.js
vendored
|
|
@ -1,7 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const { Headers, HeadersList, fill, getHeadersGuard, setHeadersGuard, setHeadersList } = require('./headers')
|
||||
const { extractBody, cloneBody, mixinBody, hasFinalizationRegistry, streamRegistry, bodyUnusable } = require('./body')
|
||||
const { extractBody, cloneBody, mixinBody, streamRegistry, bodyUnusable } = require('./body')
|
||||
const util = require('../../core/util')
|
||||
const nodeUtil = require('node:util')
|
||||
const { kEnumerableProperty } = util
|
||||
|
|
@ -352,7 +352,9 @@ function cloneResponse (response) {
|
|||
// 3. If response’s body is non-null, then set newResponse’s body to the
|
||||
// result of cloning response’s body.
|
||||
if (response.body != null) {
|
||||
newResponse.body = cloneBody(newResponse, response.body)
|
||||
newResponse.body = cloneBody(response.body)
|
||||
|
||||
streamRegistry.register(newResponse, new WeakRef(response.body.stream))
|
||||
}
|
||||
|
||||
// 4. Return newResponse.
|
||||
|
|
@ -552,7 +554,7 @@ function fromInnerResponse (innerResponse, guard) {
|
|||
setHeadersList(headers, innerResponse.headersList)
|
||||
setHeadersGuard(headers, guard)
|
||||
|
||||
if (hasFinalizationRegistry && innerResponse.body?.stream) {
|
||||
if (innerResponse.body?.stream) {
|
||||
// If the target (response) is reclaimed, the cleanup callback may be called at some point with
|
||||
// the held value provided for it (innerResponse.body.stream). The held value can be any value:
|
||||
// a primitive or an object, even undefined. If the held value is an object, the registry keeps
|
||||
|
|
|
|||
44
deps/undici/src/lib/web/fetch/util.js
vendored
44
deps/undici/src/lib/web/fetch/util.js
vendored
|
|
@ -924,17 +924,6 @@ function sameOrigin (A, B) {
|
|||
return false
|
||||
}
|
||||
|
||||
function createDeferredPromise () {
|
||||
let res
|
||||
let rej
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
res = resolve
|
||||
rej = reject
|
||||
})
|
||||
|
||||
return { promise, resolve: res, reject: rej }
|
||||
}
|
||||
|
||||
function isAborted (fetchParams) {
|
||||
return fetchParams.controller.state === 'aborted'
|
||||
}
|
||||
|
|
@ -1177,6 +1166,11 @@ function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueInde
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {import('./body').ExtractBodyResult} body
|
||||
* @param {(bytes: Uint8Array) => void} processBody
|
||||
* @param {(error: Error) => void} processBodyError
|
||||
* @returns {void}
|
||||
*
|
||||
* @see https://fetch.spec.whatwg.org/#body-fully-read
|
||||
*/
|
||||
function fullyReadBody (body, processBody, processBodyError) {
|
||||
|
|
@ -1191,20 +1185,17 @@ function fullyReadBody (body, processBody, processBodyError) {
|
|||
// with taskDestination.
|
||||
const errorSteps = processBodyError
|
||||
|
||||
try {
|
||||
// 4. Let reader be the result of getting a reader for body’s stream.
|
||||
// If that threw an exception, then run errorSteps with that
|
||||
// exception and return.
|
||||
let reader
|
||||
const reader = body.stream.getReader()
|
||||
|
||||
try {
|
||||
reader = body.stream.getReader()
|
||||
// 5. Read all bytes from reader, given successSteps and errorSteps.
|
||||
readAllBytes(reader, successSteps, errorSteps)
|
||||
} catch (e) {
|
||||
errorSteps(e)
|
||||
return
|
||||
}
|
||||
|
||||
// 5. Read all bytes from reader, given successSteps and errorSteps.
|
||||
readAllBytes(reader, successSteps, errorSteps)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1241,15 +1232,16 @@ function isomorphicEncode (input) {
|
|||
/**
|
||||
* @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes
|
||||
* @see https://streams.spec.whatwg.org/#read-loop
|
||||
* @param {ReadableStreamDefaultReader} reader
|
||||
* @param {ReadableStream<Uint8Array<ArrayBuffer>>} reader
|
||||
* @param {(bytes: Uint8Array) => void} successSteps
|
||||
* @param {(error: Error) => void} failureSteps
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function readAllBytes (reader, successSteps, failureSteps) {
|
||||
const bytes = []
|
||||
let byteLength = 0
|
||||
|
||||
try {
|
||||
const bytes = []
|
||||
let byteLength = 0
|
||||
|
||||
do {
|
||||
const { done, value: chunk } = await reader.read()
|
||||
|
||||
|
|
@ -1324,10 +1316,17 @@ function urlIsHttpHttpsScheme (url) {
|
|||
return protocol === 'http:' || protocol === 'https:'
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} RangeHeaderValue
|
||||
* @property {number|null} rangeStartValue
|
||||
* @property {number|null} rangeEndValue
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see https://fetch.spec.whatwg.org/#simple-range-header-value
|
||||
* @param {string} value
|
||||
* @param {boolean} allowWhitespace
|
||||
* @return {RangeHeaderValue|'failure'}
|
||||
*/
|
||||
function simpleRangeHeaderValue (value, allowWhitespace) {
|
||||
// 1. Let data be the isomorphic decoding of value.
|
||||
|
|
@ -1732,7 +1731,6 @@ module.exports = {
|
|||
isAborted,
|
||||
isCancelled,
|
||||
isValidEncodedURL,
|
||||
createDeferredPromise,
|
||||
ReadableStreamFrom,
|
||||
tryUpgradeRequestToAPotentiallyTrustworthyURL,
|
||||
clampAndCoarsenConnectionTimingInfo,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
const { uid, states, sentCloseFrameState, emptyBuffer, opcodes } = require('./constants')
|
||||
const { parseExtensions, isClosed, isClosing, isEstablished, validateCloseCodeAndReason } = require('./util')
|
||||
const { channels } = require('../../core/diagnostics')
|
||||
const { makeRequest } = require('../fetch/request')
|
||||
const { fetching } = require('../fetch/index')
|
||||
const { Headers, getHeadersList } = require('../fetch/headers')
|
||||
|
|
@ -200,14 +199,6 @@ function establishWebSocketConnection (url, protocols, client, handler, options)
|
|||
response.socket.on('close', handler.onSocketClose)
|
||||
response.socket.on('error', handler.onSocketError)
|
||||
|
||||
if (channels.open.hasSubscribers) {
|
||||
channels.open.publish({
|
||||
address: response.socket.address(),
|
||||
protocol: secProtocol,
|
||||
extensions: secExtension
|
||||
})
|
||||
}
|
||||
|
||||
handler.wasEverConnected = true
|
||||
handler.onConnectionEstablished(response, extensions)
|
||||
}
|
||||
|
|
|
|||
14
deps/undici/src/lib/web/websocket/receiver.js
vendored
14
deps/undici/src/lib/web/websocket/receiver.js
vendored
|
|
@ -3,7 +3,6 @@
|
|||
const { Writable } = require('node:stream')
|
||||
const assert = require('node:assert')
|
||||
const { parserStates, opcodes, states, emptyBuffer, sentCloseFrameState } = require('./constants')
|
||||
const { channels } = require('../../core/diagnostics')
|
||||
const {
|
||||
isValidStatusCode,
|
||||
isValidOpcode,
|
||||
|
|
@ -423,22 +422,13 @@ class ByteParser extends Writable {
|
|||
|
||||
this.#handler.socket.write(frame.createFrame(opcodes.PONG))
|
||||
|
||||
if (channels.ping.hasSubscribers) {
|
||||
channels.ping.publish({
|
||||
payload: body
|
||||
})
|
||||
}
|
||||
this.#handler.onPing(body)
|
||||
}
|
||||
} else if (opcode === opcodes.PONG) {
|
||||
// A Pong frame MAY be sent unsolicited. This serves as a
|
||||
// unidirectional heartbeat. A response to an unsolicited Pong frame is
|
||||
// not expected.
|
||||
|
||||
if (channels.pong.hasSubscribers) {
|
||||
channels.pong.publish({
|
||||
payload: body
|
||||
})
|
||||
}
|
||||
this.#handler.onPong(body)
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const { createDeferredPromise, environmentSettingsObject } = require('../../fetch/util')
|
||||
const { createDeferredPromise } = require('../../../util/promise')
|
||||
const { environmentSettingsObject } = require('../../fetch/util')
|
||||
const { states, opcodes, sentCloseFrameState } = require('../constants')
|
||||
const { webidl } = require('../../webidl')
|
||||
const { getURLRecord, isValidSubprotocol, isEstablished, utf8Decode } = require('../util')
|
||||
|
|
@ -21,11 +22,11 @@ class WebSocketStream {
|
|||
#url
|
||||
|
||||
// Each WebSocketStream object has an associated opened promise , which is a promise.
|
||||
/** @type {ReturnType<typeof createDeferredPromise>} */
|
||||
/** @type {import('../../../util/promise').DeferredPromise} */
|
||||
#openedPromise
|
||||
|
||||
// Each WebSocketStream object has an associated closed promise , which is a promise.
|
||||
/** @type {ReturnType<typeof createDeferredPromise>} */
|
||||
/** @type {import('../../../util/promise').DeferredPromise} */
|
||||
#closedPromise
|
||||
|
||||
// Each WebSocketStream object has an associated readable stream , which is a ReadableStream .
|
||||
|
|
@ -64,6 +65,8 @@ class WebSocketStream {
|
|||
this.#handler.socket.destroy()
|
||||
},
|
||||
onSocketClose: () => this.#onSocketClose(),
|
||||
onPing: () => {},
|
||||
onPong: () => {},
|
||||
|
||||
readyState: states.CONNECTING,
|
||||
socket: null,
|
||||
|
|
@ -388,7 +391,7 @@ class WebSocketStream {
|
|||
// 6. If the connection was closed cleanly ,
|
||||
if (wasClean) {
|
||||
// 6.1. Close stream ’s readable stream .
|
||||
this.#readableStream.cancel().catch(() => {})
|
||||
this.#readableStreamController.close()
|
||||
|
||||
// 6.2. Error stream ’s writable stream with an " InvalidStateError " DOMException indicating that a closed WebSocketStream cannot be written to.
|
||||
if (!this.#writableStream.locked) {
|
||||
|
|
|
|||
58
deps/undici/src/lib/web/websocket/websocket.js
vendored
58
deps/undici/src/lib/web/websocket/websocket.js
vendored
|
|
@ -8,6 +8,7 @@ const {
|
|||
isConnecting,
|
||||
isEstablished,
|
||||
isClosing,
|
||||
isClosed,
|
||||
isValidSubprotocol,
|
||||
fireEvent,
|
||||
utf8Decode,
|
||||
|
|
@ -21,6 +22,7 @@ const { getGlobalDispatcher } = require('../../global')
|
|||
const { types } = require('node:util')
|
||||
const { ErrorEvent, CloseEvent, createFastMessageEvent } = require('./events')
|
||||
const { SendQueue } = require('./sender')
|
||||
const { WebsocketFrameSend } = require('./frame')
|
||||
const { channels } = require('../../core/diagnostics')
|
||||
|
||||
/**
|
||||
|
|
@ -33,6 +35,8 @@ const { channels } = require('../../core/diagnostics')
|
|||
* @property {(chunk: Buffer) => void} onSocketData
|
||||
* @property {(err: Error) => void} onSocketError
|
||||
* @property {() => void} onSocketClose
|
||||
* @property {(body: Buffer) => void} onPing
|
||||
* @property {(body: Buffer) => void} onPong
|
||||
*
|
||||
* @property {number} readyState
|
||||
* @property {import('stream').Duplex} socket
|
||||
|
|
@ -79,6 +83,22 @@ class WebSocket extends EventTarget {
|
|||
this.#handler.socket.destroy()
|
||||
},
|
||||
onSocketClose: () => this.#onSocketClose(),
|
||||
onPing: (body) => {
|
||||
if (channels.ping.hasSubscribers) {
|
||||
channels.ping.publish({
|
||||
payload: body,
|
||||
websocket: this
|
||||
})
|
||||
}
|
||||
},
|
||||
onPong: (body) => {
|
||||
if (channels.pong.hasSubscribers) {
|
||||
channels.pong.publish({
|
||||
payload: body,
|
||||
websocket: this
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
readyState: states.CONNECTING,
|
||||
socket: null,
|
||||
|
|
@ -460,6 +480,15 @@ class WebSocket extends EventTarget {
|
|||
|
||||
// 4. Fire an event named open at the WebSocket object.
|
||||
fireEvent('open', this)
|
||||
|
||||
if (channels.open.hasSubscribers) {
|
||||
channels.open.publish({
|
||||
address: response.socket.address(),
|
||||
protocol: this.#protocol,
|
||||
extensions: this.#extensions,
|
||||
websocket: this
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#onFail (code, reason, cause) {
|
||||
|
|
@ -586,8 +615,34 @@ class WebSocket extends EventTarget {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {WebSocket} ws
|
||||
* @param {Buffer|undefined} buffer
|
||||
*/
|
||||
static ping (ws, buffer) {
|
||||
if (Buffer.isBuffer(buffer)) {
|
||||
if (buffer.length > 125) {
|
||||
throw new TypeError('A PING frame cannot have a body larger than 125 bytes.')
|
||||
}
|
||||
} else if (buffer !== undefined) {
|
||||
throw new TypeError('Expected buffer payload')
|
||||
}
|
||||
|
||||
// An endpoint MAY send a Ping frame any time after the connection is
|
||||
// established and before the connection is closed.
|
||||
const readyState = ws.#handler.readyState
|
||||
|
||||
if (isEstablished(readyState) && !isClosing(readyState) && !isClosed(readyState)) {
|
||||
const frame = new WebsocketFrameSend(buffer)
|
||||
ws.#handler.socket.write(frame.createFrame(opcodes.PING))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { ping } = WebSocket
|
||||
Reflect.deleteProperty(WebSocket, 'ping')
|
||||
|
||||
// https://websockets.spec.whatwg.org/#dom-websocket-connecting
|
||||
WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING
|
||||
// https://websockets.spec.whatwg.org/#dom-websocket-open
|
||||
|
|
@ -682,5 +737,6 @@ webidl.converters.WebSocketSendData = function (V) {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
WebSocket
|
||||
WebSocket,
|
||||
ping
|
||||
}
|
||||
|
|
|
|||
796
deps/undici/src/package-lock.json
generated
vendored
796
deps/undici/src/package-lock.json
generated
vendored
File diff suppressed because it is too large
Load Diff
4
deps/undici/src/package.json
vendored
4
deps/undici/src/package.json
vendored
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "undici",
|
||||
"version": "7.11.0",
|
||||
"version": "7.12.0",
|
||||
"description": "An HTTP/1.1 client, written from scratch for Node.js",
|
||||
"homepage": "https://undici.nodejs.org",
|
||||
"bugs": {
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
"test:tdd:node-test": "borp -p \"test/node-test/**/*.js\" -w",
|
||||
"test:typescript": "tsd && tsc test/imports/undici-import.ts --typeRoots ./types --noEmit && tsc ./types/*.d.ts --noEmit --typeRoots ./types",
|
||||
"test:webidl": "borp -p \"test/webidl/*.js\"",
|
||||
"test:websocket": "borp -p \"test/websocket/*.js\"",
|
||||
"test:websocket": "borp -p \"test/websocket/**/*.js\"",
|
||||
"test:websocket:autobahn": "node test/autobahn/client.js",
|
||||
"test:websocket:autobahn:report": "node test/autobahn/report.js",
|
||||
"test:wpt": "node test/wpt/start-fetch.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node test/wpt/start-websockets.mjs && node test/wpt/start-cacheStorage.mjs && node test/wpt/start-eventsource.mjs",
|
||||
|
|
|
|||
10
deps/undici/src/types/webidl.d.ts
vendored
10
deps/undici/src/types/webidl.d.ts
vendored
|
|
@ -182,6 +182,16 @@ interface WebidlConverters {
|
|||
|
||||
['record<ByteString, ByteString>']: RecordConverter<string, string>
|
||||
|
||||
/**
|
||||
* @see https://fetch.spec.whatwg.org/#requestinfo
|
||||
*/
|
||||
RequestInfo (V: unknown): undici.Request | string
|
||||
|
||||
/**
|
||||
* @see https://fetch.spec.whatwg.org/#requestinit
|
||||
*/
|
||||
RequestInit (V: unknown): undici.RequestInit
|
||||
|
||||
[Key: string]: (...args: any[]) => unknown
|
||||
}
|
||||
|
||||
|
|
|
|||
2
deps/undici/src/types/websocket.d.ts
vendored
2
deps/undici/src/types/websocket.d.ts
vendored
|
|
@ -182,3 +182,5 @@ export declare const WebSocketError: {
|
|||
prototype: WebSocketError
|
||||
new (type: string, init?: WebSocketCloseInfo): WebSocketError
|
||||
}
|
||||
|
||||
export declare const ping: (ws: WebSocket, body?: Buffer) => void
|
||||
|
|
|
|||
391
deps/undici/undici.js
vendored
391
deps/undici/undici.js
vendored
|
|
@ -947,7 +947,7 @@ var require_tree = __commonJS({
|
|||
}
|
||||
/**
|
||||
* @param {Uint8Array} key
|
||||
* @return {TstNode | null}
|
||||
* @returns {TstNode | null}
|
||||
*/
|
||||
search(key) {
|
||||
const keylength = key.length;
|
||||
|
|
@ -2359,7 +2359,8 @@ var require_request = __commonJS({
|
|||
reset,
|
||||
expectContinue,
|
||||
servername,
|
||||
throwOnError
|
||||
throwOnError,
|
||||
maxRedirections
|
||||
}, handler) {
|
||||
if (typeof path !== "string") {
|
||||
throw new InvalidArgumentError("path must be a string");
|
||||
|
|
@ -2391,6 +2392,9 @@ var require_request = __commonJS({
|
|||
if (throwOnError != null) {
|
||||
throw new InvalidArgumentError("invalid throwOnError");
|
||||
}
|
||||
if (maxRedirections != null && maxRedirections !== 0) {
|
||||
throw new InvalidArgumentError("maxRedirections is not supported, use the redirect interceptor");
|
||||
}
|
||||
this.headersTimeout = headersTimeout;
|
||||
this.bodyTimeout = bodyTimeout;
|
||||
this.method = method;
|
||||
|
|
@ -4970,16 +4974,6 @@ var require_util2 = __commonJS({
|
|||
return false;
|
||||
}
|
||||
__name(sameOrigin, "sameOrigin");
|
||||
function createDeferredPromise() {
|
||||
let res;
|
||||
let rej;
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
res = resolve;
|
||||
rej = reject;
|
||||
});
|
||||
return { promise, resolve: res, reject: rej };
|
||||
}
|
||||
__name(createDeferredPromise, "createDeferredPromise");
|
||||
function isAborted(fetchParams) {
|
||||
return fetchParams.controller.state === "aborted";
|
||||
}
|
||||
|
|
@ -5136,14 +5130,12 @@ var require_util2 = __commonJS({
|
|||
function fullyReadBody(body, processBody, processBodyError) {
|
||||
const successSteps = processBody;
|
||||
const errorSteps = processBodyError;
|
||||
let reader;
|
||||
try {
|
||||
reader = body.stream.getReader();
|
||||
const reader = body.stream.getReader();
|
||||
readAllBytes(reader, successSteps, errorSteps);
|
||||
} catch (e) {
|
||||
errorSteps(e);
|
||||
return;
|
||||
}
|
||||
readAllBytes(reader, successSteps, errorSteps);
|
||||
}
|
||||
__name(fullyReadBody, "fullyReadBody");
|
||||
function readableStreamClose(controller) {
|
||||
|
|
@ -5164,9 +5156,9 @@ var require_util2 = __commonJS({
|
|||
}
|
||||
__name(isomorphicEncode, "isomorphicEncode");
|
||||
async function readAllBytes(reader, successSteps, failureSteps) {
|
||||
const bytes = [];
|
||||
let byteLength = 0;
|
||||
try {
|
||||
const bytes = [];
|
||||
let byteLength = 0;
|
||||
do {
|
||||
const { done, value: chunk } = await reader.read();
|
||||
if (done) {
|
||||
|
|
@ -5423,7 +5415,6 @@ var require_util2 = __commonJS({
|
|||
isAborted,
|
||||
isCancelled,
|
||||
isValidEncodedURL,
|
||||
createDeferredPromise,
|
||||
ReadableStreamFrom,
|
||||
tryUpgradeRequestToAPotentiallyTrustworthyURL,
|
||||
clampAndCoarsenConnectionTimingInfo,
|
||||
|
|
@ -5921,6 +5912,26 @@ var require_formdata_parser = __commonJS({
|
|||
}
|
||||
});
|
||||
|
||||
// lib/util/promise.js
|
||||
var require_promise = __commonJS({
|
||||
"lib/util/promise.js"(exports2, module2) {
|
||||
"use strict";
|
||||
function createDeferredPromise() {
|
||||
let res;
|
||||
let rej;
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
res = resolve;
|
||||
rej = reject;
|
||||
});
|
||||
return { promise, resolve: res, reject: rej };
|
||||
}
|
||||
__name(createDeferredPromise, "createDeferredPromise");
|
||||
module2.exports = {
|
||||
createDeferredPromise
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// lib/web/fetch/body.js
|
||||
var require_body = __commonJS({
|
||||
"lib/web/fetch/body.js"(exports2, module2) {
|
||||
|
|
@ -5929,7 +5940,6 @@ var require_body = __commonJS({
|
|||
var {
|
||||
ReadableStreamFrom,
|
||||
readableStreamClose,
|
||||
createDeferredPromise,
|
||||
fullyReadBody,
|
||||
extractMimeType,
|
||||
utf8DecodeBytes
|
||||
|
|
@ -5942,6 +5952,7 @@ var require_body = __commonJS({
|
|||
var { isArrayBuffer } = require("node:util/types");
|
||||
var { serializeAMimeType } = require_data_url();
|
||||
var { multipartFormDataParser } = require_formdata_parser();
|
||||
var { createDeferredPromise } = require_promise();
|
||||
var random;
|
||||
try {
|
||||
const crypto = require("node:crypto");
|
||||
|
|
@ -5953,16 +5964,12 @@ var require_body = __commonJS({
|
|||
function noop() {
|
||||
}
|
||||
__name(noop, "noop");
|
||||
var hasFinalizationRegistry = globalThis.FinalizationRegistry;
|
||||
var streamRegistry;
|
||||
if (hasFinalizationRegistry) {
|
||||
streamRegistry = new FinalizationRegistry((weakRef) => {
|
||||
const stream = weakRef.deref();
|
||||
if (stream && !stream.locked && !isDisturbed(stream) && !isErrored(stream)) {
|
||||
stream.cancel("Response object has been garbage collected").catch(noop);
|
||||
}
|
||||
});
|
||||
}
|
||||
var streamRegistry = new FinalizationRegistry((weakRef) => {
|
||||
const stream = weakRef.deref();
|
||||
if (stream && !stream.locked && !isDisturbed(stream) && !isErrored(stream)) {
|
||||
stream.cancel("Response object has been garbage collected").catch(noop);
|
||||
}
|
||||
});
|
||||
function extractBody(object, keepalive = false) {
|
||||
let stream = null;
|
||||
if (webidl.is.ReadableStream(object)) {
|
||||
|
|
@ -6108,11 +6115,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
|
|||
return extractBody(object, keepalive);
|
||||
}
|
||||
__name(safelyExtractBody, "safelyExtractBody");
|
||||
function cloneBody(instance, body) {
|
||||
const [out1, out2] = body.stream.tee();
|
||||
if (hasFinalizationRegistry) {
|
||||
streamRegistry.register(instance, new WeakRef(out1));
|
||||
}
|
||||
function cloneBody(body) {
|
||||
const { 0: out1, 1: out2 } = body.stream.tee();
|
||||
body.stream = out1;
|
||||
return {
|
||||
stream: out2,
|
||||
|
|
@ -6238,7 +6242,6 @@ Content-Type: ${value.type || "application/octet-stream"}\r
|
|||
cloneBody,
|
||||
mixinBody,
|
||||
streamRegistry,
|
||||
hasFinalizationRegistry,
|
||||
bodyUnusable
|
||||
};
|
||||
}
|
||||
|
|
@ -6303,15 +6306,15 @@ var require_client_h1 = __commonJS({
|
|||
var FastBuffer = Buffer[Symbol.species];
|
||||
var removeAllListeners = util.removeAllListeners;
|
||||
var extractBody;
|
||||
async function lazyllhttp() {
|
||||
function lazyllhttp() {
|
||||
const llhttpWasmData = process.env.JEST_WORKER_ID ? require_llhttp_wasm() : void 0;
|
||||
let mod;
|
||||
try {
|
||||
mod = await WebAssembly.compile(require_llhttp_simd_wasm());
|
||||
mod = new WebAssembly.Module(require_llhttp_simd_wasm());
|
||||
} catch (e) {
|
||||
mod = await WebAssembly.compile(llhttpWasmData || require_llhttp_wasm());
|
||||
mod = new WebAssembly.Module(llhttpWasmData || require_llhttp_wasm());
|
||||
}
|
||||
return await WebAssembly.instantiate(mod, {
|
||||
return new WebAssembly.Instance(mod, {
|
||||
env: {
|
||||
/**
|
||||
* @param {number} p
|
||||
|
|
@ -6398,8 +6401,6 @@ var require_client_h1 = __commonJS({
|
|||
}
|
||||
__name(lazyllhttp, "lazyllhttp");
|
||||
var llhttpInstance = null;
|
||||
var llhttpPromise = lazyllhttp();
|
||||
llhttpPromise.catch();
|
||||
var currentParser = null;
|
||||
var currentBufferRef = null;
|
||||
var currentBufferSize = 0;
|
||||
|
|
@ -6811,7 +6812,7 @@ var require_client_h1 = __commonJS({
|
|||
util.destroy(socket, new InformationalError("reset"));
|
||||
return constants.ERROR.PAUSED;
|
||||
} else if (client[kPipelining] == null || client[kPipelining] === 1) {
|
||||
setImmediate(() => client[kResume]());
|
||||
setImmediate(client[kResume]);
|
||||
} else {
|
||||
client[kResume]();
|
||||
}
|
||||
|
|
@ -6838,12 +6839,7 @@ var require_client_h1 = __commonJS({
|
|||
async function connectH1(client, socket) {
|
||||
client[kSocket] = socket;
|
||||
if (!llhttpInstance) {
|
||||
const noop = /* @__PURE__ */ __name(() => {
|
||||
}, "noop");
|
||||
socket.on("error", noop);
|
||||
llhttpInstance = await llhttpPromise;
|
||||
llhttpPromise = null;
|
||||
socket.off("error", noop);
|
||||
llhttpInstance = lazyllhttp();
|
||||
}
|
||||
if (socket.errored) {
|
||||
throw socket.errored;
|
||||
|
|
@ -7185,9 +7181,9 @@ upgrade: ${upgrade}\r
|
|||
}
|
||||
socket.on("drain", onDrain).on("error", onFinished);
|
||||
if (body.errorEmitted ?? body.errored) {
|
||||
setImmediate(() => onFinished(body.errored));
|
||||
setImmediate(onFinished, body.errored);
|
||||
} else if (body.endEmitted ?? body.readableEnded) {
|
||||
setImmediate(() => onFinished(null));
|
||||
setImmediate(onFinished, null);
|
||||
}
|
||||
if (body.closeEmitted ?? body.closed) {
|
||||
setImmediate(onClose);
|
||||
|
|
@ -9636,7 +9632,7 @@ var require_response = __commonJS({
|
|||
"lib/web/fetch/response.js"(exports2, module2) {
|
||||
"use strict";
|
||||
var { Headers, HeadersList, fill, getHeadersGuard, setHeadersGuard, setHeadersList } = require_headers();
|
||||
var { extractBody, cloneBody, mixinBody, hasFinalizationRegistry, streamRegistry, bodyUnusable } = require_body();
|
||||
var { extractBody, cloneBody, mixinBody, streamRegistry, bodyUnusable } = require_body();
|
||||
var util = require_util();
|
||||
var nodeUtil = require("node:util");
|
||||
var { kEnumerableProperty } = util;
|
||||
|
|
@ -9867,7 +9863,8 @@ var require_response = __commonJS({
|
|||
}
|
||||
const newResponse = makeResponse({ ...response, body: null });
|
||||
if (response.body != null) {
|
||||
newResponse.body = cloneBody(newResponse, response.body);
|
||||
newResponse.body = cloneBody(response.body);
|
||||
streamRegistry.register(newResponse, new WeakRef(response.body.stream));
|
||||
}
|
||||
return newResponse;
|
||||
}
|
||||
|
|
@ -10000,7 +9997,7 @@ var require_response = __commonJS({
|
|||
setResponseHeaders(response, headers);
|
||||
setHeadersList(headers, innerResponse.headersList);
|
||||
setHeadersGuard(headers, guard);
|
||||
if (hasFinalizationRegistry && innerResponse.body?.stream) {
|
||||
if (innerResponse.body?.stream) {
|
||||
streamRegistry.register(response, new WeakRef(innerResponse.body.stream));
|
||||
}
|
||||
return response;
|
||||
|
|
@ -10064,23 +10061,12 @@ var require_response = __commonJS({
|
|||
}
|
||||
});
|
||||
|
||||
// lib/web/fetch/dispatcher-weakref.js
|
||||
var require_dispatcher_weakref = __commonJS({
|
||||
"lib/web/fetch/dispatcher-weakref.js"(exports2, module2) {
|
||||
"use strict";
|
||||
module2.exports = function() {
|
||||
return { WeakRef, FinalizationRegistry };
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// lib/web/fetch/request.js
|
||||
var require_request2 = __commonJS({
|
||||
"lib/web/fetch/request.js"(exports2, module2) {
|
||||
"use strict";
|
||||
var { extractBody, mixinBody, cloneBody, bodyUnusable } = require_body();
|
||||
var { Headers, fill: fillHeaders, HeadersList, setHeadersGuard, getHeadersGuard, setHeadersList, getHeadersList } = require_headers();
|
||||
var { FinalizationRegistry: FinalizationRegistry2 } = require_dispatcher_weakref()();
|
||||
var util = require_util();
|
||||
var nodeUtil = require("node:util");
|
||||
var {
|
||||
|
|
@ -10105,7 +10091,7 @@ var require_request2 = __commonJS({
|
|||
var assert = require("node:assert");
|
||||
var { getMaxListeners, setMaxListeners, defaultMaxListeners } = require("node:events");
|
||||
var kAbortController = Symbol("abortController");
|
||||
var requestFinalizer = new FinalizationRegistry2(({ signal, abort }) => {
|
||||
var requestFinalizer = new FinalizationRegistry(({ signal, abort }) => {
|
||||
signal.removeEventListener("abort", abort);
|
||||
});
|
||||
var dependentControllerMap = /* @__PURE__ */ new WeakMap();
|
||||
|
|
@ -10161,8 +10147,8 @@ var require_request2 = __commonJS({
|
|||
}
|
||||
const prefix = "Request constructor";
|
||||
webidl.argumentLengthCheck(arguments, 1, prefix);
|
||||
input = webidl.converters.RequestInfo(input, prefix, "input");
|
||||
init = webidl.converters.RequestInit(init, prefix, "init");
|
||||
input = webidl.converters.RequestInfo(input);
|
||||
init = webidl.converters.RequestInit(init);
|
||||
let request = null;
|
||||
let fallbackMode = null;
|
||||
const baseUrl = environmentSettingsObject.settingsObject.baseUrl;
|
||||
|
|
@ -10685,7 +10671,7 @@ var require_request2 = __commonJS({
|
|||
function cloneRequest(request) {
|
||||
const newRequest = makeRequest({ ...request, body: null });
|
||||
if (request.body != null) {
|
||||
newRequest.body = cloneBody(newRequest, request.body);
|
||||
newRequest.body = cloneBody(request.body);
|
||||
}
|
||||
return newRequest;
|
||||
}
|
||||
|
|
@ -10729,7 +10715,7 @@ var require_request2 = __commonJS({
|
|||
}
|
||||
});
|
||||
webidl.is.Request = webidl.util.MakeTypeAssertion(Request);
|
||||
webidl.converters.RequestInfo = function(V, prefix, argument) {
|
||||
webidl.converters.RequestInfo = function(V) {
|
||||
if (typeof V === "string") {
|
||||
return webidl.converters.USVString(V);
|
||||
}
|
||||
|
|
@ -10863,7 +10849,6 @@ var require_fetch = __commonJS({
|
|||
crossOriginResourcePolicyCheck,
|
||||
determineRequestsReferrer,
|
||||
coarsenedSharedCurrentTime,
|
||||
createDeferredPromise,
|
||||
sameOrigin,
|
||||
isCancelled,
|
||||
isAborted,
|
||||
|
|
@ -10896,6 +10881,7 @@ var require_fetch = __commonJS({
|
|||
var { getGlobalDispatcher: getGlobalDispatcher2 } = require_global2();
|
||||
var { webidl } = require_webidl();
|
||||
var { STATUS_CODES } = require("node:http");
|
||||
var { createDeferredPromise } = require_promise();
|
||||
var GET_OR_HEAD = ["GET", "HEAD"];
|
||||
var defaultUserAgent = typeof __UNDICI_IS_NODE__ !== "undefined" || true ? "node" : "undici";
|
||||
var resolveObjectURL;
|
||||
|
|
@ -11118,104 +11104,106 @@ var require_fetch = __commonJS({
|
|||
}
|
||||
if (subresourceSet.has(request.destination)) {
|
||||
}
|
||||
mainFetch(fetchParams).catch((err) => {
|
||||
fetchParams.controller.terminate(err);
|
||||
});
|
||||
mainFetch(fetchParams, false);
|
||||
return fetchParams.controller;
|
||||
}
|
||||
__name(fetching, "fetching");
|
||||
async function mainFetch(fetchParams, recursive = false) {
|
||||
const request = fetchParams.request;
|
||||
let response = null;
|
||||
if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) {
|
||||
response = makeNetworkError("local URLs only");
|
||||
}
|
||||
tryUpgradeRequestToAPotentiallyTrustworthyURL(request);
|
||||
if (requestBadPort(request) === "blocked") {
|
||||
response = makeNetworkError("bad port");
|
||||
}
|
||||
if (request.referrerPolicy === "") {
|
||||
request.referrerPolicy = request.policyContainer.referrerPolicy;
|
||||
}
|
||||
if (request.referrer !== "no-referrer") {
|
||||
request.referrer = determineRequestsReferrer(request);
|
||||
}
|
||||
if (response === null) {
|
||||
const currentURL = requestCurrentURL(request);
|
||||
if (
|
||||
// - request?s current URL?s origin is same origin with request?s origin,
|
||||
// and request?s response tainting is "basic"
|
||||
sameOrigin(currentURL, request.url) && request.responseTainting === "basic" || // request?s current URL?s scheme is "data"
|
||||
currentURL.protocol === "data:" || // - request?s mode is "navigate" or "websocket"
|
||||
(request.mode === "navigate" || request.mode === "websocket")
|
||||
) {
|
||||
request.responseTainting = "basic";
|
||||
response = await schemeFetch(fetchParams);
|
||||
} else if (request.mode === "same-origin") {
|
||||
response = makeNetworkError('request mode cannot be "same-origin"');
|
||||
} else if (request.mode === "no-cors") {
|
||||
if (request.redirect !== "follow") {
|
||||
response = makeNetworkError(
|
||||
'redirect mode cannot be "follow" for "no-cors" request'
|
||||
);
|
||||
} else {
|
||||
request.responseTainting = "opaque";
|
||||
async function mainFetch(fetchParams, recursive) {
|
||||
try {
|
||||
const request = fetchParams.request;
|
||||
let response = null;
|
||||
if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) {
|
||||
response = makeNetworkError("local URLs only");
|
||||
}
|
||||
tryUpgradeRequestToAPotentiallyTrustworthyURL(request);
|
||||
if (requestBadPort(request) === "blocked") {
|
||||
response = makeNetworkError("bad port");
|
||||
}
|
||||
if (request.referrerPolicy === "") {
|
||||
request.referrerPolicy = request.policyContainer.referrerPolicy;
|
||||
}
|
||||
if (request.referrer !== "no-referrer") {
|
||||
request.referrer = determineRequestsReferrer(request);
|
||||
}
|
||||
if (response === null) {
|
||||
const currentURL = requestCurrentURL(request);
|
||||
if (
|
||||
// - request?s current URL?s origin is same origin with request?s origin,
|
||||
// and request?s response tainting is "basic"
|
||||
sameOrigin(currentURL, request.url) && request.responseTainting === "basic" || // request?s current URL?s scheme is "data"
|
||||
currentURL.protocol === "data:" || // - request?s mode is "navigate" or "websocket"
|
||||
(request.mode === "navigate" || request.mode === "websocket")
|
||||
) {
|
||||
request.responseTainting = "basic";
|
||||
response = await schemeFetch(fetchParams);
|
||||
} else if (request.mode === "same-origin") {
|
||||
response = makeNetworkError('request mode cannot be "same-origin"');
|
||||
} else if (request.mode === "no-cors") {
|
||||
if (request.redirect !== "follow") {
|
||||
response = makeNetworkError(
|
||||
'redirect mode cannot be "follow" for "no-cors" request'
|
||||
);
|
||||
} else {
|
||||
request.responseTainting = "opaque";
|
||||
response = await schemeFetch(fetchParams);
|
||||
}
|
||||
} else if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) {
|
||||
response = makeNetworkError("URL scheme must be a HTTP(S) scheme");
|
||||
} else {
|
||||
request.responseTainting = "cors";
|
||||
response = await httpFetch(fetchParams);
|
||||
}
|
||||
} else if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) {
|
||||
response = makeNetworkError("URL scheme must be a HTTP(S) scheme");
|
||||
} else {
|
||||
request.responseTainting = "cors";
|
||||
response = await httpFetch(fetchParams);
|
||||
}
|
||||
}
|
||||
if (recursive) {
|
||||
return response;
|
||||
}
|
||||
if (response.status !== 0 && !response.internalResponse) {
|
||||
if (request.responseTainting === "cors") {
|
||||
if (recursive) {
|
||||
return response;
|
||||
}
|
||||
if (request.responseTainting === "basic") {
|
||||
response = filterResponse(response, "basic");
|
||||
} else if (request.responseTainting === "cors") {
|
||||
response = filterResponse(response, "cors");
|
||||
} else if (request.responseTainting === "opaque") {
|
||||
response = filterResponse(response, "opaque");
|
||||
} else {
|
||||
assert(false);
|
||||
if (response.status !== 0 && !response.internalResponse) {
|
||||
if (request.responseTainting === "cors") {
|
||||
}
|
||||
if (request.responseTainting === "basic") {
|
||||
response = filterResponse(response, "basic");
|
||||
} else if (request.responseTainting === "cors") {
|
||||
response = filterResponse(response, "cors");
|
||||
} else if (request.responseTainting === "opaque") {
|
||||
response = filterResponse(response, "opaque");
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
let internalResponse = response.status === 0 ? response : response.internalResponse;
|
||||
if (internalResponse.urlList.length === 0) {
|
||||
internalResponse.urlList.push(...request.urlList);
|
||||
}
|
||||
if (!request.timingAllowFailed) {
|
||||
response.timingAllowPassed = true;
|
||||
}
|
||||
if (response.type === "opaque" && internalResponse.status === 206 && internalResponse.rangeRequested && !request.headers.contains("range", true)) {
|
||||
response = internalResponse = makeNetworkError();
|
||||
}
|
||||
if (response.status !== 0 && (request.method === "HEAD" || request.method === "CONNECT" || nullBodyStatus.includes(internalResponse.status))) {
|
||||
internalResponse.body = null;
|
||||
fetchParams.controller.dump = true;
|
||||
}
|
||||
if (request.integrity) {
|
||||
const processBodyError = /* @__PURE__ */ __name((reason) => fetchFinale(fetchParams, makeNetworkError(reason)), "processBodyError");
|
||||
if (request.responseTainting === "opaque" || response.body == null) {
|
||||
processBodyError(response.error);
|
||||
return;
|
||||
let internalResponse = response.status === 0 ? response : response.internalResponse;
|
||||
if (internalResponse.urlList.length === 0) {
|
||||
internalResponse.urlList.push(...request.urlList);
|
||||
}
|
||||
const processBody = /* @__PURE__ */ __name((bytes) => {
|
||||
if (!bytesMatch(bytes, request.integrity)) {
|
||||
processBodyError("integrity mismatch");
|
||||
if (!request.timingAllowFailed) {
|
||||
response.timingAllowPassed = true;
|
||||
}
|
||||
if (response.type === "opaque" && internalResponse.status === 206 && internalResponse.rangeRequested && !request.headers.contains("range", true)) {
|
||||
response = internalResponse = makeNetworkError();
|
||||
}
|
||||
if (response.status !== 0 && (request.method === "HEAD" || request.method === "CONNECT" || nullBodyStatus.includes(internalResponse.status))) {
|
||||
internalResponse.body = null;
|
||||
fetchParams.controller.dump = true;
|
||||
}
|
||||
if (request.integrity) {
|
||||
const processBodyError = /* @__PURE__ */ __name((reason) => fetchFinale(fetchParams, makeNetworkError(reason)), "processBodyError");
|
||||
if (request.responseTainting === "opaque" || response.body == null) {
|
||||
processBodyError(response.error);
|
||||
return;
|
||||
}
|
||||
response.body = safelyExtractBody(bytes)[0];
|
||||
const processBody = /* @__PURE__ */ __name((bytes) => {
|
||||
if (!bytesMatch(bytes, request.integrity)) {
|
||||
processBodyError("integrity mismatch");
|
||||
return;
|
||||
}
|
||||
response.body = safelyExtractBody(bytes)[0];
|
||||
fetchFinale(fetchParams, response);
|
||||
}, "processBody");
|
||||
fullyReadBody(response.body, processBody, processBodyError);
|
||||
} else {
|
||||
fetchFinale(fetchParams, response);
|
||||
}, "processBody");
|
||||
await fullyReadBody(response.body, processBody, processBodyError);
|
||||
} else {
|
||||
fetchFinale(fetchParams, response);
|
||||
}
|
||||
} catch (err) {
|
||||
fetchParams.controller.terminate(err);
|
||||
}
|
||||
}
|
||||
__name(mainFetch, "mainFetch");
|
||||
|
|
@ -11692,15 +11680,11 @@ var require_fetch = __commonJS({
|
|||
}, "cancelAlgorithm");
|
||||
const stream = new ReadableStream(
|
||||
{
|
||||
async start(controller) {
|
||||
start(controller) {
|
||||
fetchParams.controller.controller = controller;
|
||||
},
|
||||
async pull(controller) {
|
||||
await pullAlgorithm(controller);
|
||||
},
|
||||
async cancel(reason) {
|
||||
await cancelAlgorithm(reason);
|
||||
},
|
||||
pull: pullAlgorithm,
|
||||
cancel: cancelAlgorithm,
|
||||
type: "bytes"
|
||||
}
|
||||
);
|
||||
|
|
@ -11800,10 +11784,9 @@ var require_fetch = __commonJS({
|
|||
},
|
||||
onHeaders(status, rawHeaders, resume, statusText) {
|
||||
if (status < 200) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
let codings = [];
|
||||
let location = "";
|
||||
const headersList = new HeadersList();
|
||||
for (let i = 0; i < rawHeaders.length; i += 2) {
|
||||
headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true);
|
||||
|
|
@ -11812,7 +11795,7 @@ var require_fetch = __commonJS({
|
|||
if (contentEncoding) {
|
||||
codings = contentEncoding.toLowerCase().split(",").map((x) => x.trim());
|
||||
}
|
||||
location = headersList.get("location", true);
|
||||
const location = headersList.get("location", true);
|
||||
this.body = new Readable({ read: resume });
|
||||
const decoders = [];
|
||||
const willFollow = location && request.redirect === "follow" && redirectStatusSet.has(status);
|
||||
|
|
@ -12560,7 +12543,6 @@ var require_connection = __commonJS({
|
|||
"use strict";
|
||||
var { uid, states, sentCloseFrameState, emptyBuffer, opcodes } = require_constants4();
|
||||
var { parseExtensions, isClosed, isClosing, isEstablished, validateCloseCodeAndReason } = require_util3();
|
||||
var { channels } = require_diagnostics();
|
||||
var { makeRequest } = require_request2();
|
||||
var { fetching } = require_fetch();
|
||||
var { Headers, getHeadersList } = require_headers();
|
||||
|
|
@ -12647,13 +12629,6 @@ var require_connection = __commonJS({
|
|||
response.socket.on("data", handler.onSocketData);
|
||||
response.socket.on("close", handler.onSocketClose);
|
||||
response.socket.on("error", handler.onSocketError);
|
||||
if (channels.open.hasSubscribers) {
|
||||
channels.open.publish({
|
||||
address: response.socket.address(),
|
||||
protocol: secProtocol,
|
||||
extensions: secExtension
|
||||
});
|
||||
}
|
||||
handler.wasEverConnected = true;
|
||||
handler.onConnectionEstablished(response, extensions);
|
||||
}
|
||||
|
|
@ -12779,7 +12754,6 @@ var require_receiver = __commonJS({
|
|||
var { Writable } = require("node:stream");
|
||||
var assert = require("node:assert");
|
||||
var { parserStates, opcodes, states, emptyBuffer, sentCloseFrameState } = require_constants4();
|
||||
var { channels } = require_diagnostics();
|
||||
var {
|
||||
isValidStatusCode,
|
||||
isValidOpcode,
|
||||
|
|
@ -13071,18 +13045,10 @@ var require_receiver = __commonJS({
|
|||
if (!this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
|
||||
const frame = new WebsocketFrameSend(body);
|
||||
this.#handler.socket.write(frame.createFrame(opcodes.PONG));
|
||||
if (channels.ping.hasSubscribers) {
|
||||
channels.ping.publish({
|
||||
payload: body
|
||||
});
|
||||
}
|
||||
this.#handler.onPing(body);
|
||||
}
|
||||
} else if (opcode === opcodes.PONG) {
|
||||
if (channels.pong.hasSubscribers) {
|
||||
channels.pong.publish({
|
||||
payload: body
|
||||
});
|
||||
}
|
||||
this.#handler.onPong(body);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -13200,6 +13166,7 @@ var require_websocket = __commonJS({
|
|||
isConnecting,
|
||||
isEstablished,
|
||||
isClosing,
|
||||
isClosed,
|
||||
isValidSubprotocol,
|
||||
fireEvent,
|
||||
utf8Decode,
|
||||
|
|
@ -13213,6 +13180,7 @@ var require_websocket = __commonJS({
|
|||
var { types } = require("node:util");
|
||||
var { ErrorEvent: ErrorEvent2, CloseEvent: CloseEvent2, createFastMessageEvent: createFastMessageEvent2 } = require_events();
|
||||
var { SendQueue } = require_sender();
|
||||
var { WebsocketFrameSend } = require_frame();
|
||||
var { channels } = require_diagnostics();
|
||||
var WebSocket = class _WebSocket extends EventTarget {
|
||||
static {
|
||||
|
|
@ -13249,6 +13217,22 @@ var require_websocket = __commonJS({
|
|||
this.#handler.socket.destroy();
|
||||
}, "onSocketError"),
|
||||
onSocketClose: /* @__PURE__ */ __name(() => this.#onSocketClose(), "onSocketClose"),
|
||||
onPing: /* @__PURE__ */ __name((body) => {
|
||||
if (channels.ping.hasSubscribers) {
|
||||
channels.ping.publish({
|
||||
payload: body,
|
||||
websocket: this
|
||||
});
|
||||
}
|
||||
}, "onPing"),
|
||||
onPong: /* @__PURE__ */ __name((body) => {
|
||||
if (channels.pong.hasSubscribers) {
|
||||
channels.pong.publish({
|
||||
payload: body,
|
||||
websocket: this
|
||||
});
|
||||
}
|
||||
}, "onPong"),
|
||||
readyState: states.CONNECTING,
|
||||
socket: null,
|
||||
closeState: /* @__PURE__ */ new Set(),
|
||||
|
|
@ -13466,6 +13450,14 @@ var require_websocket = __commonJS({
|
|||
this.#protocol = protocol;
|
||||
}
|
||||
fireEvent("open", this);
|
||||
if (channels.open.hasSubscribers) {
|
||||
channels.open.publish({
|
||||
address: response.socket.address(),
|
||||
protocol: this.#protocol,
|
||||
extensions: this.#extensions,
|
||||
websocket: this
|
||||
});
|
||||
}
|
||||
}
|
||||
#onFail(code, reason, cause) {
|
||||
if (reason) {
|
||||
|
|
@ -13539,7 +13531,27 @@ var require_websocket = __commonJS({
|
|||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {WebSocket} ws
|
||||
* @param {Buffer|undefined} buffer
|
||||
*/
|
||||
static ping(ws, buffer) {
|
||||
if (Buffer.isBuffer(buffer)) {
|
||||
if (buffer.length > 125) {
|
||||
throw new TypeError("A PING frame cannot have a body larger than 125 bytes.");
|
||||
}
|
||||
} else if (buffer !== void 0) {
|
||||
throw new TypeError("Expected buffer payload");
|
||||
}
|
||||
const readyState = ws.#handler.readyState;
|
||||
if (isEstablished(readyState) && !isClosing(readyState) && !isClosed(readyState)) {
|
||||
const frame = new WebsocketFrameSend(buffer);
|
||||
ws.#handler.socket.write(frame.createFrame(opcodes.PING));
|
||||
}
|
||||
}
|
||||
};
|
||||
var { ping } = WebSocket;
|
||||
Reflect.deleteProperty(WebSocket, "ping");
|
||||
WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING;
|
||||
WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN;
|
||||
WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING;
|
||||
|
|
@ -13617,7 +13629,8 @@ var require_websocket = __commonJS({
|
|||
return webidl.converters.USVString(V);
|
||||
};
|
||||
module2.exports = {
|
||||
WebSocket
|
||||
WebSocket,
|
||||
ping
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
@ -14254,9 +14267,7 @@ var require_readable = __commonJS({
|
|||
this[kAbort]();
|
||||
}
|
||||
if (!this[kUsed]) {
|
||||
setImmediate(() => {
|
||||
callback(err);
|
||||
});
|
||||
setImmediate(callback, err);
|
||||
} else {
|
||||
callback(err);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
// Refer to tools/dep_updaters/update-undici.sh
|
||||
#ifndef SRC_UNDICI_VERSION_H_
|
||||
#define SRC_UNDICI_VERSION_H_
|
||||
#define UNDICI_VERSION "7.11.0"
|
||||
#define UNDICI_VERSION "7.12.0"
|
||||
#endif // SRC_UNDICI_VERSION_H_
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user