| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f130a33 commit 4ebb944
84 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,34 +18,23 @@ npm i undici | |||
| 18 | 18 | ## Benchmarks | |
| 19 | 19 | ||
| 20 | 20 | The benchmark is a simple `hello world` [example](benchmarks/benchmark.js) using a | |
| 21 | - number of unix sockets (connections) with a pipelining depth of 10 running on Node 20.6.0. | ||
| 22 | - | ||
| 23 | - ### Connections 1 | ||
| 24 | - | ||
| 25 | - | ||
| 26 | - | Tests | Samples | Result | Tolerance | Difference with slowest | | ||
| 27 | - |---------------------|---------|---------------|-----------|-------------------------| | ||
| 28 | - | http - no keepalive | 15 | 5.32 req/sec | ± 2.61 % | - | | ||
| 29 | - | http - keepalive | 10 | 5.35 req/sec | ± 2.47 % | + 0.44 % | | ||
| 30 | - | undici - fetch | 15 | 41.85 req/sec | ± 2.49 % | + 686.04 % | | ||
| 31 | - | undici - pipeline | 40 | 50.36 req/sec | ± 2.77 % | + 845.92 % | | ||
| 32 | - | undici - stream | 15 | 60.58 req/sec | ± 2.75 % | + 1037.72 % | | ||
| 33 | - | undici - request | 10 | 61.19 req/sec | ± 2.60 % | + 1049.24 % | | ||
| 34 | - | undici - dispatch | 20 | 64.84 req/sec | ± 2.81 % | + 1117.81 % | | ||
| 35 | - | ||
| 36 | - | ||
| 37 | - ### Connections 50 | ||
| 38 | - | ||
| 39 | - | Tests | Samples | Result | Tolerance | Difference with slowest | | ||
| 40 | - |---------------------|---------|------------------|-----------|-------------------------| | ||
| 41 | - | undici - fetch | 30 | 2107.19 req/sec | ± 2.69 % | - | | ||
| 42 | - | http - no keepalive | 10 | 2698.90 req/sec | ± 2.68 % | + 28.08 % | | ||
| 43 | - | http - keepalive | 10 | 4639.49 req/sec | ± 2.55 % | + 120.17 % | | ||
| 44 | - | undici - pipeline | 40 | 6123.33 req/sec | ± 2.97 % | + 190.59 % | | ||
| 45 | - | undici - stream | 50 | 9426.51 req/sec | ± 2.92 % | + 347.35 % | | ||
| 46 | - | undici - request | 10 | 10162.88 req/sec | ± 2.13 % | + 382.29 % | | ||
| 47 | - | undici - dispatch | 50 | 11191.11 req/sec | ± 2.98 % | + 431.09 % | | ||
| 21 | + 50 TCP connections with a pipelining depth of 10 running on Node 20.10.0. | ||
| 48 | 22 | ||
| 23 | + ``` | ||
| 24 | + │ Tests │ Samples │ Result │ Tolerance │ Difference with slowest │ | ||
| 25 | + |─────────────────────|─────────|─────────────────|───────────|─────────────────────────| | ||
| 26 | + │ got │ 45 │ 1661.71 req/sec │ ± 2.93 % │ - │ | ||
| 27 | + │ node-fetch │ 20 │ 2164.81 req/sec │ ± 2.63 % │ + 30.28 % │ | ||
| 28 | + │ undici - fetch │ 35 │ 2274.27 req/sec │ ± 2.70 % │ + 36.86 % │ | ||
| 29 | + │ http - no keepalive │ 15 │ 2376.04 req/sec │ ± 2.99 % │ + 42.99 % │ | ||
| 30 | + │ axios │ 25 │ 2612.93 req/sec │ ± 2.89 % │ + 57.24 % │ | ||
| 31 | + │ request │ 40 │ 2712.19 req/sec │ ± 2.92 % │ + 63.22 % │ | ||
| 32 | + │ http - keepalive │ 45 │ 4393.25 req/sec │ ± 2.86 % │ + 164.38 % │ | ||
| 33 | + │ undici - pipeline │ 45 │ 5484.69 req/sec │ ± 2.87 % │ + 230.06 % │ | ||
| 34 | + │ undici - request │ 55 │ 7773.98 req/sec │ ± 2.93 % │ + 367.83 % │ | ||
| 35 | + │ undici - stream │ 70 │ 8425.96 req/sec │ ± 2.91 % │ + 407.07 % │ | ||
| 36 | + │ undici - dispatch │ 50 │ 9488.99 req/sec │ ± 2.85 % │ + 471.04 % │ | ||
| 37 | + ``` | ||
| 49 | 38 | ||
| 50 | 39 | ## Quick Start | |
| 51 | 40 | ||
@@ -62,9 +51,7 @@ const { | |||
| 62 | 51 | console.log('response received', statusCode) | |
| 63 | 52 | console.log('headers', headers) | |
| 64 | 53 | ||
| 65 | - for await (const data of body) { | ||
| 66 | - console.log('data', data) | ||
| 67 | - } | ||
| 54 | + for await (const data of body) { console.log('data', data) } | ||
| 68 | 55 | ||
| 69 | 56 | console.log('trailers', trailers) | |
| 70 | 57 | ``` | |
@@ -119,7 +106,7 @@ Returns a promise with the result of the `Dispatcher.request` method. | |||
| 119 | 106 | ||
| 120 | 107 | Calls `options.dispatcher.request(options)`. | |
| 121 | 108 | ||
| 122 | - See [Dispatcher.request](./docs/api/Dispatcher.md#dispatcherrequestoptions-callback) for more details. | ||
| 109 | + See [Dispatcher.request](./docs/api/Dispatcher.md#dispatcherrequestoptions-callback) for more details, and [request examples](./examples/README.md) for examples. | ||
| 123 | 110 | ||
| 124 | 111 | ### `undici.stream([url, options, ]factory): Promise` | |
| 125 | 112 | ||
@@ -180,8 +167,6 @@ Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method). | |||
| 180 | 167 | * https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch | |
| 181 | 168 | * https://fetch.spec.whatwg.org/#fetch-method | |
| 182 | 169 | ||
| 183 | - Only supported on Node 16.8+. | ||
| 184 | - | ||
| 185 | 170 | Basic usage example: | |
| 186 | 171 | ||
| 187 | 172 | ```js | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -50,7 +50,7 @@ Arguments: | |||
| 50 | 50 | ||
| 51 | 51 | ### `BalancedPool.removeUpstream(upstream)` | |
| 52 | 52 | ||
| 53 | - Removes an upstream that was previously addded. | ||
| 53 | + Removes an upstream that was previously added. | ||
| 54 | 54 | ||
| 55 | 55 | ### `BalancedPool.close([callback])` | |
| 56 | 56 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,62 @@ | |||
| 1 | + # Debug | ||
| 2 | + | ||
| 3 | + Undici (and subsenquently `fetch` and `websocket`) exposes a debug statement that can be enabled by setting `NODE_DEBUG` within the environment. | ||
| 4 | + | ||
| 5 | + The flags availabile are: | ||
| 6 | + | ||
| 7 | + ## `undici` | ||
| 8 | + | ||
| 9 | + This flag enables debug statements for the core undici library. | ||
| 10 | + | ||
| 11 | + ```sh | ||
| 12 | + NODE_DEBUG=undici node script.js | ||
| 13 | + | ||
| 14 | + UNDICI 16241: connecting to nodejs.org using https:h1 | ||
| 15 | + UNDICI 16241: connecting to nodejs.org using https:h1 | ||
| 16 | + UNDICI 16241: connected to nodejs.org using https:h1 | ||
| 17 | + UNDICI 16241: sending request to GET https://nodejs.org// | ||
| 18 | + UNDICI 16241: received response to GET https://nodejs.org// - HTTP 307 | ||
| 19 | + UNDICI 16241: connecting to nodejs.org using https:h1 | ||
| 20 | + UNDICI 16241: trailers received from GET https://nodejs.org// | ||
| 21 | + UNDICI 16241: connected to nodejs.org using https:h1 | ||
| 22 | + UNDICI 16241: sending request to GET https://nodejs.org//en | ||
| 23 | + UNDICI 16241: received response to GET https://nodejs.org//en - HTTP 200 | ||
| 24 | + UNDICI 16241: trailers received from GET https://nodejs.org//en | ||
| 25 | + ``` | ||
| 26 | + | ||
| 27 | + ## `fetch` | ||
| 28 | + | ||
| 29 | + This flag enables debug statements for the `fetch` API. | ||
| 30 | + | ||
| 31 | + > **Note**: statements are pretty similar to the ones in the `undici` flag, but scoped to `fetch` | ||
| 32 | + | ||
| 33 | + ```sh | ||
| 34 | + NODE_DEBUG=fetch node script.js | ||
| 35 | + | ||
| 36 | + FETCH 16241: connecting to nodejs.org using https:h1 | ||
| 37 | + FETCH 16241: connecting to nodejs.org using https:h1 | ||
| 38 | + FETCH 16241: connected to nodejs.org using https:h1 | ||
| 39 | + FETCH 16241: sending request to GET https://nodejs.org// | ||
| 40 | + FETCH 16241: received response to GET https://nodejs.org// - HTTP 307 | ||
| 41 | + FETCH 16241: connecting to nodejs.org using https:h1 | ||
| 42 | + FETCH 16241: trailers received from GET https://nodejs.org// | ||
| 43 | + FETCH 16241: connected to nodejs.org using https:h1 | ||
| 44 | + FETCH 16241: sending request to GET https://nodejs.org//en | ||
| 45 | + FETCH 16241: received response to GET https://nodejs.org//en - HTTP 200 | ||
| 46 | + FETCH 16241: trailers received from GET https://nodejs.org//en | ||
| 47 | + ``` | ||
| 48 | + | ||
| 49 | + ## `websocket` | ||
| 50 | + | ||
| 51 | + This flag enables debug statements for the `Websocket` API. | ||
| 52 | + | ||
| 53 | + > **Note**: statements can overlap with `UNDICI` ones if `undici` or `fetch` flag has been enabled as well. | ||
| 54 | + | ||
| 55 | + ```sh | ||
| 56 | + NODE_DEBUG=websocket node script.js | ||
| 57 | + | ||
| 58 | + WEBSOCKET 18309: connecting to echo.websocket.org using https:h1 | ||
| 59 | + WEBSOCKET 18309: connected to echo.websocket.org using https:h1 | ||
| 60 | + WEBSOCKET 18309: sending request to GET https://echo.websocket.org// | ||
| 61 | + WEBSOCKET 18309: connection opened <ip_address> | ||
| 62 | + ``` | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -105,7 +105,7 @@ You can not assume that this event is related to any specific request. | |||
| 105 | 105 | import diagnosticsChannel from 'diagnostics_channel' | |
| 106 | 106 | ||
| 107 | 107 | diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(({ connectParams, connector }) => { | |
| 108 | - // const { host, hostname, protocol, port, servername } = connectParams | ||
| 108 | + // const { host, hostname, protocol, port, servername, version } = connectParams | ||
| 109 | 109 | // connector is a function that creates the socket | |
| 110 | 110 | }) | |
| 111 | 111 | ``` | |
@@ -118,7 +118,7 @@ This message is published after a connection is established. | |||
| 118 | 118 | import diagnosticsChannel from 'diagnostics_channel' | |
| 119 | 119 | ||
| 120 | 120 | diagnosticsChannel.channel('undici:client:connected').subscribe(({ socket, connectParams, connector }) => { | |
| 121 | - // const { host, hostname, protocol, port, servername } = connectParams | ||
| 121 | + // const { host, hostname, protocol, port, servername, version } = connectParams | ||
| 122 | 122 | // connector is a function that creates the socket | |
| 123 | 123 | }) | |
| 124 | 124 | ``` | |
@@ -131,7 +131,7 @@ This message is published if it did not succeed to create new connection | |||
| 131 | 131 | import diagnosticsChannel from 'diagnostics_channel' | |
| 132 | 132 | ||
| 133 | 133 | diagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, socket, connectParams, connector }) => { | |
| 134 | - // const { host, hostname, protocol, port, servername } = connectParams | ||
| 134 | + // const { host, hostname, protocol, port, servername, version } = connectParams | ||
| 135 | 135 | // connector is a function that creates the socket | |
| 136 | 136 | console.log(`Connect failed with ${error.message}`) | |
| 137 | 137 | }) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -209,6 +209,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo | |||
| 209 | 209 | * **onConnect** `(abort: () => void, 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. | |
| 210 | 210 | * **onError** `(error: Error) => void` - Invoked when an error has occurred. May not throw. | |
| 211 | 211 | * **onUpgrade** `(statusCode: number, headers: Buffer[], socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`. | |
| 212 | + * **onResponseStarted** `() => void` (optional) - Invoked when response is received, before headers have been read. | ||
| 212 | 213 | * **onHeaders** `(statusCode: number, headers: Buffer[], resume: () => void, statusText: string) => boolean` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests. | |
| 213 | 214 | * **onData** `(chunk: Buffer) => boolean` - Invoked when response payload data is received. Not required for `upgrade` requests. | |
| 214 | 215 | * **onComplete** `(trailers: Buffer[]) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,21 @@ | |||
| 1 | + # EventSource | ||
| 2 | + | ||
| 3 | + Undici exposes a WHATWG spec-compliant implementation of [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) | ||
| 4 | + for [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events). | ||
| 5 | + | ||
| 6 | + ## Instantiating EventSource | ||
| 7 | + | ||
| 8 | + Undici exports a EventSource class. You can instantiate the EventSource as | ||
| 9 | + follows: | ||
| 10 | + | ||
| 11 | + ```mjs | ||
| 12 | + import { EventSource } from 'undici' | ||
| 13 | + | ||
| 14 | + const evenSource = new EventSource('http://localhost:3000') | ||
| 15 | + evenSource.onmessage = (event) => { | ||
| 16 | + console.log(event.data) | ||
| 17 | + } | ||
| 18 | + ``` | ||
| 19 | + | ||
| 20 | + More information about the EventSource API can be found on | ||
| 21 | + [MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventSource). | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,96 @@ | |||
| 1 | + # Class: RedirectHandler | ||
| 2 | + | ||
| 3 | + A class that handles redirection logic for HTTP requests. | ||
| 4 | + | ||
| 5 | + ## `new RedirectHandler(dispatch, maxRedirections, opts, handler, redirectionLimitReached)` | ||
| 6 | + | ||
| 7 | + Arguments: | ||
| 8 | + | ||
| 9 | + - **dispatch** `function` - The dispatch function to be called after every retry. | ||
| 10 | + - **maxRedirections** `number` - Maximum number of redirections allowed. | ||
| 11 | + - **opts** `object` - Options for handling redirection. | ||
| 12 | + - **handler** `object` - An object containing handlers for different stages of the request lifecycle. | ||
| 13 | + - **redirectionLimitReached** `boolean` (default: `false`) - A flag that the implementer can provide to enable or disable the feature. If set to `false`, it indicates that the caller doesn't want to use the feature and prefers the old behavior. | ||
| 14 | + | ||
| 15 | + Returns: `RedirectHandler` | ||
| 16 | + | ||
| 17 | + ### Parameters | ||
| 18 | + | ||
| 19 | + - **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every redirection. | ||
| 20 | + - **maxRedirections** `number` (required) - Maximum number of redirections allowed. | ||
| 21 | + - **opts** `object` (required) - Options for handling redirection. | ||
| 22 | + - **handler** `object` (required) - Handlers for different stages of the request lifecycle. | ||
| 23 | + - **redirectionLimitReached** `boolean` (default: `false`) - A flag that the implementer can provide to enable or disable the feature. If set to `false`, it indicates that the caller doesn't want to use the feature and prefers the old behavior. | ||
| 24 | + | ||
| 25 | + ### Properties | ||
| 26 | + | ||
| 27 | + - **location** `string` - The current redirection location. | ||
| 28 | + - **abort** `function` - The abort function. | ||
| 29 | + - **opts** `object` - The options for handling redirection. | ||
| 30 | + - **maxRedirections** `number` - Maximum number of redirections allowed. | ||
| 31 | + - **handler** `object` - Handlers for different stages of the request lifecycle. | ||
| 32 | + - **history** `Array` - An array representing the history of URLs during redirection. | ||
| 33 | + - **redirectionLimitReached** `boolean` - Indicates whether the redirection limit has been reached. | ||
| 34 | + | ||
| 35 | + ### Methods | ||
| 36 | + | ||
| 37 | + #### `onConnect(abort)` | ||
| 38 | + | ||
| 39 | + Called when the connection is established. | ||
| 40 | + | ||
| 41 | + Parameters: | ||
| 42 | + | ||
| 43 | + - **abort** `function` - The abort function. | ||
| 44 | + | ||
| 45 | + #### `onUpgrade(statusCode, headers, socket)` | ||
| 46 | + | ||
| 47 | + Called when an upgrade is requested. | ||
| 48 | + | ||
| 49 | + Parameters: | ||
| 50 | + | ||
| 51 | + - **statusCode** `number` - The HTTP status code. | ||
| 52 | + - **headers** `object` - The headers received in the response. | ||
| 53 | + - **socket** `object` - The socket object. | ||
| 54 | + | ||
| 55 | + #### `onError(error)` | ||
| 56 | + | ||
| 57 | + Called when an error occurs. | ||
| 58 | + | ||
| 59 | + Parameters: | ||
| 60 | + | ||
| 61 | + - **error** `Error` - The error that occurred. | ||
| 62 | + | ||
| 63 | + #### `onHeaders(statusCode, headers, resume, statusText)` | ||
| 64 | + | ||
| 65 | + Called when headers are received. | ||
| 66 | + | ||
| 67 | + Parameters: | ||
| 68 | + | ||
| 69 | + - **statusCode** `number` - The HTTP status code. | ||
| 70 | + - **headers** `object` - The headers received in the response. | ||
| 71 | + - **resume** `function` - The resume function. | ||
| 72 | + - **statusText** `string` - The status text. | ||
| 73 | + | ||
| 74 | + #### `onData(chunk)` | ||
| 75 | + | ||
| 76 | + Called when data is received. | ||
| 77 | + | ||
| 78 | + Parameters: | ||
| 79 | + | ||
| 80 | + - **chunk** `Buffer` - The data chunk received. | ||
| 81 | + | ||
| 82 | + #### `onComplete(trailers)` | ||
| 83 | + | ||
| 84 | + Called when the request is complete. | ||
| 85 | + | ||
| 86 | + Parameters: | ||
| 87 | + | ||
| 88 | + - **trailers** `object` - The trailers received. | ||
| 89 | + | ||
| 90 | + #### `onBodySent(chunk)` | ||
| 91 | + | ||
| 92 | + Called when the request body is sent. | ||
| 93 | + | ||
| 94 | + Parameters: | ||
| 95 | + | ||
| 96 | + - **chunk** `Buffer` - The chunk of the request body sent. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,25 @@ | |||
| 1 | + # Util | ||
| 2 | + | ||
| 3 | + Utility API for third-party implementations of the dispatcher API. | ||
| 4 | + | ||
| 5 | + ## `parseHeaders(headers, [obj])` | ||
| 6 | + | ||
| 7 | + Receives a header object and returns the parsed value. | ||
| 8 | + | ||
| 9 | + Arguments: | ||
| 10 | + | ||
| 11 | + - **headers** `Record<string, string | string[]> | (Buffer | string | (Buffer | string)[])[]` (required) - Header object. | ||
| 12 | + | ||
| 13 | + - **obj** `Record<string, string | string[]>` (optional) - Object to specify a proxy object. The parsed value is assigned to this object. But, if **headers** is an object, it is not used. | ||
| 14 | + | ||
| 15 | + Returns: `Record<string, string | string[]>` If **headers** is an object, it is **headers**. Otherwise, if **obj** is specified, it is equivalent to **obj**. | ||
| 16 | + | ||
| 17 | + ## `headerNameToString(value)` | ||
| 18 | + | ||
| 19 | + Retrieves a header name and returns its lowercase value. | ||
| 20 | + | ||
| 21 | + Arguments: | ||
| 22 | + | ||
| 23 | + - **value** `string | Buffer` (required) - Header name. | ||
| 24 | + | ||
| 25 | + Returns: `string` | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,9 +11,9 @@ The server option `rejectUnauthorized: false` allows us to handle any invalid ce | |||
| 11 | 11 | ### Client Certificate Authentication | |
| 12 | 12 | ||
| 13 | 13 | ```js | |
| 14 | - const { readFileSync } = require('fs') | ||
| 15 | - const { join } = require('path') | ||
| 16 | - const { createServer } = require('https') | ||
| 14 | + const { readFileSync } = require('node:fs') | ||
| 15 | + const { join } = require('node:path') | ||
| 16 | + const { createServer } = require('node:https') | ||
| 17 | 17 | const { Client } = require('undici') | |
| 18 | 18 | ||
| 19 | 19 | const serverOptions = { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,12 +4,17 @@ const fetchImpl = require('./lib/fetch').fetch | |||
| 4 | 4 | ||
| 5 | 5 | module.exports.fetch = function fetch (resource, init = undefined) { | |
| 6 | 6 | return fetchImpl(resource, init).catch((err) => { | |
| 7 | - Error.captureStackTrace(err, this) | ||
| 7 | + if (typeof err === 'object') { | ||
| 8 | + Error.captureStackTrace(err, this) | ||
| 9 | + } | ||
| 8 | 10 | throw err | |
| 9 | 11 | }) | |
| 10 | 12 | } | |
| 11 | 13 | module.exports.FormData = require('./lib/fetch/formdata').FormData | |
| 12 | 14 | module.exports.Headers = require('./lib/fetch/headers').Headers | |
| 13 | 15 | module.exports.Response = require('./lib/fetch/response').Response | |
| 14 | 16 | module.exports.Request = require('./lib/fetch/request').Request | |
| 17 | + | ||
| 15 | 18 | module.exports.WebSocket = require('./lib/websocket/websocket').WebSocket | |
| 19 | + | ||
| 20 | + module.exports.EventSource = require('./lib/eventsource/eventsource').EventSource | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments