| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent a34e445 commit af789d9
34 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -88,3 +88,7 @@ undici-fetch.js | |||
| 88 | 88 | ||
| 89 | 89 | # File generated by /test/request-timeout.js | |
| 90 | 90 | test/request-timeout.10mb.bin | |
| 91 | + | ||
| 92 | + # Claude files | ||
| 93 | + CLAUDE.md | ||
| 94 | + .claude | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -114,8 +114,10 @@ const response = await fetch('https://api.example.com/data'); | |||
| 114 | 114 | #### Use Built-in Fetch When: | |
| 115 | 115 | - You want zero dependencies | |
| 116 | 116 | - Building isomorphic code that runs in browsers and Node.js | |
| 117 | + - Publishing to npm and want to maximize compatibility with JS runtimes | ||
| 117 | 118 | - Simple HTTP requests without advanced configuration | |
| 118 | - - You're okay with the undici version bundled in your Node.js version | ||
| 119 | + - You're publishing to npm and you want to maximize compatiblity | ||
| 120 | + - You don't depend on features from a specific version of undici | ||
| 119 | 121 | ||
| 120 | 122 | #### Use Undici Module When: | |
| 121 | 123 | - You need the latest undici features and performance improvements | |
@@ -209,7 +211,7 @@ The `install()` function adds the following classes to `globalThis`: | |||
| 209 | 211 | - `fetch` - The fetch function | |
| 210 | 212 | - `Headers` - HTTP headers management | |
| 211 | 213 | - `Response` - HTTP response representation | |
| 212 | - - `Request` - HTTP request representation | ||
| 214 | + - `Request` - HTTP request representation | ||
| 213 | 215 | - `FormData` - Form data handling | |
| 214 | 216 | - `WebSocket` - WebSocket client | |
| 215 | 217 | - `CloseEvent`, `ErrorEvent`, `MessageEvent` - WebSocket events | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -169,10 +169,11 @@ This message is published after the client has successfully connected to a serve | |||
| 169 | 169 | ```js | |
| 170 | 170 | import diagnosticsChannel from 'diagnostics_channel' | |
| 171 | 171 | ||
| 172 | - diagnosticsChannel.channel('undici:websocket:open').subscribe(({ address, protocol, extensions }) => { | ||
| 172 | + diagnosticsChannel.channel('undici:websocket:open').subscribe(({ address, protocol, extensions, websocket }) => { | ||
| 173 | 173 | console.log(address) // address, family, and port | |
| 174 | 174 | console.log(protocol) // negotiated subprotocols | |
| 175 | 175 | console.log(extensions) // negotiated extensions | |
| 176 | + console.log(websocket) // the WebSocket instance | ||
| 176 | 177 | }) | |
| 177 | 178 | ``` | |
| 178 | 179 | ||
@@ -184,7 +185,7 @@ This message is published after the connection has closed. | |||
| 184 | 185 | import diagnosticsChannel from 'diagnostics_channel' | |
| 185 | 186 | ||
| 186 | 187 | diagnosticsChannel.channel('undici:websocket:close').subscribe(({ websocket, code, reason }) => { | |
| 187 | - console.log(websocket) // the WebSocket object | ||
| 188 | + console.log(websocket) // the WebSocket instance | ||
| 188 | 189 | console.log(code) // the closing status code | |
| 189 | 190 | console.log(reason) // the closing reason | |
| 190 | 191 | }) | |
@@ -209,9 +210,10 @@ This message is published after the client receives a ping frame, if the connect | |||
| 209 | 210 | ```js | |
| 210 | 211 | import diagnosticsChannel from 'diagnostics_channel' | |
| 211 | 212 | ||
| 212 | - diagnosticsChannel.channel('undici:websocket:ping').subscribe(({ payload }) => { | ||
| 213 | + diagnosticsChannel.channel('undici:websocket:ping').subscribe(({ payload, websocket }) => { | ||
| 213 | 214 | // a Buffer or undefined, containing the optional application data of the frame | |
| 214 | 215 | console.log(payload) | |
| 216 | + console.log(websocket) // the WebSocket instance | ||
| 215 | 217 | }) | |
| 216 | 218 | ``` | |
| 217 | 219 | ||
@@ -222,8 +224,9 @@ This message is published after the client receives a pong frame. | |||
| 222 | 224 | ```js | |
| 223 | 225 | import diagnosticsChannel from 'diagnostics_channel' | |
| 224 | 226 | ||
| 225 | - diagnosticsChannel.channel('undici:websocket:pong').subscribe(({ payload }) => { | ||
| 227 | + diagnosticsChannel.channel('undici:websocket:pong').subscribe(({ payload, websocket }) => { | ||
| 226 | 228 | // a Buffer or undefined, containing the optional application data of the frame | |
| 227 | 229 | console.log(payload) | |
| 230 | + console.log(websocket) // the WebSocket instance | ||
| 228 | 231 | }) | |
| 229 | 232 | ``` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1103,8 +1103,8 @@ The `cache` interceptor implements client-side response caching as described in | |||
| 1103 | 1103 | ||
| 1104 | 1104 | - `store` - The [`CacheStore`](/docs/docs/api/CacheStore.md) to store and retrieve responses from. Default is [`MemoryCacheStore`](/docs/docs/api/CacheStore.md#memorycachestore). | |
| 1105 | 1105 | - `methods` - The [**safe** HTTP methods](https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1) to cache the response of. | |
| 1106 | - - `cacheByDefault` - The default expiration time to cache responses by if they don't have an explicit expiration. If this isn't present, responses without explicit expiration will not be cached. Default `undefined`. | ||
| 1107 | - - `type` - The type of cache for Undici to act as. Can be `shared` or `private`. Default `shared`. | ||
| 1106 | + - `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`. | ||
| 1107 | + - `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. | ||
| 1108 | 1108 | ||
| 1109 | 1109 | ## Instance Events | |
| 1110 | 1110 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -78,6 +78,33 @@ setInterval(() => write(), 5000) | |||
| 78 | 78 | ||
| 79 | 79 | ``` | |
| 80 | 80 | ||
| 81 | + ## ping(websocket, payload) | ||
| 82 | + Arguments: | ||
| 83 | + | ||
| 84 | + * **websocket** `WebSocket` - The WebSocket instance to send the ping frame on | ||
| 85 | + * **payload** `Buffer|undefined` (optional) - Optional payload data to include with the ping frame. Must not exceed 125 bytes. | ||
| 86 | + | ||
| 87 | + Sends a ping frame to the WebSocket server. The server must respond with a pong frame containing the same payload data. This can be used for keepalive purposes or to verify that the connection is still active. | ||
| 88 | + | ||
| 89 | + ### Example: | ||
| 90 | + | ||
| 91 | + ```js | ||
| 92 | + import { WebSocket, ping } from 'undici' | ||
| 93 | + | ||
| 94 | + const ws = new WebSocket('wss://echo.websocket.events') | ||
| 95 | + | ||
| 96 | + ws.addEventListener('open', () => { | ||
| 97 | + // Send ping with no payload | ||
| 98 | + ping(ws) | ||
| 99 | + | ||
| 100 | + // Send ping with payload | ||
| 101 | + const payload = Buffer.from('hello') | ||
| 102 | + ping(ws, payload) | ||
| 103 | + }) | ||
| 104 | + ``` | ||
| 105 | + | ||
| 106 | + **Note**: A ping frame cannot have a payload larger than 125 bytes. The ping will only be sent if the WebSocket connection is in the OPEN state. | ||
| 107 | + | ||
| 81 | 108 | ## Read More | |
| 82 | 109 | ||
| 83 | 110 | - [MDN - WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -157,10 +157,12 @@ module.exports.parseMIMEType = parseMIMEType | |||
| 157 | 157 | module.exports.serializeAMimeType = serializeAMimeType | |
| 158 | 158 | ||
| 159 | 159 | const { CloseEvent, ErrorEvent, MessageEvent } = require('./lib/web/websocket/events') | |
| 160 | - module.exports.WebSocket = require('./lib/web/websocket/websocket').WebSocket | ||
| 160 | + const { WebSocket, ping } = require('./lib/web/websocket/websocket') | ||
| 161 | + module.exports.WebSocket = WebSocket | ||
| 161 | 162 | module.exports.CloseEvent = CloseEvent | |
| 162 | 163 | module.exports.ErrorEvent = ErrorEvent | |
| 163 | 164 | module.exports.MessageEvent = MessageEvent | |
| 165 | + module.exports.ping = ping | ||
| 164 | 166 | ||
| 165 | 167 | module.exports.WebSocketStream = require('./lib/web/websocket/stream/websocketstream').WebSocketStream | |
| 166 | 168 | module.exports.WebSocketError = require('./lib/web/websocket/stream/websocketerror').WebSocketError | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -89,9 +89,7 @@ class BodyReadable extends Readable { | |||
| 89 | 89 | // promise (i.e micro tick) for installing an 'error' listener will | |
| 90 | 90 | // never get a chance and will always encounter an unhandled exception. | |
| 91 | 91 | if (!this[kUsed]) { | |
| 92 | - setImmediate(() => { | ||
| 93 | - callback(err) | ||
| 94 | - }) | ||
| 92 | + setImmediate(callback, err) | ||
| 95 | 93 | } else { | |
| 96 | 94 | callback(err) | |
| 97 | 95 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -42,7 +42,8 @@ class Request { | |||
| 42 | 42 | reset, | |
| 43 | 43 | expectContinue, | |
| 44 | 44 | servername, | |
| 45 | - throwOnError | ||
| 45 | + throwOnError, | ||
| 46 | + maxRedirections | ||
| 46 | 47 | }, handler) { | |
| 47 | 48 | if (typeof path !== 'string') { | |
| 48 | 49 | throw new InvalidArgumentError('path must be a string') | |
@@ -86,6 +87,10 @@ class Request { | |||
| 86 | 87 | throw new InvalidArgumentError('invalid throwOnError') | |
| 87 | 88 | } | |
| 88 | 89 | ||
| 90 | + if (maxRedirections != null && maxRedirections !== 0) { | ||
| 91 | + throw new InvalidArgumentError('maxRedirections is not supported, use the redirect interceptor') | ||
| 92 | + } | ||
| 93 | + | ||
| 89 | 94 | this.headersTimeout = headersTimeout | |
| 90 | 95 | ||
| 91 | 96 | this.bodyTimeout = bodyTimeout | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -86,7 +86,7 @@ class TstNode { | |||
| 86 | 86 | ||
| 87 | 87 | /** | |
| 88 | 88 | * @param {Uint8Array} key | |
| 89 | - * @return {TstNode | null} | ||
| 89 | + * @returns {TstNode | null} | ||
| 90 | 90 | */ | |
| 91 | 91 | search (key) { | |
| 92 | 92 | const keylength = key.length | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -60,23 +60,23 @@ const removeAllListeners = util.removeAllListeners | |||
| 60 | 60 | ||
| 61 | 61 | let extractBody | |
| 62 | 62 | ||
| 63 | - async function lazyllhttp () { | ||
| 63 | + function lazyllhttp () { | ||
| 64 | 64 | const llhttpWasmData = process.env.JEST_WORKER_ID ? require('../llhttp/llhttp-wasm.js') : undefined | |
| 65 | 65 | ||
| 66 | 66 | let mod | |
| 67 | 67 | try { | |
| 68 | - mod = await WebAssembly.compile(require('../llhttp/llhttp_simd-wasm.js')) | ||
| 68 | + mod = new WebAssembly.Module(require('../llhttp/llhttp_simd-wasm.js')) | ||
| 69 | 69 | } catch (e) { | |
| 70 | 70 | /* istanbul ignore next */ | |
| 71 | 71 | ||
| 72 | 72 | // We could check if the error was caused by the simd option not | |
| 73 | 73 | // being enabled, but the occurring of this other error | |
| 74 | 74 | // * https://github.com/emscripten-core/emscripten/issues/11495 | |
| 75 | 75 | // got me to remove that check to avoid breaking Node 12. | |
| 76 | - mod = await WebAssembly.compile(llhttpWasmData || require('../llhttp/llhttp-wasm.js')) | ||
| 76 | + mod = new WebAssembly.Module(llhttpWasmData || require('../llhttp/llhttp-wasm.js')) | ||
| 77 | 77 | } | |
| 78 | 78 | ||
| 79 | - return await WebAssembly.instantiate(mod, { | ||
| 79 | + return new WebAssembly.Instance(mod, { | ||
| 80 | 80 | env: { | |
| 81 | 81 | /** | |
| 82 | 82 | * @param {number} p | |
@@ -165,11 +165,6 @@ async function lazyllhttp () { | |||
| 165 | 165 | } | |
| 166 | 166 | ||
| 167 | 167 | let llhttpInstance = null | |
| 168 | - /** | ||
| 169 | - * @type {Promise<WebAssembly.Instance>|null} | ||
| 170 | - */ | ||
| 171 | - let llhttpPromise = lazyllhttp() | ||
| 172 | - llhttpPromise.catch() | ||
| 173 | 168 | ||
| 174 | 169 | /** | |
| 175 | 170 | * @type {Parser|null} | |
@@ -732,7 +727,7 @@ class Parser { | |||
| 732 | 727 | // We must wait a full event loop cycle to reuse this socket to make sure | |
| 733 | 728 | // that non-spec compliant servers are not closing the connection even if they | |
| 734 | 729 | // said they won't. | |
| 735 | - setImmediate(() => client[kResume]()) | ||
| 730 | + setImmediate(client[kResume]) | ||
| 736 | 731 | } else { | |
| 737 | 732 | client[kResume]() | |
| 738 | 733 | } | |
@@ -769,11 +764,7 @@ async function connectH1 (client, socket) { | |||
| 769 | 764 | client[kSocket] = socket | |
| 770 | 765 | ||
| 771 | 766 | if (!llhttpInstance) { | |
| 772 | - const noop = () => {} | ||
| 773 | - socket.on('error', noop) | ||
| 774 | - llhttpInstance = await llhttpPromise | ||
| 775 | - llhttpPromise = null | ||
| 776 | - socket.off('error', noop) | ||
| 767 | + llhttpInstance = lazyllhttp() | ||
| 777 | 768 | } | |
| 778 | 769 | ||
| 779 | 770 | if (socket.errored) { | |
@@ -1297,9 +1288,9 @@ function writeStream (abort, body, client, request, socket, contentLength, heade | |||
| 1297 | 1288 | .on('error', onFinished) | |
| 1298 | 1289 | ||
| 1299 | 1290 | if (body.errorEmitted ?? body.errored) { | |
| 1300 | - setImmediate(() => onFinished(body.errored)) | ||
| 1291 | + setImmediate(onFinished, body.errored) | ||
| 1301 | 1292 | } else if (body.endEmitted ?? body.readableEnded) { | |
| 1302 | - setImmediate(() => onFinished(null)) | ||
| 1293 | + setImmediate(onFinished, null) | ||
| 1303 | 1294 | } | |
| 1304 | 1295 | ||
| 1305 | 1296 | if (body.closeEmitted ?? body.closed) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments