mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
deps: update undici to 7.11.0
PR-URL: https://github.com/nodejs/node/pull/58859 Co-authored-by: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
This commit is contained in:
parent
4c65776a35
commit
0b88e0927f
66 changed files with 1419 additions and 896 deletions
157
deps/undici/src/README.md
vendored
157
deps/undici/src/README.md
vendored
|
@ -43,6 +43,125 @@ The benchmark is a simple getting data [example](https://github.com/nodejs/undic
|
|||
└────────────────────────┴─────────┴────────────────────┴────────────┴─────────────────────────┘
|
||||
```
|
||||
|
||||
## Undici vs. Fetch
|
||||
|
||||
### Overview
|
||||
|
||||
Node.js includes a built-in `fetch()` implementation powered by undici starting from Node.js v18. However, there are important differences between using the built-in fetch and installing undici as a separate module.
|
||||
|
||||
### Built-in Fetch (Node.js v18+)
|
||||
|
||||
Node.js's built-in fetch is powered by a bundled version of undici:
|
||||
|
||||
```js
|
||||
// Available globally in Node.js v18+
|
||||
const response = await fetch('https://api.example.com/data');
|
||||
const data = await response.json();
|
||||
|
||||
// Check the bundled undici version
|
||||
console.log(process.versions.undici); // e.g., "5.28.4"
|
||||
```
|
||||
|
||||
**Pros:**
|
||||
- No additional dependencies required
|
||||
- Works across different JavaScript runtimes
|
||||
- Automatic compression handling (gzip, deflate, br)
|
||||
- Built-in caching support (in development)
|
||||
|
||||
**Cons:**
|
||||
- Limited to the undici version bundled with your Node.js version
|
||||
- Less control over connection pooling and advanced features
|
||||
- Error handling follows Web API standards (errors wrapped in `TypeError`)
|
||||
- Performance overhead due to Web Streams implementation
|
||||
|
||||
### Undici Module
|
||||
|
||||
Installing undici as a separate module gives you access to the latest features and APIs:
|
||||
|
||||
```bash
|
||||
npm install undici
|
||||
```
|
||||
|
||||
```js
|
||||
import { request, fetch, Agent, setGlobalDispatcher } from 'undici';
|
||||
|
||||
// Use undici.request for maximum performance
|
||||
const { statusCode, headers, body } = await request('https://api.example.com/data');
|
||||
const data = await body.json();
|
||||
|
||||
// Or use undici.fetch with custom configuration
|
||||
const agent = new Agent({ keepAliveTimeout: 10000 });
|
||||
setGlobalDispatcher(agent);
|
||||
const response = await fetch('https://api.example.com/data');
|
||||
```
|
||||
|
||||
**Pros:**
|
||||
- Latest undici features and bug fixes
|
||||
- Access to advanced APIs (`request`, `stream`, `pipeline`)
|
||||
- Fine-grained control over connection pooling
|
||||
- Better error handling with clearer error messages
|
||||
- Superior performance, especially with `undici.request`
|
||||
- HTTP/1.1 pipelining support
|
||||
- Custom interceptors and middleware
|
||||
- Advanced features like `ProxyAgent`, `MockAgent`
|
||||
|
||||
**Cons:**
|
||||
- Additional dependency to manage
|
||||
- Larger bundle size
|
||||
|
||||
### When to Use Each
|
||||
|
||||
#### Use Built-in Fetch When:
|
||||
- You want zero dependencies
|
||||
- Building isomorphic code that runs in browsers and Node.js
|
||||
- Simple HTTP requests without advanced configuration
|
||||
- You're okay with the undici version bundled in your Node.js version
|
||||
|
||||
#### Use Undici Module When:
|
||||
- You need the latest undici features and performance improvements
|
||||
- You require advanced connection pooling configuration
|
||||
- You need APIs not available in the built-in fetch (`ProxyAgent`, `MockAgent`, etc.)
|
||||
- Performance is critical (use `undici.request` for maximum speed)
|
||||
- You want better error handling and debugging capabilities
|
||||
- You need HTTP/1.1 pipelining or advanced interceptors
|
||||
- You prefer decoupled protocol and API interfaces
|
||||
|
||||
### Performance Comparison
|
||||
|
||||
Based on benchmarks, here's the typical performance hierarchy:
|
||||
|
||||
1. **`undici.request()`** - Fastest, most efficient
|
||||
2. **`undici.fetch()`** - Good performance, standard compliance
|
||||
3. **Node.js `http`/`https`** - Baseline performance
|
||||
|
||||
### Migration Guide
|
||||
|
||||
If you're currently using built-in fetch and want to migrate to undici:
|
||||
|
||||
```js
|
||||
// Before: Built-in fetch
|
||||
const response = await fetch('https://api.example.com/data');
|
||||
|
||||
// After: Undici fetch (drop-in replacement)
|
||||
import { fetch } from 'undici';
|
||||
const response = await fetch('https://api.example.com/data');
|
||||
|
||||
// Or: Undici request (better performance)
|
||||
import { request } from 'undici';
|
||||
const { statusCode, body } = await request('https://api.example.com/data');
|
||||
const data = await body.json();
|
||||
```
|
||||
|
||||
### Version Compatibility
|
||||
|
||||
You can check which version of undici is bundled with your Node.js version:
|
||||
|
||||
```js
|
||||
console.log(process.versions.undici);
|
||||
```
|
||||
|
||||
Installing undici as a module allows you to use a newer version than what's bundled with Node.js, giving you access to the latest features and performance improvements.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```js
|
||||
|
@ -63,6 +182,44 @@ for await (const data of body) { console.log('data', data) }
|
|||
console.log('trailers', trailers)
|
||||
```
|
||||
|
||||
## Global Installation
|
||||
|
||||
Undici provides an `install()` function to add all WHATWG fetch classes to `globalThis`, making them available globally:
|
||||
|
||||
```js
|
||||
import { install } from 'undici'
|
||||
|
||||
// Install all WHATWG fetch classes globally
|
||||
install()
|
||||
|
||||
// Now you can use fetch classes globally without importing
|
||||
const response = await fetch('https://api.example.com/data')
|
||||
const data = await response.json()
|
||||
|
||||
// All classes are available globally:
|
||||
const headers = new Headers([['content-type', 'application/json']])
|
||||
const request = new Request('https://example.com')
|
||||
const formData = new FormData()
|
||||
const ws = new WebSocket('wss://example.com')
|
||||
const eventSource = new EventSource('https://example.com/events')
|
||||
```
|
||||
|
||||
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
|
||||
- `FormData` - Form data handling
|
||||
- `WebSocket` - WebSocket client
|
||||
- `CloseEvent`, `ErrorEvent`, `MessageEvent` - WebSocket events
|
||||
- `EventSource` - Server-sent events client
|
||||
|
||||
This is useful for:
|
||||
- Polyfilling environments that don't have fetch
|
||||
- Ensuring consistent fetch behavior across different Node.js versions
|
||||
- Making undici's implementations available globally for libraries that expect them
|
||||
|
||||
## Body Mixins
|
||||
|
||||
The `body` mixins are the most common way to format the request/response body. Mixins include:
|
||||
|
|
6
deps/undici/src/docs/docs/api/CacheStore.md
vendored
6
deps/undici/src/docs/docs/api/CacheStore.md
vendored
|
@ -13,9 +13,9 @@ The `MemoryCacheStore` stores the responses in-memory.
|
|||
|
||||
**Options**
|
||||
|
||||
- `maxSize` - The maximum total size in bytes of all stored responses. Default `Infinity`.
|
||||
- `maxCount` - The maximum amount of responses to store. Default `Infinity`.
|
||||
- `maxEntrySize` - The maximum size in bytes that a response's body can be. If a response's body is greater than or equal to this, the response will not be cached. Default `Infinity`.
|
||||
- `maxSize` - The maximum total size in bytes of all stored responses. Default `104857600` (100MB).
|
||||
- `maxCount` - The maximum amount of responses to store. Default `1024`.
|
||||
- `maxEntrySize` - The maximum size in bytes that a response's body can be. If a response's body is greater than or equal to this, the response will not be cached. Default `5242880` (5MB).
|
||||
|
||||
### Getters
|
||||
|
||||
|
|
26
deps/undici/src/docs/docs/api/Debug.md
vendored
26
deps/undici/src/docs/docs/api/Debug.md
vendored
|
@ -14,14 +14,14 @@ NODE_DEBUG=undici node script.js
|
|||
UNDICI 16241: connecting to nodejs.org using https:h1
|
||||
UNDICI 16241: connecting to nodejs.org using https:h1
|
||||
UNDICI 16241: connected to nodejs.org using https:h1
|
||||
UNDICI 16241: sending request to GET https://nodejs.org//
|
||||
UNDICI 16241: received response to GET https://nodejs.org// - HTTP 307
|
||||
UNDICI 16241: sending request to GET https://nodejs.org/
|
||||
UNDICI 16241: received response to GET https://nodejs.org/ - HTTP 307
|
||||
UNDICI 16241: connecting to nodejs.org using https:h1
|
||||
UNDICI 16241: trailers received from GET https://nodejs.org//
|
||||
UNDICI 16241: trailers received from GET https://nodejs.org/
|
||||
UNDICI 16241: connected to nodejs.org using https:h1
|
||||
UNDICI 16241: sending request to GET https://nodejs.org//en
|
||||
UNDICI 16241: received response to GET https://nodejs.org//en - HTTP 200
|
||||
UNDICI 16241: trailers received from GET https://nodejs.org//en
|
||||
UNDICI 16241: sending request to GET https://nodejs.org/en
|
||||
UNDICI 16241: received response to GET https://nodejs.org/en - HTTP 200
|
||||
UNDICI 16241: trailers received from GET https://nodejs.org/en
|
||||
```
|
||||
|
||||
## `fetch`
|
||||
|
@ -36,14 +36,14 @@ NODE_DEBUG=fetch node script.js
|
|||
FETCH 16241: connecting to nodejs.org using https:h1
|
||||
FETCH 16241: connecting to nodejs.org using https:h1
|
||||
FETCH 16241: connected to nodejs.org using https:h1
|
||||
FETCH 16241: sending request to GET https://nodejs.org//
|
||||
FETCH 16241: received response to GET https://nodejs.org// - HTTP 307
|
||||
FETCH 16241: sending request to GET https://nodejs.org/
|
||||
FETCH 16241: received response to GET https://nodejs.org/ - HTTP 307
|
||||
FETCH 16241: connecting to nodejs.org using https:h1
|
||||
FETCH 16241: trailers received from GET https://nodejs.org//
|
||||
FETCH 16241: trailers received from GET https://nodejs.org/
|
||||
FETCH 16241: connected to nodejs.org using https:h1
|
||||
FETCH 16241: sending request to GET https://nodejs.org//en
|
||||
FETCH 16241: received response to GET https://nodejs.org//en - HTTP 200
|
||||
FETCH 16241: trailers received from GET https://nodejs.org//en
|
||||
FETCH 16241: sending request to GET https://nodejs.org/en
|
||||
FETCH 16241: received response to GET https://nodejs.org/en - HTTP 200
|
||||
FETCH 16241: trailers received from GET https://nodejs.org/en
|
||||
```
|
||||
|
||||
## `websocket`
|
||||
|
@ -57,6 +57,6 @@ NODE_DEBUG=websocket node script.js
|
|||
|
||||
WEBSOCKET 18309: connecting to echo.websocket.org using https:h1
|
||||
WEBSOCKET 18309: connected to echo.websocket.org using https:h1
|
||||
WEBSOCKET 18309: sending request to GET https://echo.websocket.org//
|
||||
WEBSOCKET 18309: sending request to GET https://echo.websocket.org/
|
||||
WEBSOCKET 18309: connection opened <ip_address>
|
||||
```
|
||||
|
|
|
@ -27,9 +27,22 @@ diagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => {
|
|||
|
||||
Note: a request is only loosely completed to a given socket.
|
||||
|
||||
## `undici:request:bodyChunkSent`
|
||||
|
||||
This message is published when a chunk of the request body is being sent.
|
||||
|
||||
```js
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:request:bodyChunkSent').subscribe(({ request, chunk }) => {
|
||||
// request is the same object undici:request:create
|
||||
})
|
||||
```
|
||||
|
||||
## `undici:request:bodySent`
|
||||
|
||||
This message is published after the request body has been fully sent.
|
||||
|
||||
```js
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
|
@ -54,6 +67,18 @@ diagnosticsChannel.channel('undici:request:headers').subscribe(({ request, respo
|
|||
})
|
||||
```
|
||||
|
||||
## `undici:request:bodyChunkReceived`
|
||||
|
||||
This message is published after a chunk of the response body has been received.
|
||||
|
||||
```js
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:request:bodyChunkReceived').subscribe(({ request, chunk }) => {
|
||||
// request is the same object undici:request:create
|
||||
})
|
||||
```
|
||||
|
||||
## `undici:request:trailers`
|
||||
|
||||
This message is published after the response body and trailers have been received, i.e. the response has been completed.
|
||||
|
|
21
deps/undici/src/docs/docs/api/Dispatcher.md
vendored
21
deps/undici/src/docs/docs/api/Dispatcher.md
vendored
|
@ -841,9 +841,28 @@ try {
|
|||
Compose a new dispatcher from the current dispatcher and the given interceptors.
|
||||
|
||||
> _Notes_:
|
||||
> - The order of the interceptors matters. The first interceptor will be the first to be called.
|
||||
> - The order of the interceptors matters. The last interceptor will be the first to be called.
|
||||
> - It is important to note that the `interceptor` function should return a function that follows the `Dispatcher.dispatch` signature.
|
||||
> - Any fork of the chain of `interceptors` can lead to unexpected results.
|
||||
>
|
||||
> **Interceptor Stack Visualization:**
|
||||
> ```
|
||||
> compose([interceptor1, interceptor2, interceptor3])
|
||||
>
|
||||
> Request Flow:
|
||||
> ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
> │ Request │───▶│interceptor3 │───▶│interceptor2 │───▶│interceptor1 │───▶│ dispatcher │
|
||||
> └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ .dispatch │
|
||||
> ▲ ▲ ▲ └─────────────┘
|
||||
> │ │ │ ▲
|
||||
> (called first) (called second) (called last) │
|
||||
> │
|
||||
> ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
> │ Response │◀───│interceptor3 │◀───│interceptor2 │◀───│interceptor1 │◀─────────┘
|
||||
> └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
||||
>
|
||||
> The interceptors are composed in reverse order due to function composition.
|
||||
> ```
|
||||
|
||||
Arguments:
|
||||
|
||||
|
|
91
deps/undici/src/docs/docs/api/GlobalInstallation.md
vendored
Normal file
91
deps/undici/src/docs/docs/api/GlobalInstallation.md
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
# Global Installation
|
||||
|
||||
Undici provides an `install()` function to add all WHATWG fetch classes to `globalThis`, making them available globally without requiring imports.
|
||||
|
||||
## `install()`
|
||||
|
||||
Install all WHATWG fetch classes globally on `globalThis`.
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
import { install } from 'undici'
|
||||
|
||||
// Install all WHATWG fetch classes globally
|
||||
install()
|
||||
|
||||
// Now you can use fetch classes globally without importing
|
||||
const response = await fetch('https://api.example.com/data')
|
||||
const data = await response.json()
|
||||
|
||||
// All classes are available globally:
|
||||
const headers = new Headers([['content-type', 'application/json']])
|
||||
const request = new Request('https://example.com')
|
||||
const formData = new FormData()
|
||||
const ws = new WebSocket('wss://example.com')
|
||||
const eventSource = new EventSource('https://example.com/events')
|
||||
```
|
||||
|
||||
## Installed Classes
|
||||
|
||||
The `install()` function adds the following classes to `globalThis`:
|
||||
|
||||
| Class | Description |
|
||||
|-------|-------------|
|
||||
| `fetch` | The fetch function for making HTTP requests |
|
||||
| `Headers` | HTTP headers management |
|
||||
| `Response` | HTTP response representation |
|
||||
| `Request` | HTTP request representation |
|
||||
| `FormData` | Form data handling |
|
||||
| `WebSocket` | WebSocket client |
|
||||
| `CloseEvent` | WebSocket close event |
|
||||
| `ErrorEvent` | WebSocket error event |
|
||||
| `MessageEvent` | WebSocket message event |
|
||||
| `EventSource` | Server-sent events client |
|
||||
|
||||
## Use Cases
|
||||
|
||||
Global installation is useful for:
|
||||
|
||||
- **Polyfilling environments** that don't have native fetch support
|
||||
- **Ensuring consistent behavior** across different Node.js versions
|
||||
- **Library compatibility** when third-party libraries expect global fetch
|
||||
- **Migration scenarios** where you want to replace built-in implementations
|
||||
- **Testing environments** where you need predictable fetch behavior
|
||||
|
||||
## Example: Polyfilling an Environment
|
||||
|
||||
```js
|
||||
import { install } from 'undici'
|
||||
|
||||
// Check if fetch is available and install if needed
|
||||
if (typeof globalThis.fetch === 'undefined') {
|
||||
install()
|
||||
console.log('Undici fetch installed globally')
|
||||
}
|
||||
|
||||
// Now fetch is guaranteed to be available
|
||||
const response = await fetch('https://api.example.com')
|
||||
```
|
||||
|
||||
## Example: Testing Environment
|
||||
|
||||
```js
|
||||
import { install } from 'undici'
|
||||
|
||||
// In test setup, ensure consistent fetch behavior
|
||||
install()
|
||||
|
||||
// Now all tests use undici's implementations
|
||||
test('fetch API test', async () => {
|
||||
const response = await fetch('https://example.com')
|
||||
expect(response).toBeInstanceOf(Response)
|
||||
})
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The `install()` function overwrites any existing global implementations
|
||||
- Classes installed are undici's implementations, not Node.js built-ins
|
||||
- This provides access to undici's latest features and performance improvements
|
||||
- The global installation persists for the lifetime of the process
|
4
deps/undici/src/docs/docs/api/MockClient.md
vendored
4
deps/undici/src/docs/docs/api/MockClient.md
vendored
|
@ -38,6 +38,10 @@ const mockClient = mockAgent.get('http://localhost:3000')
|
|||
|
||||
Implements: [`MockPool.intercept(options)`](/docs/docs/api/MockPool.md#mockpoolinterceptoptions)
|
||||
|
||||
### `MockClient.cleanMocks()`
|
||||
|
||||
Implements: [`MockPool.cleanMocks()`](/docs/docs/api/MockPool.md#mockpoolcleanmocks)
|
||||
|
||||
### `MockClient.close()`
|
||||
|
||||
Implements: [`MockPool.close()`](/docs/docs/api/MockPool.md#mockpoolclose)
|
||||
|
|
6
deps/undici/src/docs/docs/api/MockPool.md
vendored
6
deps/undici/src/docs/docs/api/MockPool.md
vendored
|
@ -546,3 +546,9 @@ for await (const data of body) {
|
|||
console.log('data', data.toString('utf8')) // data foo
|
||||
}
|
||||
```
|
||||
|
||||
### `MockPool.cleanMocks()`
|
||||
|
||||
This method cleans up all the prepared mocks.
|
||||
|
||||
Returns: `void`
|
||||
|
|
2
deps/undici/src/docs/docs/api/ProxyAgent.md
vendored
2
deps/undici/src/docs/docs/api/ProxyAgent.md
vendored
|
@ -17,6 +17,8 @@ Returns: `ProxyAgent`
|
|||
Extends: [`AgentOptions`](/docs/docs/api/Agent.md#parameter-agentoptions)
|
||||
> It ommits `AgentOptions#connect`.
|
||||
|
||||
> **Note:** When `AgentOptions#connections` is set, and different from `0`, the non-standard [`proxy-connection` header](https://udger.com/resources/http-request-headers-detail?header=Proxy-Connection) will be set to `keep-alive` in the request.
|
||||
|
||||
* **uri** `string | URL` (required) - The URI of the proxy server. This can be provided as a string, as an instance of the URL class, or as an object with a `uri` property of type string.
|
||||
If the `uri` is provided as a string or `uri` is an object with an `uri` property of type string, then it will be parsed into a `URL` object according to the [WHATWG URL Specification](https://url.spec.whatwg.org).
|
||||
For detailed information on the parsing process and potential validation errors, please refer to the ["Writing" section](https://url.spec.whatwg.org/#writing) of the WHATWG URL Specification.
|
||||
|
|
7
deps/undici/src/docs/docs/api/RetryAgent.md
vendored
7
deps/undici/src/docs/docs/api/RetryAgent.md
vendored
|
@ -16,6 +16,7 @@ Returns: `ProxyAgent`
|
|||
|
||||
### Parameter: `RetryHandlerOptions`
|
||||
|
||||
- **throwOnError** `boolean` (optional) - Disable to prevent throwing error on last retry attept, useful if you need the body on errors from server or if you have custom error handler. Default: `true`
|
||||
- **retry** `(err: Error, context: RetryContext, callback: (err?: Error | null) => void) => void` (optional) - Function to be called after every retry. It should pass error if no more retries should be performed.
|
||||
- **maxRetries** `number` (optional) - Maximum number of retries. Default: `5`
|
||||
- **maxTimeout** `number` (optional) - Maximum number of milliseconds to wait before retrying. Default: `30000` (30 seconds)
|
||||
|
@ -39,7 +40,11 @@ import { Agent, RetryAgent } from 'undici'
|
|||
|
||||
const agent = new RetryAgent(new Agent())
|
||||
|
||||
const res = await agent.request('http://example.com')
|
||||
const res = await agent.request({
|
||||
method: 'GET',
|
||||
origin: 'http://example.com',
|
||||
path: '/',
|
||||
})
|
||||
console.log(res.statusCode)
|
||||
console.log(await res.body.text())
|
||||
```
|
||||
|
|
|
@ -19,6 +19,7 @@ Extends: [`Dispatch.DispatchOptions`](/docs/docs/api/Dispatcher.md#parameter-dis
|
|||
|
||||
#### `RetryOptions`
|
||||
|
||||
- **throwOnError** `boolean` (optional) - Disable to prevent throwing error on last retry attept, useful if you need the body on errors from server or if you have custom error handler.
|
||||
- **retry** `(err: Error, context: RetryContext, callback: (err?: Error | null) => void) => number | null` (optional) - Function to be called after every retry. It should pass error if no more retries should be performed.
|
||||
- **maxRetries** `number` (optional) - Maximum number of retries. Default: `5`
|
||||
- **maxTimeout** `number` (optional) - Maximum number of milliseconds to wait before retrying. Default: `30000` (30 seconds)
|
||||
|
|
15
deps/undici/src/index.js
vendored
15
deps/undici/src/index.js
vendored
|
@ -181,3 +181,18 @@ module.exports.mockErrors = mockErrors
|
|||
const { EventSource } = require('./lib/web/eventsource/eventsource')
|
||||
|
||||
module.exports.EventSource = EventSource
|
||||
|
||||
function install () {
|
||||
globalThis.fetch = module.exports.fetch
|
||||
globalThis.Headers = module.exports.Headers
|
||||
globalThis.Response = module.exports.Response
|
||||
globalThis.Request = module.exports.Request
|
||||
globalThis.FormData = module.exports.FormData
|
||||
globalThis.WebSocket = module.exports.WebSocket
|
||||
globalThis.CloseEvent = module.exports.CloseEvent
|
||||
globalThis.ErrorEvent = module.exports.ErrorEvent
|
||||
globalThis.MessageEvent = module.exports.MessageEvent
|
||||
globalThis.EventSource = module.exports.EventSource
|
||||
}
|
||||
|
||||
module.exports.install = install
|
||||
|
|
2
deps/undici/src/lib/api/api-stream.js
vendored
2
deps/undici/src/lib/api/api-stream.js
vendored
|
@ -117,7 +117,7 @@ class StreamHandler extends AsyncResource {
|
|||
const { callback, res, opaque, trailers, abort } = this
|
||||
|
||||
this.res = null
|
||||
if (err || !res.readable) {
|
||||
if (err || !res?.readable) {
|
||||
util.destroy(res, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ const { assertCacheKey, assertCacheValue } = require('../util/cache.js')
|
|||
* @extends {EventEmitter}
|
||||
*/
|
||||
class MemoryCacheStore extends EventEmitter {
|
||||
#maxCount = Infinity
|
||||
#maxSize = Infinity
|
||||
#maxEntrySize = Infinity
|
||||
#maxCount = 1024
|
||||
#maxSize = 104857600 // 100MB
|
||||
#maxEntrySize = 5242880 // 5MB
|
||||
|
||||
#size = 0
|
||||
#count = 0
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
const { Writable } = require('stream')
|
||||
const { Writable } = require('node:stream')
|
||||
const { assertCacheKey, assertCacheValue } = require('../util/cache.js')
|
||||
|
||||
let DatabaseSync
|
||||
|
|
74
deps/undici/src/lib/core/connect.js
vendored
74
deps/undici/src/lib/core/connect.js
vendored
|
@ -12,64 +12,34 @@ let tls // include tls conditionally since it is not always available
|
|||
// resolve the same servername multiple times even when
|
||||
// re-use is enabled.
|
||||
|
||||
let SessionCache
|
||||
// FIXME: remove workaround when the Node bug is fixed
|
||||
// https://github.com/nodejs/node/issues/49344#issuecomment-1741776308
|
||||
if (global.FinalizationRegistry && !(process.env.NODE_V8_COVERAGE || process.env.UNDICI_NO_FG)) {
|
||||
SessionCache = class WeakSessionCache {
|
||||
constructor (maxCachedSessions) {
|
||||
this._maxCachedSessions = maxCachedSessions
|
||||
this._sessionCache = new Map()
|
||||
this._sessionRegistry = new global.FinalizationRegistry((key) => {
|
||||
if (this._sessionCache.size < this._maxCachedSessions) {
|
||||
return
|
||||
}
|
||||
|
||||
const ref = this._sessionCache.get(key)
|
||||
if (ref !== undefined && ref.deref() === undefined) {
|
||||
this._sessionCache.delete(key)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get (sessionKey) {
|
||||
const ref = this._sessionCache.get(sessionKey)
|
||||
return ref ? ref.deref() : null
|
||||
}
|
||||
|
||||
set (sessionKey, session) {
|
||||
if (this._maxCachedSessions === 0) {
|
||||
const SessionCache = class WeakSessionCache {
|
||||
constructor (maxCachedSessions) {
|
||||
this._maxCachedSessions = maxCachedSessions
|
||||
this._sessionCache = new Map()
|
||||
this._sessionRegistry = new FinalizationRegistry((key) => {
|
||||
if (this._sessionCache.size < this._maxCachedSessions) {
|
||||
return
|
||||
}
|
||||
|
||||
this._sessionCache.set(sessionKey, new WeakRef(session))
|
||||
this._sessionRegistry.register(session, sessionKey)
|
||||
}
|
||||
const ref = this._sessionCache.get(key)
|
||||
if (ref !== undefined && ref.deref() === undefined) {
|
||||
this._sessionCache.delete(key)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
SessionCache = class SimpleSessionCache {
|
||||
constructor (maxCachedSessions) {
|
||||
this._maxCachedSessions = maxCachedSessions
|
||||
this._sessionCache = new Map()
|
||||
|
||||
get (sessionKey) {
|
||||
const ref = this._sessionCache.get(sessionKey)
|
||||
return ref ? ref.deref() : null
|
||||
}
|
||||
|
||||
set (sessionKey, session) {
|
||||
if (this._maxCachedSessions === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
get (sessionKey) {
|
||||
return this._sessionCache.get(sessionKey)
|
||||
}
|
||||
|
||||
set (sessionKey, session) {
|
||||
if (this._maxCachedSessions === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this._sessionCache.size >= this._maxCachedSessions) {
|
||||
// remove the oldest session
|
||||
const { value: oldestKey } = this._sessionCache.keys().next()
|
||||
this._sessionCache.delete(oldestKey)
|
||||
}
|
||||
|
||||
this._sessionCache.set(sessionKey, session)
|
||||
}
|
||||
this._sessionCache.set(sessionKey, new WeakRef(session))
|
||||
this._sessionRegistry.register(session, sessionKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
10
deps/undici/src/lib/core/diagnostics.js
vendored
10
deps/undici/src/lib/core/diagnostics.js
vendored
|
@ -16,6 +16,8 @@ const channels = {
|
|||
// Request
|
||||
create: diagnosticsChannel.channel('undici:request:create'),
|
||||
bodySent: diagnosticsChannel.channel('undici:request:bodySent'),
|
||||
bodyChunkSent: diagnosticsChannel.channel('undici:request:bodyChunkSent'),
|
||||
bodyChunkReceived: diagnosticsChannel.channel('undici:request:bodyChunkReceived'),
|
||||
headers: diagnosticsChannel.channel('undici:request:headers'),
|
||||
trailers: diagnosticsChannel.channel('undici:request:trailers'),
|
||||
error: diagnosticsChannel.channel('undici:request:error'),
|
||||
|
@ -85,7 +87,7 @@ function trackClientEvents (debugLog = undiciDebugLog) {
|
|||
const {
|
||||
request: { method, path, origin }
|
||||
} = evt
|
||||
debugLog('sending request to %s %s/%s', method, origin, path)
|
||||
debugLog('sending request to %s %s%s', method, origin, path)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -105,7 +107,7 @@ function trackRequestEvents (debugLog = undiciDebugLog) {
|
|||
response: { statusCode }
|
||||
} = evt
|
||||
debugLog(
|
||||
'received response to %s %s/%s - HTTP %d',
|
||||
'received response to %s %s%s - HTTP %d',
|
||||
method,
|
||||
origin,
|
||||
path,
|
||||
|
@ -118,7 +120,7 @@ function trackRequestEvents (debugLog = undiciDebugLog) {
|
|||
const {
|
||||
request: { method, path, origin }
|
||||
} = evt
|
||||
debugLog('trailers received from %s %s/%s', method, origin, path)
|
||||
debugLog('trailers received from %s %s%s', method, origin, path)
|
||||
})
|
||||
|
||||
diagnosticsChannel.subscribe('undici:request:error',
|
||||
|
@ -128,7 +130,7 @@ function trackRequestEvents (debugLog = undiciDebugLog) {
|
|||
error
|
||||
} = evt
|
||||
debugLog(
|
||||
'request to %s %s/%s errored - %s',
|
||||
'request to %s %s%s errored - %s',
|
||||
method,
|
||||
origin,
|
||||
path,
|
||||
|
|
6
deps/undici/src/lib/core/request.js
vendored
6
deps/undici/src/lib/core/request.js
vendored
|
@ -194,6 +194,9 @@ class Request {
|
|||
}
|
||||
|
||||
onBodySent (chunk) {
|
||||
if (channels.bodyChunkSent.hasSubscribers) {
|
||||
channels.bodyChunkSent.publish({ request: this, chunk })
|
||||
}
|
||||
if (this[kHandler].onBodySent) {
|
||||
try {
|
||||
return this[kHandler].onBodySent(chunk)
|
||||
|
@ -252,6 +255,9 @@ class Request {
|
|||
assert(!this.aborted)
|
||||
assert(!this.completed)
|
||||
|
||||
if (channels.bodyChunkReceived.hasSubscribers) {
|
||||
channels.bodyChunkReceived.publish({ request: this, chunk })
|
||||
}
|
||||
try {
|
||||
return this[kHandler].onData(chunk)
|
||||
} catch (err) {
|
||||
|
|
45
deps/undici/src/lib/core/util.js
vendored
45
deps/undici/src/lib/core/util.js
vendored
|
@ -6,7 +6,6 @@ const { IncomingMessage } = require('node:http')
|
|||
const stream = require('node:stream')
|
||||
const net = require('node:net')
|
||||
const { Blob } = require('node:buffer')
|
||||
const nodeUtil = require('node:util')
|
||||
const { stringify } = require('node:querystring')
|
||||
const { EventEmitter: EE } = require('node:events')
|
||||
const timers = require('../util/timers')
|
||||
|
@ -660,48 +659,6 @@ function addAbortListener (signal, listener) {
|
|||
return () => signal.removeListener('abort', listener)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function
|
||||
* @param {string} value
|
||||
* @returns {string}
|
||||
*/
|
||||
const toUSVString = (() => {
|
||||
if (typeof String.prototype.toWellFormed === 'function') {
|
||||
/**
|
||||
* @param {string} value
|
||||
* @returns {string}
|
||||
*/
|
||||
return (value) => `${value}`.toWellFormed()
|
||||
} else {
|
||||
/**
|
||||
* @param {string} value
|
||||
* @returns {string}
|
||||
*/
|
||||
return nodeUtil.toUSVString
|
||||
}
|
||||
})()
|
||||
|
||||
/**
|
||||
* @param {*} value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
// TODO: move this to webidl
|
||||
const isUSVString = (() => {
|
||||
if (typeof String.prototype.isWellFormed === 'function') {
|
||||
/**
|
||||
* @param {*} value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
return (value) => `${value}`.isWellFormed()
|
||||
} else {
|
||||
/**
|
||||
* @param {*} value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
return (value) => toUSVString(value) === `${value}`
|
||||
}
|
||||
})()
|
||||
|
||||
/**
|
||||
* @see https://tools.ietf.org/html/rfc7230#section-3.2.6
|
||||
* @param {number} c
|
||||
|
@ -943,8 +900,6 @@ Object.setPrototypeOf(normalizedMethodRecords, null)
|
|||
module.exports = {
|
||||
kEnumerableProperty,
|
||||
isDisturbed,
|
||||
toUSVString,
|
||||
isUSVString,
|
||||
isBlobLike,
|
||||
parseOrigin,
|
||||
parseURL,
|
||||
|
|
2
deps/undici/src/lib/dispatcher/client-h1.js
vendored
2
deps/undici/src/lib/dispatcher/client-h1.js
vendored
|
@ -249,7 +249,7 @@ class Parser {
|
|||
this.timeout = timers.setFastTimeout(onParserTimeout, delay, new WeakRef(this))
|
||||
} else {
|
||||
this.timeout = setTimeout(onParserTimeout, delay, new WeakRef(this))
|
||||
this.timeout.unref()
|
||||
this.timeout?.unref()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,8 @@ class ProxyAgent extends DispatcherBase {
|
|||
signal: opts.signal,
|
||||
headers: {
|
||||
...this[kProxyHeaders],
|
||||
host: opts.host
|
||||
host: opts.host,
|
||||
...(opts.connections == null || opts.connections > 0 ? { 'proxy-connection': 'keep-alive' } : {})
|
||||
},
|
||||
servername: this[kProxyTls]?.servername || proxyHostname
|
||||
})
|
||||
|
|
166
deps/undici/src/lib/handler/retry-handler.js
vendored
166
deps/undici/src/lib/handler/retry-handler.js
vendored
|
@ -29,13 +29,16 @@ class RetryHandler {
|
|||
methods,
|
||||
errorCodes,
|
||||
retryAfter,
|
||||
statusCodes
|
||||
statusCodes,
|
||||
throwOnError
|
||||
} = retryOptions ?? {}
|
||||
|
||||
this.error = null
|
||||
this.dispatch = dispatch
|
||||
this.handler = WrapHandler.wrap(handler)
|
||||
this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) }
|
||||
this.retryOpts = {
|
||||
throwOnError: throwOnError ?? true,
|
||||
retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry],
|
||||
retryAfter: retryAfter ?? true,
|
||||
maxTimeout: maxTimeout ?? 30 * 1000, // 30s,
|
||||
|
@ -68,6 +71,50 @@ class RetryHandler {
|
|||
this.etag = null
|
||||
}
|
||||
|
||||
onResponseStartWithRetry (controller, statusCode, headers, statusMessage, err) {
|
||||
if (this.retryOpts.throwOnError) {
|
||||
// Preserve old behavior for status codes that are not eligible for retry
|
||||
if (this.retryOpts.statusCodes.includes(statusCode) === false) {
|
||||
this.headersSent = true
|
||||
this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage)
|
||||
} else {
|
||||
this.error = err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (isDisturbed(this.opts.body)) {
|
||||
this.headersSent = true
|
||||
this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage)
|
||||
return
|
||||
}
|
||||
|
||||
function shouldRetry (passedErr) {
|
||||
if (passedErr) {
|
||||
this.headersSent = true
|
||||
|
||||
this.headersSent = true
|
||||
this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage)
|
||||
controller.resume()
|
||||
return
|
||||
}
|
||||
|
||||
this.error = err
|
||||
controller.resume()
|
||||
}
|
||||
|
||||
controller.pause()
|
||||
this.retryOpts.retry(
|
||||
err,
|
||||
{
|
||||
state: { counter: this.retryCount },
|
||||
opts: { retryOptions: this.retryOpts, ...this.opts }
|
||||
},
|
||||
shouldRetry.bind(this)
|
||||
)
|
||||
}
|
||||
|
||||
onRequestStart (controller, context) {
|
||||
if (!this.headersSent) {
|
||||
this.handler.onRequestStart?.(controller, context)
|
||||
|
@ -137,26 +184,19 @@ class RetryHandler {
|
|||
}
|
||||
|
||||
onResponseStart (controller, statusCode, headers, statusMessage) {
|
||||
this.error = null
|
||||
this.retryCount += 1
|
||||
|
||||
if (statusCode >= 300) {
|
||||
if (this.retryOpts.statusCodes.includes(statusCode) === false) {
|
||||
this.headersSent = true
|
||||
this.handler.onResponseStart?.(
|
||||
controller,
|
||||
statusCode,
|
||||
headers,
|
||||
statusMessage
|
||||
)
|
||||
return
|
||||
} else {
|
||||
throw new RequestRetryError('Request failed', statusCode, {
|
||||
headers,
|
||||
data: {
|
||||
count: this.retryCount
|
||||
}
|
||||
})
|
||||
}
|
||||
const err = new RequestRetryError('Request failed', statusCode, {
|
||||
headers,
|
||||
data: {
|
||||
count: this.retryCount
|
||||
}
|
||||
})
|
||||
|
||||
this.onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Checkpoint for resume from where we left it
|
||||
|
@ -175,6 +215,7 @@ class RetryHandler {
|
|||
const contentRange = parseRangeHeader(headers['content-range'])
|
||||
// If no content range
|
||||
if (!contentRange) {
|
||||
// We always throw here as we want to indicate that we entred unexpected path
|
||||
throw new RequestRetryError('Content-Range mismatch', statusCode, {
|
||||
headers,
|
||||
data: { count: this.retryCount }
|
||||
|
@ -183,6 +224,7 @@ class RetryHandler {
|
|||
|
||||
// Let's start with a weak etag check
|
||||
if (this.etag != null && this.etag !== headers.etag) {
|
||||
// We always throw here as we want to indicate that we entred unexpected path
|
||||
throw new RequestRetryError('ETag mismatch', statusCode, {
|
||||
headers,
|
||||
data: { count: this.retryCount }
|
||||
|
@ -266,14 +308,52 @@ class RetryHandler {
|
|||
}
|
||||
|
||||
onResponseData (controller, chunk) {
|
||||
if (this.error) {
|
||||
return
|
||||
}
|
||||
|
||||
this.start += chunk.length
|
||||
|
||||
this.handler.onResponseData?.(controller, chunk)
|
||||
}
|
||||
|
||||
onResponseEnd (controller, trailers) {
|
||||
this.retryCount = 0
|
||||
return this.handler.onResponseEnd?.(controller, trailers)
|
||||
if (this.error && this.retryOpts.throwOnError) {
|
||||
throw this.error
|
||||
}
|
||||
|
||||
if (!this.error) {
|
||||
this.retryCount = 0
|
||||
return this.handler.onResponseEnd?.(controller, trailers)
|
||||
}
|
||||
|
||||
this.retry(controller)
|
||||
}
|
||||
|
||||
retry (controller) {
|
||||
if (this.start !== 0) {
|
||||
const headers = { range: `bytes=${this.start}-${this.end ?? ''}` }
|
||||
|
||||
// Weak etag check - weak etags will make comparison algorithms never match
|
||||
if (this.etag != null) {
|
||||
headers['if-match'] = this.etag
|
||||
}
|
||||
|
||||
this.opts = {
|
||||
...this.opts,
|
||||
headers: {
|
||||
...this.opts.headers,
|
||||
...headers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this.retryCountCheckpoint = this.retryCount
|
||||
this.dispatch(this.opts, this)
|
||||
} catch (err) {
|
||||
this.handler.onResponseError?.(controller, err)
|
||||
}
|
||||
}
|
||||
|
||||
onResponseError (controller, err) {
|
||||
|
@ -282,6 +362,15 @@ class RetryHandler {
|
|||
return
|
||||
}
|
||||
|
||||
function shouldRetry (returnedErr) {
|
||||
if (!returnedErr) {
|
||||
this.retry(controller)
|
||||
return
|
||||
}
|
||||
|
||||
this.handler?.onResponseError?.(controller, returnedErr)
|
||||
}
|
||||
|
||||
// We reconcile in case of a mix between network errors
|
||||
// and server error response
|
||||
if (this.retryCount - this.retryCountCheckpoint > 0) {
|
||||
|
@ -299,43 +388,8 @@ class RetryHandler {
|
|||
state: { counter: this.retryCount },
|
||||
opts: { retryOptions: this.retryOpts, ...this.opts }
|
||||
},
|
||||
onRetry.bind(this)
|
||||
shouldRetry.bind(this)
|
||||
)
|
||||
|
||||
/**
|
||||
* @this {RetryHandler}
|
||||
* @param {Error} [err]
|
||||
* @returns
|
||||
*/
|
||||
function onRetry (err) {
|
||||
if (err != null || controller?.aborted || isDisturbed(this.opts.body)) {
|
||||
return this.handler.onResponseError?.(controller, err)
|
||||
}
|
||||
|
||||
if (this.start !== 0) {
|
||||
const headers = { range: `bytes=${this.start}-${this.end ?? ''}` }
|
||||
|
||||
// Weak etag check - weak etags will make comparison algorithms never match
|
||||
if (this.etag != null) {
|
||||
headers['if-match'] = this.etag
|
||||
}
|
||||
|
||||
this.opts = {
|
||||
...this.opts,
|
||||
headers: {
|
||||
...this.opts.headers,
|
||||
...headers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this.retryCountCheckpoint = this.retryCount
|
||||
this.dispatch(this.opts, this)
|
||||
} catch (err) {
|
||||
this.handler.onResponseError?.(controller, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
> undici@7.10.0 build:wasm
|
||||
> undici@7.11.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
|
||||
|
|
4
deps/undici/src/lib/mock/mock-client.js
vendored
4
deps/undici/src/lib/mock/mock-client.js
vendored
|
@ -54,6 +54,10 @@ class MockClient extends Client {
|
|||
)
|
||||
}
|
||||
|
||||
cleanMocks () {
|
||||
this[kDispatches] = []
|
||||
}
|
||||
|
||||
async [kClose] () {
|
||||
await promisify(this[kOriginalClose])()
|
||||
this[kConnected] = 0
|
||||
|
|
4
deps/undici/src/lib/mock/mock-pool.js
vendored
4
deps/undici/src/lib/mock/mock-pool.js
vendored
|
@ -54,6 +54,10 @@ class MockPool extends Pool {
|
|||
)
|
||||
}
|
||||
|
||||
cleanMocks () {
|
||||
this[kDispatches] = []
|
||||
}
|
||||
|
||||
async [kClose] () {
|
||||
await promisify(this[kOriginalClose])()
|
||||
this[kConnected] = 0
|
||||
|
|
12
deps/undici/src/lib/util/cache.js
vendored
12
deps/undici/src/lib/util/cache.js
vendored
|
@ -4,6 +4,8 @@ const {
|
|||
safeHTTPMethods
|
||||
} = require('../core/util')
|
||||
|
||||
const { serializePathWithQuery } = require('../core/util')
|
||||
|
||||
/**
|
||||
* @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts
|
||||
*/
|
||||
|
@ -12,10 +14,18 @@ function makeCacheKey (opts) {
|
|||
throw new Error('opts.origin is undefined')
|
||||
}
|
||||
|
||||
let fullPath
|
||||
try {
|
||||
fullPath = serializePathWithQuery(opts.path || '/', opts.query)
|
||||
} catch (error) {
|
||||
// If fails (path already has query params), use as-is
|
||||
fullPath = opts.path || '/'
|
||||
}
|
||||
|
||||
return {
|
||||
origin: opts.origin.toString(),
|
||||
method: opts.method,
|
||||
path: opts.path,
|
||||
path: fullPath,
|
||||
headers: opts.headers
|
||||
}
|
||||
}
|
||||
|
|
20
deps/undici/src/lib/util/timers.js
vendored
20
deps/undici/src/lib/util/timers.js
vendored
|
@ -188,19 +188,21 @@ function onTick () {
|
|||
}
|
||||
|
||||
function refreshTimeout () {
|
||||
// If the fastNowTimeout is already set, refresh it.
|
||||
if (fastNowTimeout) {
|
||||
// If the fastNowTimeout is already set and the Timer has the refresh()-
|
||||
// method available, call it to refresh the timer.
|
||||
// Some timer objects returned by setTimeout may not have a .refresh()
|
||||
// method (e.g. mocked timers in tests).
|
||||
if (fastNowTimeout?.refresh) {
|
||||
fastNowTimeout.refresh()
|
||||
// fastNowTimeout is not instantiated yet, create a new Timer.
|
||||
// fastNowTimeout is not instantiated yet or refresh is not availabe,
|
||||
// create a new Timer.
|
||||
} else {
|
||||
clearTimeout(fastNowTimeout)
|
||||
fastNowTimeout = setTimeout(onTick, TICK_MS)
|
||||
|
||||
// If the Timer has an unref method, call it to allow the process to exit if
|
||||
// there are no other active handles.
|
||||
if (fastNowTimeout.unref) {
|
||||
fastNowTimeout.unref()
|
||||
}
|
||||
// If the Timer has an unref method, call it to allow the process to exit,
|
||||
// if there are no other active handles. When using fake timers or mocked
|
||||
// environments (like Jest), .unref() may not be defined,
|
||||
fastNowTimeout?.unref()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
deps/undici/src/lib/web/cache/cache.js
vendored
2
deps/undici/src/lib/web/cache/cache.js
vendored
|
@ -3,7 +3,7 @@
|
|||
const { kConstruct } = require('../../core/symbols')
|
||||
const { urlEquals, getFieldValues } = require('./util')
|
||||
const { kEnumerableProperty, isDisturbed } = require('../../core/util')
|
||||
const { webidl } = require('../fetch/webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { cloneResponse, fromInnerResponse, getResponseState } = require('../fetch/response')
|
||||
const { Request, fromInnerRequest, getRequestState } = require('../fetch/request')
|
||||
const { fetching } = require('../fetch/index')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const { Cache } = require('./cache')
|
||||
const { webidl } = require('../fetch/webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { kEnumerableProperty } = require('../../core/util')
|
||||
const { kConstruct } = require('../../core/symbols')
|
||||
|
||||
|
|
2
deps/undici/src/lib/web/cookies/index.js
vendored
2
deps/undici/src/lib/web/cookies/index.js
vendored
|
@ -2,7 +2,7 @@
|
|||
|
||||
const { parseSetCookie } = require('./parse')
|
||||
const { stringify } = require('./util')
|
||||
const { webidl } = require('../fetch/webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { Headers } = require('../fetch/headers')
|
||||
|
||||
const brandChecks = webidl.brandCheckMultiple([Headers, globalThis.Headers].filter(Boolean))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
const { pipeline } = require('node:stream')
|
||||
const { fetching } = require('../fetch')
|
||||
const { makeRequest } = require('../fetch/request')
|
||||
const { webidl } = require('../fetch/webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { EventSourceStream } = require('./eventsource-stream')
|
||||
const { parseMIMEType } = require('../fetch/data-url')
|
||||
const { createFastMessageEvent } = require('../websocket/events')
|
||||
|
@ -231,12 +231,9 @@ class EventSource extends EventTarget {
|
|||
|
||||
// 14. Let processEventSourceEndOfBody given response res be the following step: if res is not a network error, then reestablish the connection.
|
||||
const processEventSourceEndOfBody = (response) => {
|
||||
if (isNetworkError(response)) {
|
||||
this.dispatchEvent(new Event('error'))
|
||||
this.close()
|
||||
if (!isNetworkError(response)) {
|
||||
return this.#reconnect()
|
||||
}
|
||||
|
||||
this.#reconnect()
|
||||
}
|
||||
|
||||
// 15. Fetch request, with processResponseEndOfBody set to processEventSourceEndOfBody...
|
||||
|
|
2
deps/undici/src/lib/web/eventsource/util.js
vendored
2
deps/undici/src/lib/web/eventsource/util.js
vendored
|
@ -26,7 +26,7 @@ function isASCIINumber (value) {
|
|||
// https://github.com/nodejs/undici/issues/2664
|
||||
function delay (ms) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, ms).unref()
|
||||
setTimeout(resolve, ms)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
4
deps/undici/src/lib/web/fetch/body.js
vendored
4
deps/undici/src/lib/web/fetch/body.js
vendored
|
@ -10,7 +10,7 @@ const {
|
|||
utf8DecodeBytes
|
||||
} = require('./util')
|
||||
const { FormData, setFormDataState } = require('./formdata')
|
||||
const { webidl } = require('./webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { Blob } = require('node:buffer')
|
||||
const assert = require('node:assert')
|
||||
const { isErrored, isDisturbed } = require('node:stream')
|
||||
|
@ -29,7 +29,7 @@ try {
|
|||
const textEncoder = new TextEncoder()
|
||||
function noop () {}
|
||||
|
||||
const hasFinalizationRegistry = globalThis.FinalizationRegistry && process.version.indexOf('v18') !== 0
|
||||
const hasFinalizationRegistry = globalThis.FinalizationRegistry
|
||||
let streamRegistry
|
||||
|
||||
if (hasFinalizationRegistry) {
|
||||
|
|
|
@ -1,46 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
const { kConnected, kSize } = require('../../core/symbols')
|
||||
|
||||
class CompatWeakRef {
|
||||
constructor (value) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
deref () {
|
||||
return this.value[kConnected] === 0 && this.value[kSize] === 0
|
||||
? undefined
|
||||
: this.value
|
||||
}
|
||||
}
|
||||
|
||||
class CompatFinalizer {
|
||||
constructor (finalizer) {
|
||||
this.finalizer = finalizer
|
||||
}
|
||||
|
||||
register (dispatcher, key) {
|
||||
if (dispatcher.on) {
|
||||
dispatcher.on('disconnect', () => {
|
||||
if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) {
|
||||
this.finalizer(key)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
unregister (key) {}
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
// FIXME: remove workaround when the Node bug is backported to v18
|
||||
// https://github.com/nodejs/node/issues/49344#issuecomment-1741776308
|
||||
if (process.env.NODE_V8_COVERAGE && process.version.startsWith('v18')) {
|
||||
process._rawDebug('Using compatibility WeakRef and FinalizationRegistry')
|
||||
return {
|
||||
WeakRef: CompatWeakRef,
|
||||
FinalizationRegistry: CompatFinalizer
|
||||
}
|
||||
}
|
||||
return { WeakRef, FinalizationRegistry }
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
'use strict'
|
||||
|
||||
const { isUSVString, bufferToLowerCasedHeaderName } = require('../../core/util')
|
||||
const { bufferToLowerCasedHeaderName } = require('../../core/util')
|
||||
const { utf8DecodeBytes } = require('./util')
|
||||
const { HTTP_TOKEN_CODEPOINTS, isomorphicDecode } = require('./data-url')
|
||||
const { makeEntry } = require('./formdata')
|
||||
const { webidl } = require('./webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const assert = require('node:assert')
|
||||
const { File: NodeFile } = require('node:buffer')
|
||||
|
||||
|
@ -200,8 +200,8 @@ function multipartFormDataParser (input, mimeType) {
|
|||
}
|
||||
|
||||
// 5.12. Assert: name is a scalar value string and value is either a scalar value string or a File object.
|
||||
assert(isUSVString(name))
|
||||
assert((typeof value === 'string' && isUSVString(value)) || webidl.is.File(value))
|
||||
assert(webidl.is.USVString(name))
|
||||
assert((typeof value === 'string' && webidl.is.USVString(value)) || webidl.is.File(value))
|
||||
|
||||
// 5.13. Create an entry with name and value, and append it to entry list.
|
||||
entryList.push(makeEntry(name, value, filename))
|
||||
|
|
2
deps/undici/src/lib/web/fetch/formdata.js
vendored
2
deps/undici/src/lib/web/fetch/formdata.js
vendored
|
@ -2,7 +2,7 @@
|
|||
|
||||
const { iteratorMixin } = require('./util')
|
||||
const { kEnumerableProperty } = require('../../core/util')
|
||||
const { webidl } = require('./webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { File: NativeFile } = require('node:buffer')
|
||||
const nodeUtil = require('node:util')
|
||||
|
||||
|
|
2
deps/undici/src/lib/web/fetch/headers.js
vendored
2
deps/undici/src/lib/web/fetch/headers.js
vendored
|
@ -9,7 +9,7 @@ const {
|
|||
isValidHeaderName,
|
||||
isValidHeaderValue
|
||||
} = require('./util')
|
||||
const { webidl } = require('./webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const assert = require('node:assert')
|
||||
const util = require('node:util')
|
||||
|
||||
|
|
8
deps/undici/src/lib/web/fetch/index.js
vendored
8
deps/undici/src/lib/web/fetch/index.js
vendored
|
@ -61,7 +61,7 @@ const { Readable, pipeline, finished, isErrored, isReadable } = require('node:st
|
|||
const { addAbortListener, bufferToLowerCasedHeaderName } = require('../../core/util')
|
||||
const { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = require('./data-url')
|
||||
const { getGlobalDispatcher } = require('../../global')
|
||||
const { webidl } = require('./webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { STATUS_CODES } = require('node:http')
|
||||
const GET_OR_HEAD = ['GET', 'HEAD']
|
||||
|
||||
|
@ -2155,6 +2155,12 @@ async function httpNetworkFetch (
|
|||
flush: zlib.constants.BROTLI_OPERATION_FLUSH,
|
||||
finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
|
||||
}))
|
||||
} else if (coding === 'zstd' && typeof zlib.createZstdDecompress === 'function') {
|
||||
// Node.js v23.8.0+ and v22.15.0+ supports Zstandard
|
||||
decoders.push(zlib.createZstdDecompress({
|
||||
flush: zlib.constants.ZSTD_e_continue,
|
||||
finishFlush: zlib.constants.ZSTD_e_end
|
||||
}))
|
||||
} else {
|
||||
decoders.length = 0
|
||||
break
|
||||
|
|
2
deps/undici/src/lib/web/fetch/request.js
vendored
2
deps/undici/src/lib/web/fetch/request.js
vendored
|
@ -23,7 +23,7 @@ const {
|
|||
requestDuplex
|
||||
} = require('./constants')
|
||||
const { kEnumerableProperty, normalizedMethodRecordsBase, normalizedMethodRecords } = util
|
||||
const { webidl } = require('./webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { URLSerializer } = require('./data-url')
|
||||
const { kConstruct } = require('../../core/symbols')
|
||||
const assert = require('node:assert')
|
||||
|
|
2
deps/undici/src/lib/web/fetch/response.js
vendored
2
deps/undici/src/lib/web/fetch/response.js
vendored
|
@ -18,7 +18,7 @@ const {
|
|||
redirectStatusSet,
|
||||
nullBodyStatus
|
||||
} = require('./constants')
|
||||
const { webidl } = require('./webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { URLSerializer } = require('./data-url')
|
||||
const { kConstruct } = require('../../core/symbols')
|
||||
const assert = require('node:assert')
|
||||
|
|
4
deps/undici/src/lib/web/fetch/util.js
vendored
4
deps/undici/src/lib/web/fetch/util.js
vendored
|
@ -9,7 +9,7 @@ const { performance } = require('node:perf_hooks')
|
|||
const { ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require('../../core/util')
|
||||
const assert = require('node:assert')
|
||||
const { isUint8Array } = require('node:util/types')
|
||||
const { webidl } = require('./webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
|
||||
let supportedHashes = []
|
||||
|
||||
|
@ -1262,7 +1262,7 @@ async function readAllBytes (reader, successSteps, failureSteps) {
|
|||
// 1. If chunk is not a Uint8Array object, call failureSteps
|
||||
// with a TypeError and abort these steps.
|
||||
if (!isUint8Array(chunk)) {
|
||||
failureSteps(TypeError('Received non-Uint8Array chunk'))
|
||||
failureSteps(new TypeError('Received non-Uint8Array chunk'))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
const { types, inspect } = require('node:util')
|
||||
const { markAsUncloneable } = require('node:worker_threads')
|
||||
const { toUSVString } = require('../../core/util')
|
||||
|
||||
const UNDEFINED = 1
|
||||
const BOOLEAN = 2
|
||||
|
@ -23,22 +22,48 @@ const webidl = {
|
|||
is: {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Instantiate an error.
|
||||
*
|
||||
* @param {Object} opts
|
||||
* @param {string} opts.header
|
||||
* @param {string} opts.message
|
||||
* @returns {TypeError}
|
||||
*/
|
||||
webidl.errors.exception = function (message) {
|
||||
return new TypeError(`${message.header}: ${message.message}`)
|
||||
}
|
||||
|
||||
webidl.errors.conversionFailed = function (context) {
|
||||
const plural = context.types.length === 1 ? '' : ' one of'
|
||||
/**
|
||||
* @description Instantiate an error when conversion from one type to another has failed.
|
||||
*
|
||||
* @param {Object} opts
|
||||
* @param {string} opts.prefix
|
||||
* @param {string} opts.argument
|
||||
* @param {string[]} opts.types
|
||||
* @returns {TypeError}
|
||||
*/
|
||||
webidl.errors.conversionFailed = function (opts) {
|
||||
const plural = opts.types.length === 1 ? '' : ' one of'
|
||||
const message =
|
||||
`${context.argument} could not be converted to` +
|
||||
`${plural}: ${context.types.join(', ')}.`
|
||||
`${opts.argument} could not be converted to` +
|
||||
`${plural}: ${opts.types.join(', ')}.`
|
||||
|
||||
return webidl.errors.exception({
|
||||
header: context.prefix,
|
||||
header: opts.prefix,
|
||||
message
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Instantiate an error when an invalid argument is provided
|
||||
*
|
||||
* @param {Object} context
|
||||
* @param {string} context.prefix
|
||||
* @param {string} context.value
|
||||
* @param {string} context.type
|
||||
* @returns {TypeError}
|
||||
*/
|
||||
webidl.errors.invalidArgument = function (context) {
|
||||
return webidl.errors.exception({
|
||||
header: context.prefix,
|
||||
|
@ -278,6 +303,8 @@ webidl.util.Stringify = function (V) {
|
|||
return inspect(V)
|
||||
case STRING:
|
||||
return `"${V}"`
|
||||
case BIGINT:
|
||||
return `${V}n`
|
||||
default:
|
||||
return `${V}`
|
||||
}
|
||||
|
@ -468,6 +495,17 @@ webidl.nullableConverter = function (converter) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
webidl.is.USVString = function (value) {
|
||||
return (
|
||||
typeof value === 'string' &&
|
||||
value.isWellFormed()
|
||||
)
|
||||
}
|
||||
|
||||
webidl.is.ReadableStream = webidl.util.MakeTypeAssertion(ReadableStream)
|
||||
webidl.is.Blob = webidl.util.MakeTypeAssertion(Blob)
|
||||
webidl.is.URLSearchParams = webidl.util.MakeTypeAssertion(URLSearchParams)
|
||||
|
@ -529,13 +567,23 @@ webidl.converters.ByteString = function (V, prefix, argument) {
|
|||
return x
|
||||
}
|
||||
|
||||
// https://webidl.spec.whatwg.org/#es-USVString
|
||||
// TODO: rewrite this so we can control the errors thrown
|
||||
webidl.converters.USVString = toUSVString
|
||||
/**
|
||||
* @param {unknown} value
|
||||
* @returns {string}
|
||||
* @see https://webidl.spec.whatwg.org/#es-USVString
|
||||
*/
|
||||
webidl.converters.USVString = function (value) {
|
||||
// TODO: rewrite this so we can control the errors thrown
|
||||
if (typeof value === 'string') {
|
||||
return value.toWellFormed()
|
||||
}
|
||||
return `${value}`.toWellFormed()
|
||||
}
|
||||
|
||||
// https://webidl.spec.whatwg.org/#es-boolean
|
||||
webidl.converters.boolean = function (V) {
|
||||
// 1. Let x be the result of computing ToBoolean(V).
|
||||
// https://262.ecma-international.org/10.0/index.html#table-10
|
||||
const x = Boolean(V)
|
||||
|
||||
// 2. Return the IDL boolean value that is the one that represents
|
|
@ -105,7 +105,7 @@ function establishWebSocketConnection (url, protocols, client, handler, options)
|
|||
// 1. If response is a network error or its status is not 101,
|
||||
// fail the WebSocket connection.
|
||||
if (response.type === 'error' || response.status !== 101) {
|
||||
failWebsocketConnection(handler, 1002, 'Received network error or non-101 status code.')
|
||||
failWebsocketConnection(handler, 1002, 'Received network error or non-101 status code.', response.error)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -298,9 +298,10 @@ function closeWebSocketConnection (object, code, reason, validate = false) {
|
|||
* @param {import('./websocket').Handler} handler
|
||||
* @param {number} code
|
||||
* @param {string|undefined} reason
|
||||
* @param {unknown} cause
|
||||
* @returns {void}
|
||||
*/
|
||||
function failWebsocketConnection (handler, code, reason) {
|
||||
function failWebsocketConnection (handler, code, reason, cause) {
|
||||
// If _The WebSocket Connection is Established_ prior to the point where
|
||||
// the endpoint is required to _Fail the WebSocket Connection_, the
|
||||
// endpoint SHOULD send a Close frame with an appropriate status code
|
||||
|
@ -315,7 +316,7 @@ function failWebsocketConnection (handler, code, reason) {
|
|||
handler.socket.destroy()
|
||||
}
|
||||
|
||||
handler.onFail(code, reason)
|
||||
handler.onFail(code, reason, cause)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
2
deps/undici/src/lib/web/websocket/events.js
vendored
2
deps/undici/src/lib/web/websocket/events.js
vendored
|
@ -1,6 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
const { webidl } = require('../fetch/webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { kEnumerableProperty } = require('../../core/util')
|
||||
const { kConstruct } = require('../../core/symbols')
|
||||
|
||||
|
|
3
deps/undici/src/lib/web/websocket/frame.js
vendored
3
deps/undici/src/lib/web/websocket/frame.js
vendored
|
@ -134,5 +134,6 @@ class WebsocketFrameSend {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
WebsocketFrameSend
|
||||
WebsocketFrameSend,
|
||||
generateMask // for benchmark
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
const { webidl } = require('../../fetch/webidl')
|
||||
const { webidl } = require('../../webidl')
|
||||
const { validateCloseCodeAndReason } = require('../util')
|
||||
const { kConstruct } = require('../../../core/symbols')
|
||||
const { kEnumerableProperty } = require('../../../core/util')
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
const { createDeferredPromise, environmentSettingsObject } = require('../../fetch/util')
|
||||
const { states, opcodes, sentCloseFrameState } = require('../constants')
|
||||
const { webidl } = require('../../fetch/webidl')
|
||||
const { webidl } = require('../../webidl')
|
||||
const { getURLRecord, isValidSubprotocol, isEstablished, utf8Decode } = require('../util')
|
||||
const { establishWebSocketConnection, failWebsocketConnection, closeWebSocketConnection } = require('../connection')
|
||||
const { types } = require('node:util')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
const { webidl } = require('../fetch/webidl')
|
||||
const { webidl } = require('../webidl')
|
||||
const { URLSerializer } = require('../fetch/data-url')
|
||||
const { environmentSettingsObject } = require('../fetch/util')
|
||||
const { staticPropertyDescriptors, states, sentCloseFrameState, sendHints, opcodes } = require('./constants')
|
||||
|
@ -60,7 +60,7 @@ class WebSocket extends EventTarget {
|
|||
/** @type {Handler} */
|
||||
#handler = {
|
||||
onConnectionEstablished: (response, extensions) => this.#onConnectionEstablished(response, extensions),
|
||||
onFail: (code, reason) => this.#onFail(code, reason),
|
||||
onFail: (code, reason, cause) => this.#onFail(code, reason, cause),
|
||||
onMessage: (opcode, data) => this.#onMessage(opcode, data),
|
||||
onParserError: (err) => failWebsocketConnection(this.#handler, null, err.message),
|
||||
onParserDrain: () => this.#onParserDrain(),
|
||||
|
@ -462,11 +462,11 @@ class WebSocket extends EventTarget {
|
|||
fireEvent('open', this)
|
||||
}
|
||||
|
||||
#onFail (code, reason) {
|
||||
#onFail (code, reason, cause) {
|
||||
if (reason) {
|
||||
// TODO: process.nextTick
|
||||
fireEvent('error', this, (type, init) => new ErrorEvent(type, init), {
|
||||
error: new Error(reason),
|
||||
error: new Error(reason, cause ? { cause } : undefined),
|
||||
message: reason
|
||||
})
|
||||
}
|
||||
|
|
1088
deps/undici/src/package-lock.json
generated
vendored
1088
deps/undici/src/package-lock.json
generated
vendored
File diff suppressed because it is too large
Load diff
8
deps/undici/src/package.json
vendored
8
deps/undici/src/package.json
vendored
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "undici",
|
||||
"version": "7.10.0",
|
||||
"version": "7.11.0",
|
||||
"description": "An HTTP/1.1 client, written from scratch for Node.js",
|
||||
"homepage": "https://undici.nodejs.org",
|
||||
"bugs": {
|
||||
|
@ -112,20 +112,20 @@
|
|||
"@sinonjs/fake-timers": "^12.0.0",
|
||||
"@types/node": "^18.19.50",
|
||||
"abort-controller": "^3.0.0",
|
||||
"borp": "^0.19.0",
|
||||
"borp": "^0.20.0",
|
||||
"c8": "^10.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"dns-packet": "^5.4.0",
|
||||
"esbuild": "^0.25.2",
|
||||
"eslint": "^9.9.0",
|
||||
"fast-check": "^3.17.1",
|
||||
"fast-check": "^4.1.1",
|
||||
"https-pem": "^3.0.0",
|
||||
"husky": "^9.0.7",
|
||||
"jest": "^29.0.2",
|
||||
"neostandard": "^0.12.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"proxy": "^2.1.1",
|
||||
"tsd": "^0.31.2",
|
||||
"tsd": "^0.32.0",
|
||||
"typescript": "^5.6.2",
|
||||
"ws": "^8.11.0"
|
||||
},
|
||||
|
|
|
@ -31,6 +31,15 @@ declare namespace DiagnosticsChannel {
|
|||
export interface RequestBodySentMessage {
|
||||
request: Request;
|
||||
}
|
||||
|
||||
export interface RequestBodyChunkSentMessage {
|
||||
request: Request;
|
||||
chunk: Uint8Array | string;
|
||||
}
|
||||
export interface RequestBodyChunkReceivedMessage {
|
||||
request: Request;
|
||||
chunk: Buffer;
|
||||
}
|
||||
export interface RequestHeadersMessage {
|
||||
request: Request;
|
||||
response: Response;
|
||||
|
|
5
deps/undici/src/types/dispatcher.d.ts
vendored
5
deps/undici/src/types/dispatcher.d.ts
vendored
|
@ -97,7 +97,8 @@ declare class Dispatcher extends EventEmitter {
|
|||
|
||||
declare namespace Dispatcher {
|
||||
export interface ComposedDispatcher extends Dispatcher {}
|
||||
export type DispatcherComposeInterceptor = (dispatch: Dispatcher['dispatch']) => Dispatcher['dispatch']
|
||||
export type Dispatch = Dispatcher['dispatch']
|
||||
export type DispatcherComposeInterceptor = (dispatch: Dispatch) => Dispatch
|
||||
export interface DispatchOptions {
|
||||
origin?: string | URL;
|
||||
path: string;
|
||||
|
@ -276,6 +277,6 @@ declare namespace Dispatcher {
|
|||
}
|
||||
|
||||
export interface DispatchInterceptor {
|
||||
(dispatch: Dispatcher['dispatch']): Dispatcher['dispatch']
|
||||
(dispatch: Dispatch): Dispatch
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Agent from './agent'
|
||||
import ProxyAgent from './proxy-agent'
|
||||
import Dispatcher from './dispatcher'
|
||||
|
||||
export default EnvHttpProxyAgent
|
||||
|
@ -10,7 +11,7 @@ declare class EnvHttpProxyAgent extends Dispatcher {
|
|||
}
|
||||
|
||||
declare namespace EnvHttpProxyAgent {
|
||||
export interface Options extends Agent.Options {
|
||||
export interface Options extends Omit<ProxyAgent.Options, 'uri'> {
|
||||
/** Overrides the value of the HTTP_PROXY environment variable */
|
||||
httpProxy?: string;
|
||||
/** Overrides the value of the HTTPS_PROXY environment variable */
|
||||
|
|
6
deps/undici/src/types/eventsource.d.ts
vendored
6
deps/undici/src/types/eventsource.d.ts
vendored
|
@ -18,9 +18,9 @@ interface EventSource extends EventTarget {
|
|||
readonly CLOSED: 2
|
||||
readonly CONNECTING: 0
|
||||
readonly OPEN: 1
|
||||
onerror: (this: EventSource, ev: ErrorEvent) => any
|
||||
onmessage: (this: EventSource, ev: MessageEvent) => any
|
||||
onopen: (this: EventSource, ev: Event) => any
|
||||
onerror: ((this: EventSource, ev: ErrorEvent) => any) | null
|
||||
onmessage: ((this: EventSource, ev: MessageEvent) => any) | null
|
||||
onopen: ((this: EventSource, ev: Event) => any) | null
|
||||
readonly readyState: 0 | 1 | 2
|
||||
readonly url: string
|
||||
readonly withCredentials: boolean
|
||||
|
|
1
deps/undici/src/types/fetch.d.ts
vendored
1
deps/undici/src/types/fetch.d.ts
vendored
|
@ -33,6 +33,7 @@ export class BodyMixin {
|
|||
|
||||
readonly arrayBuffer: () => Promise<ArrayBuffer>
|
||||
readonly blob: () => Promise<Blob>
|
||||
readonly bytes: () => Promise<Uint8Array>
|
||||
/**
|
||||
* @deprecated This method is not recommended for parsing multipart/form-data bodies in server environments.
|
||||
* It is recommended to use a library such as [@fastify/busboy](https://www.npmjs.com/package/@fastify/busboy) as follows:
|
||||
|
|
2
deps/undici/src/types/handlers.d.ts
vendored
2
deps/undici/src/types/handlers.d.ts
vendored
|
@ -2,7 +2,7 @@ import Dispatcher from './dispatcher'
|
|||
|
||||
export declare class RedirectHandler implements Dispatcher.DispatchHandler {
|
||||
constructor (
|
||||
dispatch: Dispatcher,
|
||||
dispatch: Dispatcher.Dispatch,
|
||||
maxRedirections: number,
|
||||
opts: Dispatcher.DispatchOptions,
|
||||
handler: Dispatcher.DispatchHandler,
|
||||
|
|
2
deps/undici/src/types/mock-client.d.ts
vendored
2
deps/undici/src/types/mock-client.d.ts
vendored
|
@ -14,6 +14,8 @@ declare class MockClient extends Client implements Interceptable {
|
|||
dispatch (options: Dispatcher.DispatchOptions, handlers: Dispatcher.DispatchHandler): boolean
|
||||
/** Closes the mock client and gracefully waits for enqueued requests to complete. */
|
||||
close (): Promise<void>
|
||||
/** Clean up all the prepared mocks. */
|
||||
cleanMocks (): void
|
||||
}
|
||||
|
||||
declare namespace MockClient {
|
||||
|
|
2
deps/undici/src/types/mock-interceptor.d.ts
vendored
2
deps/undici/src/types/mock-interceptor.d.ts
vendored
|
@ -84,6 +84,8 @@ declare namespace MockInterceptor {
|
|||
interface Interceptable extends Dispatcher {
|
||||
/** Intercepts any matching requests that use the same origin as this mock client. */
|
||||
intercept(options: MockInterceptor.Options): MockInterceptor;
|
||||
/** Clean up all the prepared mocks. */
|
||||
cleanMocks (): void
|
||||
}
|
||||
|
||||
export {
|
||||
|
|
2
deps/undici/src/types/mock-pool.d.ts
vendored
2
deps/undici/src/types/mock-pool.d.ts
vendored
|
@ -14,6 +14,8 @@ declare class MockPool extends Pool implements Interceptable {
|
|||
dispatch (options: Dispatcher.DispatchOptions, handlers: Dispatcher.DispatchHandler): boolean
|
||||
/** Closes the mock pool and gracefully waits for enqueued requests to complete. */
|
||||
close (): Promise<void>
|
||||
/** Clean up all the prepared mocks. */
|
||||
cleanMocks (): void
|
||||
}
|
||||
|
||||
declare namespace MockPool {
|
||||
|
|
9
deps/undici/src/types/retry-handler.d.ts
vendored
9
deps/undici/src/types/retry-handler.d.ts
vendored
|
@ -35,6 +35,15 @@ declare namespace RetryHandler {
|
|||
) => void
|
||||
|
||||
export interface RetryOptions {
|
||||
/**
|
||||
* If true, the retry handler will throw an error if the request fails,
|
||||
* this will prevent the folling handlers from being called, and will destroy the socket.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof RetryOptions
|
||||
* @default true
|
||||
*/
|
||||
throwOnError?: boolean;
|
||||
/**
|
||||
* Callback to be invoked on every retry iteration.
|
||||
* It receives the error, current state of the retry object and the options object
|
||||
|
|
34
deps/undici/src/types/webidl.d.ts
vendored
34
deps/undici/src/types/webidl.d.ts
vendored
|
@ -16,9 +16,12 @@ interface ConvertToIntOpts {
|
|||
}
|
||||
|
||||
interface WebidlErrors {
|
||||
/**
|
||||
* @description Instantiate an error
|
||||
*/
|
||||
exception (opts: { header: string, message: string }): TypeError
|
||||
/**
|
||||
* @description Throw an error when conversion from one type to another has failed
|
||||
* @description Instantiate an error when conversion from one type to another has failed
|
||||
*/
|
||||
conversionFailed (opts: {
|
||||
prefix: string
|
||||
|
@ -75,7 +78,7 @@ interface WebidlUtil {
|
|||
): number
|
||||
|
||||
/**
|
||||
* @see https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
|
||||
* @see https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
|
||||
*/
|
||||
IntegerPart (N: number): number
|
||||
|
||||
|
@ -182,20 +185,21 @@ interface WebidlConverters {
|
|||
[Key: string]: (...args: any[]) => unknown
|
||||
}
|
||||
|
||||
type IsAssertion<T> = (arg: any) => arg is T
|
||||
type WebidlIsFunction<T> = (arg: any) => arg is T
|
||||
|
||||
interface WebidlIs {
|
||||
Request: IsAssertion<undici.Request>
|
||||
Response: IsAssertion<undici.Response>
|
||||
ReadableStream: IsAssertion<ReadableStream>
|
||||
Blob: IsAssertion<Blob>
|
||||
URLSearchParams: IsAssertion<URLSearchParams>
|
||||
File: IsAssertion<File>
|
||||
FormData: IsAssertion<undici.FormData>
|
||||
URL: IsAssertion<URL>
|
||||
WebSocketError: IsAssertion<undici.WebSocketError>
|
||||
AbortSignal: IsAssertion<AbortSignal>
|
||||
MessagePort: IsAssertion<MessagePort>
|
||||
Request: WebidlIsFunction<undici.Request>
|
||||
Response: WebidlIsFunction<undici.Response>
|
||||
ReadableStream: WebidlIsFunction<ReadableStream>
|
||||
Blob: WebidlIsFunction<Blob>
|
||||
URLSearchParams: WebidlIsFunction<URLSearchParams>
|
||||
File: WebidlIsFunction<File>
|
||||
FormData: WebidlIsFunction<undici.FormData>
|
||||
URL: WebidlIsFunction<URL>
|
||||
WebSocketError: WebidlIsFunction<undici.WebSocketError>
|
||||
AbortSignal: WebidlIsFunction<AbortSignal>
|
||||
MessagePort: WebidlIsFunction<MessagePort>
|
||||
USVString: WebidlIsFunction<string>
|
||||
}
|
||||
|
||||
export interface Webidl {
|
||||
|
@ -233,7 +237,7 @@ export interface Webidl {
|
|||
* Similar to {@link Webidl.brandCheck} but allows skipping the check if third party
|
||||
* interfaces are allowed.
|
||||
*/
|
||||
interfaceConverter <Interface>(typeCheck: IsAssertion<Interface>, name: string): (
|
||||
interfaceConverter <Interface>(typeCheck: WebidlIsFunction<Interface>, name: string): (
|
||||
V: unknown,
|
||||
prefix: string,
|
||||
argument: string
|
||||
|
|
2
deps/undici/src/types/websocket.d.ts
vendored
2
deps/undici/src/types/websocket.d.ts
vendored
|
@ -136,7 +136,7 @@ interface ErrorEvent extends Event {
|
|||
readonly filename: string
|
||||
readonly lineno: number
|
||||
readonly colno: number
|
||||
readonly error: any
|
||||
readonly error: Error
|
||||
}
|
||||
|
||||
export declare const ErrorEvent: {
|
||||
|
|
224
deps/undici/undici.js
vendored
224
deps/undici/undici.js
vendored
|
@ -543,14 +543,12 @@ var require_timers = __commonJS({
|
|||
}
|
||||
__name(onTick, "onTick");
|
||||
function refreshTimeout() {
|
||||
if (fastNowTimeout) {
|
||||
if (fastNowTimeout?.refresh) {
|
||||
fastNowTimeout.refresh();
|
||||
} else {
|
||||
clearTimeout(fastNowTimeout);
|
||||
fastNowTimeout = setTimeout(onTick, TICK_MS);
|
||||
if (fastNowTimeout.unref) {
|
||||
fastNowTimeout.unref();
|
||||
}
|
||||
fastNowTimeout?.unref();
|
||||
}
|
||||
}
|
||||
__name(refreshTimeout, "refreshTimeout");
|
||||
|
@ -1022,7 +1020,6 @@ var require_util = __commonJS({
|
|||
var stream = require("node:stream");
|
||||
var net = require("node:net");
|
||||
var { Blob: Blob2 } = require("node:buffer");
|
||||
var nodeUtil = require("node:util");
|
||||
var { stringify } = require("node:querystring");
|
||||
var { EventEmitter: EE } = require("node:events");
|
||||
var timers = require_timers();
|
||||
|
@ -1411,20 +1408,6 @@ var require_util = __commonJS({
|
|||
return () => signal.removeListener("abort", listener);
|
||||
}
|
||||
__name(addAbortListener, "addAbortListener");
|
||||
var toUSVString = (() => {
|
||||
if (typeof String.prototype.toWellFormed === "function") {
|
||||
return (value) => `${value}`.toWellFormed();
|
||||
} else {
|
||||
return nodeUtil.toUSVString;
|
||||
}
|
||||
})();
|
||||
var isUSVString = (() => {
|
||||
if (typeof String.prototype.isWellFormed === "function") {
|
||||
return (value) => `${value}`.isWellFormed();
|
||||
} else {
|
||||
return (value) => toUSVString(value) === `${value}`;
|
||||
}
|
||||
})();
|
||||
function isTokenCharCode(c) {
|
||||
switch (c) {
|
||||
case 34:
|
||||
|
@ -1575,8 +1558,6 @@ var require_util = __commonJS({
|
|||
module2.exports = {
|
||||
kEnumerableProperty,
|
||||
isDisturbed,
|
||||
toUSVString,
|
||||
isUSVString,
|
||||
isBlobLike,
|
||||
parseOrigin,
|
||||
parseURL,
|
||||
|
@ -2147,6 +2128,8 @@ var require_diagnostics = __commonJS({
|
|||
// Request
|
||||
create: diagnosticsChannel.channel("undici:request:create"),
|
||||
bodySent: diagnosticsChannel.channel("undici:request:bodySent"),
|
||||
bodyChunkSent: diagnosticsChannel.channel("undici:request:bodyChunkSent"),
|
||||
bodyChunkReceived: diagnosticsChannel.channel("undici:request:bodyChunkReceived"),
|
||||
headers: diagnosticsChannel.channel("undici:request:headers"),
|
||||
trailers: diagnosticsChannel.channel("undici:request:trailers"),
|
||||
error: diagnosticsChannel.channel("undici:request:error"),
|
||||
|
@ -2216,7 +2199,7 @@ var require_diagnostics = __commonJS({
|
|||
const {
|
||||
request: { method, path, origin }
|
||||
} = evt;
|
||||
debugLog("sending request to %s %s/%s", method, origin, path);
|
||||
debugLog("sending request to %s %s%s", method, origin, path);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -2235,7 +2218,7 @@ var require_diagnostics = __commonJS({
|
|||
response: { statusCode }
|
||||
} = evt;
|
||||
debugLog(
|
||||
"received response to %s %s/%s - HTTP %d",
|
||||
"received response to %s %s%s - HTTP %d",
|
||||
method,
|
||||
origin,
|
||||
path,
|
||||
|
@ -2249,7 +2232,7 @@ var require_diagnostics = __commonJS({
|
|||
const {
|
||||
request: { method, path, origin }
|
||||
} = evt;
|
||||
debugLog("trailers received from %s %s/%s", method, origin, path);
|
||||
debugLog("trailers received from %s %s%s", method, origin, path);
|
||||
}
|
||||
);
|
||||
diagnosticsChannel.subscribe(
|
||||
|
@ -2260,7 +2243,7 @@ var require_diagnostics = __commonJS({
|
|||
error
|
||||
} = evt;
|
||||
debugLog(
|
||||
"request to %s %s/%s errored - %s",
|
||||
"request to %s %s%s errored - %s",
|
||||
method,
|
||||
origin,
|
||||
path,
|
||||
|
@ -2489,6 +2472,9 @@ var require_request = __commonJS({
|
|||
}
|
||||
}
|
||||
onBodySent(chunk) {
|
||||
if (channels.bodyChunkSent.hasSubscribers) {
|
||||
channels.bodyChunkSent.publish({ request: this, chunk });
|
||||
}
|
||||
if (this[kHandler].onBodySent) {
|
||||
try {
|
||||
return this[kHandler].onBodySent(chunk);
|
||||
|
@ -2537,6 +2523,9 @@ var require_request = __commonJS({
|
|||
onData(chunk) {
|
||||
assert(!this.aborted);
|
||||
assert(!this.completed);
|
||||
if (channels.bodyChunkReceived.hasSubscribers) {
|
||||
channels.bodyChunkReceived.publish({ request: this, chunk });
|
||||
}
|
||||
try {
|
||||
return this[kHandler].onData(chunk);
|
||||
} catch (err) {
|
||||
|
@ -2671,61 +2660,35 @@ var require_connect = __commonJS({
|
|||
var util = require_util();
|
||||
var { InvalidArgumentError } = require_errors();
|
||||
var tls;
|
||||
var SessionCache;
|
||||
if (global.FinalizationRegistry && !(process.env.NODE_V8_COVERAGE || process.env.UNDICI_NO_FG)) {
|
||||
SessionCache = class WeakSessionCache {
|
||||
static {
|
||||
__name(this, "WeakSessionCache");
|
||||
}
|
||||
constructor(maxCachedSessions) {
|
||||
this._maxCachedSessions = maxCachedSessions;
|
||||
this._sessionCache = /* @__PURE__ */ new Map();
|
||||
this._sessionRegistry = new global.FinalizationRegistry((key) => {
|
||||
if (this._sessionCache.size < this._maxCachedSessions) {
|
||||
return;
|
||||
}
|
||||
const ref = this._sessionCache.get(key);
|
||||
if (ref !== void 0 && ref.deref() === void 0) {
|
||||
this._sessionCache.delete(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
get(sessionKey) {
|
||||
const ref = this._sessionCache.get(sessionKey);
|
||||
return ref ? ref.deref() : null;
|
||||
}
|
||||
set(sessionKey, session) {
|
||||
if (this._maxCachedSessions === 0) {
|
||||
var SessionCache = class WeakSessionCache {
|
||||
static {
|
||||
__name(this, "WeakSessionCache");
|
||||
}
|
||||
constructor(maxCachedSessions) {
|
||||
this._maxCachedSessions = maxCachedSessions;
|
||||
this._sessionCache = /* @__PURE__ */ new Map();
|
||||
this._sessionRegistry = new FinalizationRegistry((key) => {
|
||||
if (this._sessionCache.size < this._maxCachedSessions) {
|
||||
return;
|
||||
}
|
||||
this._sessionCache.set(sessionKey, new WeakRef(session));
|
||||
this._sessionRegistry.register(session, sessionKey);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
SessionCache = class SimpleSessionCache {
|
||||
static {
|
||||
__name(this, "SimpleSessionCache");
|
||||
}
|
||||
constructor(maxCachedSessions) {
|
||||
this._maxCachedSessions = maxCachedSessions;
|
||||
this._sessionCache = /* @__PURE__ */ new Map();
|
||||
}
|
||||
get(sessionKey) {
|
||||
return this._sessionCache.get(sessionKey);
|
||||
}
|
||||
set(sessionKey, session) {
|
||||
if (this._maxCachedSessions === 0) {
|
||||
return;
|
||||
const ref = this._sessionCache.get(key);
|
||||
if (ref !== void 0 && ref.deref() === void 0) {
|
||||
this._sessionCache.delete(key);
|
||||
}
|
||||
if (this._sessionCache.size >= this._maxCachedSessions) {
|
||||
const { value: oldestKey } = this._sessionCache.keys().next();
|
||||
this._sessionCache.delete(oldestKey);
|
||||
}
|
||||
this._sessionCache.set(sessionKey, session);
|
||||
});
|
||||
}
|
||||
get(sessionKey) {
|
||||
const ref = this._sessionCache.get(sessionKey);
|
||||
return ref ? ref.deref() : null;
|
||||
}
|
||||
set(sessionKey, session) {
|
||||
if (this._maxCachedSessions === 0) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
this._sessionCache.set(sessionKey, new WeakRef(session));
|
||||
this._sessionRegistry.register(session, sessionKey);
|
||||
}
|
||||
};
|
||||
function buildConnector({ allowH2, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) {
|
||||
if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) {
|
||||
throw new InvalidArgumentError("maxCachedSessions must be a positive integer or zero");
|
||||
|
@ -4072,13 +4035,12 @@ var require_data_url = __commonJS({
|
|||
}
|
||||
});
|
||||
|
||||
// lib/web/fetch/webidl.js
|
||||
// lib/web/webidl/index.js
|
||||
var require_webidl = __commonJS({
|
||||
"lib/web/fetch/webidl.js"(exports2, module2) {
|
||||
"lib/web/webidl/index.js"(exports2, module2) {
|
||||
"use strict";
|
||||
var { types, inspect } = require("node:util");
|
||||
var { markAsUncloneable } = require("node:worker_threads");
|
||||
var { toUSVString } = require_util();
|
||||
var UNDEFINED = 1;
|
||||
var BOOLEAN = 2;
|
||||
var STRING = 3;
|
||||
|
@ -4097,11 +4059,11 @@ var require_webidl = __commonJS({
|
|||
webidl.errors.exception = function(message) {
|
||||
return new TypeError(`${message.header}: ${message.message}`);
|
||||
};
|
||||
webidl.errors.conversionFailed = function(context) {
|
||||
const plural = context.types.length === 1 ? "" : " one of";
|
||||
const message = `${context.argument} could not be converted to${plural}: ${context.types.join(", ")}.`;
|
||||
webidl.errors.conversionFailed = function(opts) {
|
||||
const plural = opts.types.length === 1 ? "" : " one of";
|
||||
const message = `${opts.argument} could not be converted to${plural}: ${opts.types.join(", ")}.`;
|
||||
return webidl.errors.exception({
|
||||
header: context.prefix,
|
||||
header: opts.prefix,
|
||||
message
|
||||
});
|
||||
};
|
||||
|
@ -4272,6 +4234,8 @@ var require_webidl = __commonJS({
|
|||
return inspect(V);
|
||||
case STRING:
|
||||
return `"${V}"`;
|
||||
case BIGINT:
|
||||
return `${V}n`;
|
||||
default:
|
||||
return `${V}`;
|
||||
}
|
||||
|
@ -4391,6 +4355,9 @@ var require_webidl = __commonJS({
|
|||
return converter(V, prefix, argument);
|
||||
};
|
||||
};
|
||||
webidl.is.USVString = function(value) {
|
||||
return typeof value === "string" && value.isWellFormed();
|
||||
};
|
||||
webidl.is.ReadableStream = webidl.util.MakeTypeAssertion(ReadableStream);
|
||||
webidl.is.Blob = webidl.util.MakeTypeAssertion(Blob);
|
||||
webidl.is.URLSearchParams = webidl.util.MakeTypeAssertion(URLSearchParams);
|
||||
|
@ -4427,7 +4394,12 @@ var require_webidl = __commonJS({
|
|||
}
|
||||
return x;
|
||||
};
|
||||
webidl.converters.USVString = toUSVString;
|
||||
webidl.converters.USVString = function(value) {
|
||||
if (typeof value === "string") {
|
||||
return value.toWellFormed();
|
||||
}
|
||||
return `${value}`.toWellFormed();
|
||||
};
|
||||
webidl.converters.boolean = function(V) {
|
||||
const x = Boolean(V);
|
||||
return x;
|
||||
|
@ -5202,7 +5174,7 @@ var require_util2 = __commonJS({
|
|||
return;
|
||||
}
|
||||
if (!isUint8Array(chunk)) {
|
||||
failureSteps(TypeError("Received non-Uint8Array chunk"));
|
||||
failureSteps(new TypeError("Received non-Uint8Array chunk"));
|
||||
return;
|
||||
}
|
||||
bytes.push(chunk);
|
||||
|
@ -5674,7 +5646,7 @@ var require_formdata = __commonJS({
|
|||
var require_formdata_parser = __commonJS({
|
||||
"lib/web/fetch/formdata-parser.js"(exports2, module2) {
|
||||
"use strict";
|
||||
var { isUSVString, bufferToLowerCasedHeaderName } = require_util();
|
||||
var { bufferToLowerCasedHeaderName } = require_util();
|
||||
var { utf8DecodeBytes } = require_util2();
|
||||
var { HTTP_TOKEN_CODEPOINTS, isomorphicDecode } = require_data_url();
|
||||
var { makeEntry } = require_formdata();
|
||||
|
@ -5771,8 +5743,8 @@ var require_formdata_parser = __commonJS({
|
|||
} else {
|
||||
value = utf8DecodeBytes(Buffer.from(body));
|
||||
}
|
||||
assert(isUSVString(name));
|
||||
assert(typeof value === "string" && isUSVString(value) || webidl.is.File(value));
|
||||
assert(webidl.is.USVString(name));
|
||||
assert(typeof value === "string" && webidl.is.USVString(value) || webidl.is.File(value));
|
||||
entryList.push(makeEntry(name, value, filename));
|
||||
}
|
||||
}
|
||||
|
@ -5981,7 +5953,7 @@ var require_body = __commonJS({
|
|||
function noop() {
|
||||
}
|
||||
__name(noop, "noop");
|
||||
var hasFinalizationRegistry = globalThis.FinalizationRegistry && process.version.indexOf("v18") !== 0;
|
||||
var hasFinalizationRegistry = globalThis.FinalizationRegistry;
|
||||
var streamRegistry;
|
||||
if (hasFinalizationRegistry) {
|
||||
streamRegistry = new FinalizationRegistry((weakRef) => {
|
||||
|
@ -6480,7 +6452,7 @@ var require_client_h1 = __commonJS({
|
|||
this.timeout = timers.setFastTimeout(onParserTimeout, delay, new WeakRef(this));
|
||||
} else {
|
||||
this.timeout = setTimeout(onParserTimeout, delay, new WeakRef(this));
|
||||
this.timeout.unref();
|
||||
this.timeout?.unref();
|
||||
}
|
||||
}
|
||||
this.timeoutValue = delay;
|
||||
|
@ -8950,7 +8922,8 @@ var require_proxy_agent = __commonJS({
|
|||
signal: opts2.signal,
|
||||
headers: {
|
||||
...this[kProxyHeaders],
|
||||
host: opts2.host
|
||||
host: opts2.host,
|
||||
...opts2.connections == null || opts2.connections > 0 ? { "proxy-connection": "keep-alive" } : {}
|
||||
},
|
||||
servername: this[kProxyTls]?.servername || proxyHostname
|
||||
});
|
||||
|
@ -10095,45 +10068,7 @@ var require_response = __commonJS({
|
|||
var require_dispatcher_weakref = __commonJS({
|
||||
"lib/web/fetch/dispatcher-weakref.js"(exports2, module2) {
|
||||
"use strict";
|
||||
var { kConnected, kSize } = require_symbols();
|
||||
var CompatWeakRef = class {
|
||||
static {
|
||||
__name(this, "CompatWeakRef");
|
||||
}
|
||||
constructor(value) {
|
||||
this.value = value;
|
||||
}
|
||||
deref() {
|
||||
return this.value[kConnected] === 0 && this.value[kSize] === 0 ? void 0 : this.value;
|
||||
}
|
||||
};
|
||||
var CompatFinalizer = class {
|
||||
static {
|
||||
__name(this, "CompatFinalizer");
|
||||
}
|
||||
constructor(finalizer) {
|
||||
this.finalizer = finalizer;
|
||||
}
|
||||
register(dispatcher, key) {
|
||||
if (dispatcher.on) {
|
||||
dispatcher.on("disconnect", () => {
|
||||
if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) {
|
||||
this.finalizer(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
unregister(key) {
|
||||
}
|
||||
};
|
||||
module2.exports = function() {
|
||||
if (process.env.NODE_V8_COVERAGE && process.version.startsWith("v18")) {
|
||||
process._rawDebug("Using compatibility WeakRef and FinalizationRegistry");
|
||||
return {
|
||||
WeakRef: CompatWeakRef,
|
||||
FinalizationRegistry: CompatFinalizer
|
||||
};
|
||||
}
|
||||
return { WeakRef, FinalizationRegistry };
|
||||
};
|
||||
}
|
||||
|
@ -11903,6 +11838,11 @@ var require_fetch = __commonJS({
|
|||
flush: zlib.constants.BROTLI_OPERATION_FLUSH,
|
||||
finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
|
||||
}));
|
||||
} else if (coding === "zstd" && typeof zlib.createZstdDecompress === "function") {
|
||||
decoders.push(zlib.createZstdDecompress({
|
||||
flush: zlib.constants.ZSTD_e_continue,
|
||||
finishFlush: zlib.constants.ZSTD_e_end
|
||||
}));
|
||||
} else {
|
||||
decoders.length = 0;
|
||||
break;
|
||||
|
@ -12607,7 +12547,9 @@ var require_frame = __commonJS({
|
|||
}
|
||||
};
|
||||
module2.exports = {
|
||||
WebsocketFrameSend
|
||||
WebsocketFrameSend,
|
||||
generateMask
|
||||
// for benchmark
|
||||
};
|
||||
}
|
||||
});
|
||||
|
@ -12664,7 +12606,7 @@ var require_connection = __commonJS({
|
|||
handler.readyState = states.CLOSED;
|
||||
}
|
||||
if (response.type === "error" || response.status !== 101) {
|
||||
failWebsocketConnection(handler, 1002, "Received network error or non-101 status code.");
|
||||
failWebsocketConnection(handler, 1002, "Received network error or non-101 status code.", response.error);
|
||||
return;
|
||||
}
|
||||
if (protocols.length !== 0 && !response.headersList.get("Sec-WebSocket-Protocol")) {
|
||||
|
@ -12753,7 +12695,7 @@ var require_connection = __commonJS({
|
|||
}
|
||||
}
|
||||
__name(closeWebSocketConnection, "closeWebSocketConnection");
|
||||
function failWebsocketConnection(handler, code, reason) {
|
||||
function failWebsocketConnection(handler, code, reason, cause) {
|
||||
if (isEstablished(handler.readyState)) {
|
||||
closeWebSocketConnection(handler, code, reason, false);
|
||||
}
|
||||
|
@ -12761,7 +12703,7 @@ var require_connection = __commonJS({
|
|||
if (handler.socket?.destroyed === false) {
|
||||
handler.socket.destroy();
|
||||
}
|
||||
handler.onFail(code, reason);
|
||||
handler.onFail(code, reason, cause);
|
||||
}
|
||||
__name(failWebsocketConnection, "failWebsocketConnection");
|
||||
module2.exports = {
|
||||
|
@ -13290,7 +13232,7 @@ var require_websocket = __commonJS({
|
|||
/** @type {Handler} */
|
||||
#handler = {
|
||||
onConnectionEstablished: /* @__PURE__ */ __name((response, extensions) => this.#onConnectionEstablished(response, extensions), "onConnectionEstablished"),
|
||||
onFail: /* @__PURE__ */ __name((code, reason) => this.#onFail(code, reason), "onFail"),
|
||||
onFail: /* @__PURE__ */ __name((code, reason, cause) => this.#onFail(code, reason, cause), "onFail"),
|
||||
onMessage: /* @__PURE__ */ __name((opcode, data) => this.#onMessage(opcode, data), "onMessage"),
|
||||
onParserError: /* @__PURE__ */ __name((err) => failWebsocketConnection(this.#handler, null, err.message), "onParserError"),
|
||||
onParserDrain: /* @__PURE__ */ __name(() => this.#onParserDrain(), "onParserDrain"),
|
||||
|
@ -13525,10 +13467,10 @@ var require_websocket = __commonJS({
|
|||
}
|
||||
fireEvent("open", this);
|
||||
}
|
||||
#onFail(code, reason) {
|
||||
#onFail(code, reason, cause) {
|
||||
if (reason) {
|
||||
fireEvent("error", this, (type, init) => new ErrorEvent2(type, init), {
|
||||
error: new Error(reason),
|
||||
error: new Error(reason, cause ? { cause } : void 0),
|
||||
message: reason
|
||||
});
|
||||
}
|
||||
|
@ -13698,7 +13640,7 @@ var require_util4 = __commonJS({
|
|||
__name(isASCIINumber, "isASCIINumber");
|
||||
function delay(ms) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, ms).unref();
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
__name(delay, "delay");
|
||||
|
@ -14074,11 +14016,9 @@ var require_eventsource = __commonJS({
|
|||
dispatcher: this.#dispatcher
|
||||
};
|
||||
const processEventSourceEndOfBody = /* @__PURE__ */ __name((response) => {
|
||||
if (isNetworkError(response)) {
|
||||
this.dispatchEvent(new Event("error"));
|
||||
this.close();
|
||||
if (!isNetworkError(response)) {
|
||||
return this.#reconnect();
|
||||
}
|
||||
this.#reconnect();
|
||||
}, "processEventSourceEndOfBody");
|
||||
fetchParams.processResponseEndOfBody = processEventSourceEndOfBody;
|
||||
fetchParams.processResponse = (response) => {
|
||||
|
@ -14986,7 +14926,7 @@ var require_api_stream = __commonJS({
|
|||
finished(res, { readable: false }, (err) => {
|
||||
const { callback, res: res2, opaque: opaque2, trailers, abort } = this;
|
||||
this.res = null;
|
||||
if (err || !res2.readable) {
|
||||
if (err || !res2?.readable) {
|
||||
util.destroy(res2, err);
|
||||
}
|
||||
this.callback = null;
|
||||
|
|
|
@ -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.10.0"
|
||||
#define UNDICI_VERSION "7.11.0"
|
||||
#endif // SRC_UNDICI_VERSION_H_
|
||||
|
|
|
@ -23,15 +23,16 @@ const { createProxyServer, checkProxiedRequest } = require('../common/proxy-serv
|
|||
const serverHost = `localhost:${server.address().port}`;
|
||||
|
||||
// FIXME(undici:4083): undici currently always tunnels the request over
|
||||
// CONNECT, no matter it's HTTP traffic or not, which is different from e.g.
|
||||
// how curl behaves.
|
||||
// CONNECT if proxyTunnel is not explicitly set to false, but what we
|
||||
// need is for it to be automatically false for HTTP requests to be
|
||||
// consistent with curl.
|
||||
const expectedLogs = [{
|
||||
method: 'CONNECT',
|
||||
url: serverHost,
|
||||
headers: {
|
||||
// FIXME(undici:4086): this should be keep-alive.
|
||||
connection: 'close',
|
||||
host: serverHost
|
||||
'connection': 'close',
|
||||
'host': serverHost,
|
||||
'proxy-connection': 'keep-alive'
|
||||
}
|
||||
}];
|
||||
|
||||
|
|
|
@ -33,9 +33,9 @@ const { createProxyServer, checkProxiedRequest } = require('../common/proxy-serv
|
|||
method: 'CONNECT',
|
||||
url: serverHost,
|
||||
headers: {
|
||||
// FIXME(undici:4086): this should be keep-alive.
|
||||
connection: 'close',
|
||||
host: serverHost
|
||||
'connection': 'close',
|
||||
'host': serverHost,
|
||||
'proxy-connection': 'keep-alive'
|
||||
}
|
||||
}];
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue