| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent be63847 commit bfb8ad5
46 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -92,3 +92,9 @@ test/request-timeout.10mb.bin | |||
| 92 | 92 | # Claude files | |
| 93 | 93 | CLAUDE.md | |
| 94 | 94 | .claude | |
| 95 | + | ||
| 96 | + # Ignore .pi | ||
| 97 | + .pi | ||
| 98 | + | ||
| 99 | + # Ignore .githuman | ||
| 100 | + .githuman | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -103,7 +103,7 @@ const response = await fetch('https://api.example.com/data'); | |||
| 103 | 103 | - Superior performance, especially with `undici.request` | |
| 104 | 104 | - HTTP/1.1 pipelining support | |
| 105 | 105 | - Custom interceptors and middleware | |
| 106 | - - Advanced features like `ProxyAgent`, `MockAgent` | ||
| 106 | + - Advanced features like `ProxyAgent`, `Socks5Agent`, `MockAgent` | ||
| 107 | 107 | ||
| 108 | 108 | **Cons:** | |
| 109 | 109 | - Additional dependency to manage | |
@@ -122,7 +122,7 @@ const response = await fetch('https://api.example.com/data'); | |||
| 122 | 122 | #### Use Undici Module When: | |
| 123 | 123 | - You need the latest undici features and performance improvements | |
| 124 | 124 | - You require advanced connection pooling configuration | |
| 125 | - - You need APIs not available in the built-in fetch (`ProxyAgent`, `MockAgent`, etc.) | ||
| 125 | + - You need APIs not available in the built-in fetch (`ProxyAgent`, `Socks5Agent`, `MockAgent`, etc.) | ||
| 126 | 126 | - Performance is critical (use `undici.request` for maximum speed) | |
| 127 | 127 | - You want better error handling and debugging capabilities | |
| 128 | 128 | - You need HTTP/1.1 pipelining or advanced interceptors | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -207,7 +207,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo | |||
| 207 | 207 | ||
| 208 | 208 | * **onRequestStart** `(controller: DispatchController, context: object) => void` - Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails. | |
| 209 | 209 | * **onRequestUpgrade** `(controller: DispatchController, statusCode: number, headers: Record<string, string | string[]>, socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`. | |
| 210 | - * **onResponseStart** `(controller: DispatchController, statusCode: number, headers: Record<string, string | string []>, statusMessage?: string) => void` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests. | ||
| 210 | + * **onResponseStart** `(controller: DispatchController, statusCode: number, headers: Record<string, string | string []>, statusMessage?: string) => void` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests. Any return value is ignored. | ||
| 211 | 211 | * **onResponseData** `(controller: DispatchController, chunk: Buffer) => void` - Invoked when response payload data is received. Not required for `upgrade` requests. | |
| 212 | 212 | * **onResponseEnd** `(controller: DispatchController, trailers: Record<string, string | string[]>) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests. | |
| 213 | 213 | * **onResponseError** `(controller: DispatchController, error: Error) => void` - Invoked when an error has occurred. May not throw. | |
@@ -962,7 +962,7 @@ It accepts the same arguments as the [`RedirectHandler` constructor](/docs/docs/ | |||
| 962 | 962 | const { Client, interceptors } = require("undici"); | |
| 963 | 963 | const { redirect } = interceptors; | |
| 964 | 964 | ||
| 965 | - const client = new Client("http://example.com").compose( | ||
| 965 | + const client = new Client("http://service.example").compose( | ||
| 966 | 966 | redirect({ maxRedirections: 3, throwOnMaxRedirects: true }) | |
| 967 | 967 | ); | |
| 968 | 968 | client.request({ path: "/" }) | |
@@ -980,7 +980,7 @@ It accepts the same arguments as the [`RetryHandler` constructor](/docs/docs/api | |||
| 980 | 980 | const { Client, interceptors } = require("undici"); | |
| 981 | 981 | const { retry } = interceptors; | |
| 982 | 982 | ||
| 983 | - const client = new Client("http://example.com").compose( | ||
| 983 | + const client = new Client("http://service.example").compose( | ||
| 984 | 984 | retry({ | |
| 985 | 985 | maxRetries: 3, | |
| 986 | 986 | minTimeout: 1000, | |
@@ -1006,7 +1006,7 @@ The `dump` interceptor enables you to dump the response body from a request upon | |||
| 1006 | 1006 | const { Client, interceptors } = require("undici"); | |
| 1007 | 1007 | const { dump } = interceptors; | |
| 1008 | 1008 | ||
| 1009 | - const client = new Client("http://example.com").compose( | ||
| 1009 | + const client = new Client("http://service.example").compose( | ||
| 1010 | 1010 | dump({ | |
| 1011 | 1011 | maxSize: 1024, | |
| 1012 | 1012 | }) | |
@@ -1132,7 +1132,7 @@ The `responseError` interceptor throws an error for responses with status code e | |||
| 1132 | 1132 | const { Client, interceptors } = require("undici"); | |
| 1133 | 1133 | const { responseError } = interceptors; | |
| 1134 | 1134 | ||
| 1135 | - const client = new Client("http://example.com").compose( | ||
| 1135 | + const client = new Client("http://service.example").compose( | ||
| 1136 | 1136 | responseError() | |
| 1137 | 1137 | ); | |
| 1138 | 1138 | ||
@@ -1160,7 +1160,7 @@ The `decompress` interceptor automatically decompresses response bodies that are | |||
| 1160 | 1160 | const { Client, interceptors } = require("undici"); | |
| 1161 | 1161 | const { decompress } = interceptors; | |
| 1162 | 1162 | ||
| 1163 | - const client = new Client("http://example.com").compose( | ||
| 1163 | + const client = new Client("http://service.example").compose( | ||
| 1164 | 1164 | decompress() | |
| 1165 | 1165 | ); | |
| 1166 | 1166 | ||
@@ -1177,7 +1177,7 @@ const response = await client.request({ | |||
| 1177 | 1177 | const { Client, interceptors } = require("undici"); | |
| 1178 | 1178 | const { decompress } = interceptors; | |
| 1179 | 1179 | ||
| 1180 | - const client = new Client("http://example.com").compose( | ||
| 1180 | + const client = new Client("http://service.example").compose( | ||
| 1181 | 1181 | decompress({ | |
| 1182 | 1182 | skipErrorResponses: false, // Decompress 5xx responses | |
| 1183 | 1183 | skipStatusCodes: [204, 304, 201] // Skip these status codes | |
@@ -1214,6 +1214,28 @@ The `cache` interceptor implements client-side response caching as described in | |||
| 1214 | 1214 | - `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`. | |
| 1215 | 1215 | - `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. | |
| 1216 | 1216 | ||
| 1217 | + **Usage with `fetch`** | ||
| 1218 | + | ||
| 1219 | + ```js | ||
| 1220 | + const { Agent, cacheStores, interceptors, setGlobalDispatcher } = require('undici') | ||
| 1221 | + | ||
| 1222 | + const client = new Agent().compose(interceptors.cache({ | ||
| 1223 | + store: new cacheStores.MemoryCacheStore({ | ||
| 1224 | + maxSize: 100 * 1024 * 1024, // 100MB | ||
| 1225 | + maxCount: 1000, | ||
| 1226 | + maxEntrySize: 5 * 1024 * 1024 // 5MB | ||
| 1227 | + }) | ||
| 1228 | + })) | ||
| 1229 | + | ||
| 1230 | + setGlobalDispatcher(client) | ||
| 1231 | + | ||
| 1232 | + // First request goes to the network and is cached when cache headers allow it. | ||
| 1233 | + const first = await fetch('https://example.com/data') | ||
| 1234 | + | ||
| 1235 | + // Second request can be served from cache according to RFC9111 rules. | ||
| 1236 | + const second = await fetch('https://example.com/data') | ||
| 1237 | + ``` | ||
| 1238 | + | ||
| 1217 | 1239 | ##### `Deduplicate Interceptor` | |
| 1218 | 1240 | ||
| 1219 | 1241 | 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. | |
@@ -1223,6 +1245,7 @@ The `deduplicate` interceptor deduplicates concurrent identical requests. When m | |||
| 1223 | 1245 | - `methods` - The [**safe** HTTP methods](https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1) to deduplicate. Default `['GET']`. | |
| 1224 | 1246 | - `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 `[]`. | |
| 1225 | 1247 | - `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 `[]`. | |
| 1248 | + - `maxBufferSize` - Maximum bytes buffered per paused waiting deduplicated handler. If a waiting handler remains paused and exceeds this threshold, it is failed with an abort error to prevent unbounded memory growth. Default `5 * 1024 * 1024`. | ||
| 1226 | 1249 | ||
| 1227 | 1250 | **Usage** | |
| 1228 | 1251 | ||
@@ -1231,12 +1254,12 @@ const { Client, interceptors } = require("undici"); | |||
| 1231 | 1254 | const { deduplicate, cache } = interceptors; | |
| 1232 | 1255 | ||
| 1233 | 1256 | // Deduplicate only | |
| 1234 | - const client = new Client("http://example.com").compose( | ||
| 1257 | + const client = new Client("http://service.example").compose( | ||
| 1235 | 1258 | deduplicate() | |
| 1236 | 1259 | ); | |
| 1237 | 1260 | ||
| 1238 | 1261 | // Deduplicate with caching | |
| 1239 | - const clientWithCache = new Client("http://example.com").compose( | ||
| 1262 | + const clientWithCache = new Client("http://service.example").compose( | ||
| 1240 | 1263 | deduplicate(), | |
| 1241 | 1264 | cache() | |
| 1242 | 1265 | ); | |
@@ -1304,6 +1327,10 @@ Header arguments such as `options.headers` in [`Client.dispatch`](/docs/docs/api | |||
| 1304 | 1327 | * As an iterable that can encompass `Headers`, `Map`, or a custom iterator returning key-value pairs. | |
| 1305 | 1328 | Keys are lowercase and values are not modified. | |
| 1306 | 1329 | ||
| 1330 | + Undici validates header syntax at the protocol level (for example, invalid header names and invalid control characters in string values), but it does not sanitize untrusted application input. Validate and sanitize any user-provided header names and values before passing them to Undici to prevent header/body injection vulnerabilities. | ||
| 1331 | + | ||
| 1332 | + When using the array header format (`string[]`), Undici processes only indexed elements. Additional properties assigned to the array object are ignored. | ||
| 1333 | + | ||
| 1307 | 1334 | Response headers will derive a `host` from the `url` of the [Client](/docs/docs/api/Client.md#class-client) instance if no `host` header was previously specified. | |
| 1308 | 1335 | ||
| 1309 | 1336 | ### Example 1 - Object | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,6 +26,7 @@ import { errors } from 'undici' | |||
| 26 | 26 | | `InformationalError` | `UND_ERR_INFO` | expected error with reason | | |
| 27 | 27 | | `ResponseExceededMaxSizeError` | `UND_ERR_RES_EXCEEDED_MAX_SIZE` | response body exceed the max size allowed | | |
| 28 | 28 | | `SecureProxyConnectionError` | `UND_ERR_PRX_TLS` | tls connection to a proxy failed | | |
| 29 | + | `MessageSizeExceededError` | `UND_ERR_WS_MESSAGE_SIZE_EXCEEDED` | WebSocket decompressed message exceeded the maximum allowed size | | ||
| 29 | 30 | ||
| 30 | 31 | Be aware of the possible difference between the global dispatcher version and the actual undici version you might be using. We recommend to avoid the check `instanceof errors.UndiciError` and seek for the `error.code === '<error_code>'` instead to avoid inconsistencies. | |
| 31 | 32 | ### `SocketError` | |
| Back | FazBrowse Home | New Git URL |
0 commit comments