You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR-URL: #61283
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
The [Fetch Standard](https://fetch.spec.whatwg.org) requires implementations to exclude certain headers from requests and responses. In browser environments, some headers are forbidden so the user agent remains in full control over them. In Undici, these constraints are removed to give more control to the user.
Undici limits the number of `Content-Encoding` layers in a response to **5** to prevent resource exhaustion attacks. If a server responds with more than 5 content-encodings (e.g., `Content-Encoding: gzip, gzip, gzip, gzip, gzip, gzip`), the fetch will be rejected with an error. This limit matches the approach taken by [curl](https://curl.se/docs/CVE-2022-32206.html) and [urllib3](https://github.com/advisories/GHSA-gm62-xv2j-4rw9).
541
+
490
542
#### `undici.upgrade([url, options]): Promise`
491
543
492
544
Upgrade to a different protocol. See [MDN - HTTP - Protocol upgrade mechanism](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) for more details.
Copy file name to clipboardExpand all lines: deps/undici/src/docs/docs/api/Client.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,10 +26,11 @@ Returns: `Client`
26
26
***maxResponseSize**`number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable.
27
27
***pipelining**`number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections.
28
28
***connect**`ConnectOptions | Function | null` (optional) - Default: `null`.
29
-
***strictContentLength**`Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.
29
+
***strictContentLength**`Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.**Security Warning:** Disabling this option can expose your application to HTTP Request Smuggling attacks, where mismatched content-length headers cause servers and proxies to interpret request boundaries differently. This can lead to cache poisoning, credential hijacking, and bypassing security controls. Only disable this in controlled environments where you fully trust the request source.
30
30
***autoSelectFamily**: `boolean` (optional) - Default: depends on local Node version, on Node 18.13.0 and above is `false`. Enables a family autodetection algorithm that loosely implements section 5 of [RFC 8305](https://tools.ietf.org/html/rfc8305#section-5). See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. This option is ignored if not supported by the current Node version.
31
31
***autoSelectFamilyAttemptTimeout**: `number` - Default: depends on local Node version, on Node 18.13.0 and above is `250`. The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details.
32
32
***allowH2**: `boolean` - Default: `false`. Enables support for H2 if the server has assigned bigger priority to it through ALPN negotiation.
33
+
***useH2c**: `boolean` - Default: `false`. Enforces h2c for non-https connections.
33
34
***maxConcurrentStreams**: `number` - Default: `100`. Dictates the maximum number of concurrent streams for a single H2 session. It can be overridden by a SETTINGS remote frame.
This message is published when the deduplicate interceptor's pending request map changes. This is useful for monitoring and debugging request deduplication behavior.
275
+
276
+
The deduplicate interceptor automatically deduplicates concurrent requests for the same resource. When multiple identical requests are made while one is already in-flight, only one request is sent to the origin server, and all waiting handlers receive the same response.
console.log(size) // current number of pending requests
284
+
console.log(key) // the deduplication key for this request
285
+
})
286
+
```
287
+
288
+
### Event Properties
289
+
290
+
-`type` (`string`): Either `'added'` when a new pending request is registered, or `'removed'` when a pending request completes (successfully or with an error).
291
+
-`size` (`number`): The current number of pending requests after the change.
292
+
-`key` (`string`): The deduplication key for the request, composed of the origin, method, path, and request headers.
Copy file name to clipboardExpand all lines: deps/undici/src/docs/docs/api/Dispatcher.md
+86Lines changed: 86 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1043,6 +1043,7 @@ The `dns` interceptor enables you to cache DNS lookups for a given duration, per
1043
1043
- The function should return a single record from the records array.
1044
1044
- By default a simplified version of Round Robin is used.
1045
1045
- The `records` property can be mutated to store the state of the balancing algorithm.
1046
+
-`storage: DNSStorage` - Custom storage for resolved DNS records
1046
1047
1047
1048
> The `Dispatcher#options` also gets extended with the options `dns.affinity`, `dns.dualStack`, `dns.lookup` and `dns.pick` which can be used to configure the interceptor at a request-per-request basis.
1048
1049
@@ -1057,6 +1058,14 @@ It represents a map of DNS IP addresses records for a single origin.
1057
1058
-`4.ips` - (`DNSInterceptorRecord[] | null`) The IPv4 addresses.
1058
1059
-`6.ips` - (`DNSInterceptorRecord[] | null`) The IPv6 addresses.
1059
1060
1061
+
**DNSStorage**
1062
+
It represents a storage object for resolved DNS records.
1063
+
-`size` - (`number`) current size of the storage.
1064
+
-`get` - (`(origin: string) => DNSInterceptorOriginRecords | null`) method to get the records for a given origin.
1065
+
-`set` - (`(origin: string, records: DNSInterceptorOriginRecords | null, options: { ttl: number }) => void`) method to set the records for a given origin.
1066
+
-`delete` - (`(origin: string) => void`) method to delete records for a given origin.
1067
+
-`full` - (`() => boolean`) method to check if the storage is full, if returns `true`, DNS lookup will be skipped in this interceptor and new records will not be stored.
// For LRU cache, we can always store new records,
1109
+
// old records will be evicted automatically
1110
+
returnfalse;
1111
+
}
1112
+
}
1113
+
1114
+
constclient=newAgent().compose([
1115
+
dns({ storage: lruAdapter })
1116
+
])
1117
+
1118
+
constresponse=awaitclient.request({
1119
+
origin:`http://localhost:3030`,
1120
+
...requestOpts
1121
+
})
1122
+
```
1123
+
1076
1124
##### `responseError`
1077
1125
1078
1126
The `responseError` interceptor throws an error for responses with status code errors (>= 400).
@@ -1165,6 +1213,44 @@ The `cache` interceptor implements client-side response caching as described in
1165
1213
-`cacheByDefault` - The default expiration time to cache responses by if they don't have an explicit expiration and cannot have an heuristic expiry computed. If this isn't present, responses neither with an explicit expiration nor heuristically cacheable will not be cached. Default `undefined`.
1166
1214
-`type` - The [type of cache](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching#types_of_caches) for Undici to act as. Can be `shared` or `private`. Default `shared`. `private` implies privately cacheable responses will be cached and potentially shared with other users of your application.
1167
1215
1216
+
##### `Deduplicate Interceptor`
1217
+
1218
+
The `deduplicate` interceptor deduplicates concurrent identical requests. When multiple identical requests are made while one is already in-flight, only one request is sent to the origin server, and all waiting handlers receive the same response. This reduces server load and improves performance.
1219
+
1220
+
**Options**
1221
+
1222
+
-`methods` - The [**safe** HTTP methods](https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1) to deduplicate. Default `['GET']`.
1223
+
-`skipHeaderNames` - Header names that, if present in a request, will cause the request to skip deduplication entirely. Useful for headers like `idempotency-key` where presence indicates unique processing. Header name matching is case-insensitive. Default `[]`.
1224
+
-`excludeHeaderNames` - Header names to exclude from the deduplication key. Requests with different values for these headers will still be deduplicated together. Useful for headers like `x-request-id` that vary per request but shouldn't affect deduplication. Header name matching is case-insensitive. Default `[]`.
Requests are considered identical if they have the same:
1245
+
- Origin
1246
+
- HTTP method
1247
+
- Path
1248
+
- Request headers (excluding any headers specified in `excludeHeaderNames`)
1249
+
1250
+
All deduplicated requests receive the complete response including status code, headers, and body.
1251
+
1252
+
For observability, request deduplication events are published to the `undici:request:pending-requests`[diagnostic channel](/docs/docs/api/DiagnosticsChannel.md#undicirequestpending-requests).
Copy file name to clipboardExpand all lines: deps/undici/src/docs/docs/api/H2CClient.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,7 +49,7 @@ Returns: `H2CClient`
49
49
-**maxConcurrentStreams**: `number` - Default: `100`. Dictates the maximum number of concurrent streams for a single H2 session. It can be overridden by a SETTINGS remote frame.
50
50
-**pipelining**`number | null` (optional) - Default to `maxConcurrentStreams` - The amount of concurrent requests sent over a single HTTP/2 session in accordance with [RFC-7540](https://httpwg.org/specs/rfc7540.html#StreamsLayer) Stream specification. Streams can be closed up by remote server at any time.
-**strictContentLength**`Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.
52
+
-**strictContentLength**`Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.**Security Warning:** Disabling this option can expose your application to HTTP Request Smuggling attacks, where mismatched content-length headers cause servers and proxies to interpret request boundaries differently. This can lead to cache poisoning, credential hijacking, and bypassing security controls. Only disable this in controlled environments where you fully trust the request source.
53
53
-**autoSelectFamily**: `boolean` (optional) - Default: depends on local Node version, on Node 18.13.0 and above is `false`. Enables a family autodetection algorithm that loosely implements section 5 of [RFC 8305](https://tools.ietf.org/html/rfc8305#section-5). See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. This option is ignored if not supported by the current Node version.
54
54
-**autoSelectFamilyAttemptTimeout**: `number` - Default: depends on local Node version, on Node 18.13.0 and above is `250`. The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details.
0 commit comments