@depup/undici 7.24.3-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -0
  3. package/changes.json +5 -0
  4. package/docs/docs/api/Agent.md +84 -0
  5. package/docs/docs/api/BalancedPool.md +99 -0
  6. package/docs/docs/api/CacheStorage.md +30 -0
  7. package/docs/docs/api/CacheStore.md +164 -0
  8. package/docs/docs/api/Client.md +285 -0
  9. package/docs/docs/api/ClientStats.md +27 -0
  10. package/docs/docs/api/Connector.md +115 -0
  11. package/docs/docs/api/ContentType.md +57 -0
  12. package/docs/docs/api/Cookies.md +101 -0
  13. package/docs/docs/api/Debug.md +62 -0
  14. package/docs/docs/api/DiagnosticsChannel.md +313 -0
  15. package/docs/docs/api/Dispatcher.md +1392 -0
  16. package/docs/docs/api/EnvHttpProxyAgent.md +159 -0
  17. package/docs/docs/api/Errors.md +49 -0
  18. package/docs/docs/api/EventSource.md +45 -0
  19. package/docs/docs/api/Fetch.md +52 -0
  20. package/docs/docs/api/GlobalInstallation.md +91 -0
  21. package/docs/docs/api/H2CClient.md +263 -0
  22. package/docs/docs/api/MockAgent.md +603 -0
  23. package/docs/docs/api/MockCallHistory.md +197 -0
  24. package/docs/docs/api/MockCallHistoryLog.md +43 -0
  25. package/docs/docs/api/MockClient.md +81 -0
  26. package/docs/docs/api/MockErrors.md +12 -0
  27. package/docs/docs/api/MockPool.md +555 -0
  28. package/docs/docs/api/Pool.md +84 -0
  29. package/docs/docs/api/PoolStats.md +35 -0
  30. package/docs/docs/api/ProxyAgent.md +229 -0
  31. package/docs/docs/api/RedirectHandler.md +96 -0
  32. package/docs/docs/api/RetryAgent.md +50 -0
  33. package/docs/docs/api/RetryHandler.md +118 -0
  34. package/docs/docs/api/RoundRobinPool.md +145 -0
  35. package/docs/docs/api/SnapshotAgent.md +616 -0
  36. package/docs/docs/api/Socks5ProxyAgent.md +274 -0
  37. package/docs/docs/api/Util.md +25 -0
  38. package/docs/docs/api/WebSocket.md +141 -0
  39. package/docs/docs/api/api-lifecycle.md +91 -0
  40. package/docs/docs/best-practices/client-certificate.md +64 -0
  41. package/docs/docs/best-practices/crawling.md +58 -0
  42. package/docs/docs/best-practices/mocking-request.md +190 -0
  43. package/docs/docs/best-practices/proxy.md +127 -0
  44. package/docs/docs/best-practices/undici-vs-builtin-fetch.md +137 -0
  45. package/docs/docs/best-practices/writing-tests.md +20 -0
  46. package/index-fetch.js +65 -0
  47. package/index.d.ts +3 -0
  48. package/index.js +234 -0
  49. package/lib/api/abort-signal.js +59 -0
  50. package/lib/api/api-connect.js +110 -0
  51. package/lib/api/api-pipeline.js +252 -0
  52. package/lib/api/api-request.js +214 -0
  53. package/lib/api/api-stream.js +209 -0
  54. package/lib/api/api-upgrade.js +111 -0
  55. package/lib/api/index.js +7 -0
  56. package/lib/api/readable.js +580 -0
  57. package/lib/cache/memory-cache-store.js +234 -0
  58. package/lib/cache/sqlite-cache-store.js +461 -0
  59. package/lib/core/connect.js +137 -0
  60. package/lib/core/constants.js +143 -0
  61. package/lib/core/diagnostics.js +225 -0
  62. package/lib/core/errors.js +477 -0
  63. package/lib/core/request.js +430 -0
  64. package/lib/core/socks5-client.js +407 -0
  65. package/lib/core/socks5-utils.js +203 -0
  66. package/lib/core/symbols.js +75 -0
  67. package/lib/core/tree.js +160 -0
  68. package/lib/core/util.js +972 -0
  69. package/lib/dispatcher/agent.js +158 -0
  70. package/lib/dispatcher/balanced-pool.js +219 -0
  71. package/lib/dispatcher/client-h1.js +1610 -0
  72. package/lib/dispatcher/client-h2.js +995 -0
  73. package/lib/dispatcher/client.js +654 -0
  74. package/lib/dispatcher/dispatcher-base.js +165 -0
  75. package/lib/dispatcher/dispatcher.js +48 -0
  76. package/lib/dispatcher/env-http-proxy-agent.js +146 -0
  77. package/lib/dispatcher/fixed-queue.js +135 -0
  78. package/lib/dispatcher/h2c-client.js +51 -0
  79. package/lib/dispatcher/pool-base.js +214 -0
  80. package/lib/dispatcher/pool.js +118 -0
  81. package/lib/dispatcher/proxy-agent.js +318 -0
  82. package/lib/dispatcher/retry-agent.js +35 -0
  83. package/lib/dispatcher/round-robin-pool.js +137 -0
  84. package/lib/dispatcher/socks5-proxy-agent.js +249 -0
  85. package/lib/encoding/index.js +33 -0
  86. package/lib/global.js +50 -0
  87. package/lib/handler/cache-handler.js +561 -0
  88. package/lib/handler/cache-revalidation-handler.js +124 -0
  89. package/lib/handler/decorator-handler.js +67 -0
  90. package/lib/handler/deduplication-handler.js +460 -0
  91. package/lib/handler/redirect-handler.js +238 -0
  92. package/lib/handler/retry-handler.js +394 -0
  93. package/lib/handler/unwrap-handler.js +100 -0
  94. package/lib/handler/wrap-handler.js +105 -0
  95. package/lib/interceptor/cache.js +495 -0
  96. package/lib/interceptor/decompress.js +259 -0
  97. package/lib/interceptor/deduplicate.js +117 -0
  98. package/lib/interceptor/dns.js +571 -0
  99. package/lib/interceptor/dump.js +112 -0
  100. package/lib/interceptor/redirect.js +21 -0
  101. package/lib/interceptor/response-error.js +95 -0
  102. package/lib/interceptor/retry.js +19 -0
  103. package/lib/llhttp/.gitkeep +0 -0
  104. package/lib/llhttp/constants.d.ts +195 -0
  105. package/lib/llhttp/constants.js +531 -0
  106. package/lib/llhttp/llhttp-wasm.js +15 -0
  107. package/lib/llhttp/llhttp_simd-wasm.js +15 -0
  108. package/lib/llhttp/utils.d.ts +2 -0
  109. package/lib/llhttp/utils.js +12 -0
  110. package/lib/mock/mock-agent.js +232 -0
  111. package/lib/mock/mock-call-history.js +248 -0
  112. package/lib/mock/mock-client.js +68 -0
  113. package/lib/mock/mock-errors.js +29 -0
  114. package/lib/mock/mock-interceptor.js +209 -0
  115. package/lib/mock/mock-pool.js +68 -0
  116. package/lib/mock/mock-symbols.js +31 -0
  117. package/lib/mock/mock-utils.js +480 -0
  118. package/lib/mock/pending-interceptors-formatter.js +43 -0
  119. package/lib/mock/snapshot-agent.js +353 -0
  120. package/lib/mock/snapshot-recorder.js +588 -0
  121. package/lib/mock/snapshot-utils.js +158 -0
  122. package/lib/util/cache.js +407 -0
  123. package/lib/util/date.js +653 -0
  124. package/lib/util/promise.js +28 -0
  125. package/lib/util/runtime-features.js +124 -0
  126. package/lib/util/stats.js +32 -0
  127. package/lib/util/timers.js +425 -0
  128. package/lib/web/cache/cache.js +864 -0
  129. package/lib/web/cache/cachestorage.js +152 -0
  130. package/lib/web/cache/util.js +45 -0
  131. package/lib/web/cookies/constants.js +12 -0
  132. package/lib/web/cookies/index.js +199 -0
  133. package/lib/web/cookies/parse.js +322 -0
  134. package/lib/web/cookies/util.js +282 -0
  135. package/lib/web/eventsource/eventsource-stream.js +399 -0
  136. package/lib/web/eventsource/eventsource.js +501 -0
  137. package/lib/web/eventsource/util.js +29 -0
  138. package/lib/web/fetch/LICENSE +21 -0
  139. package/lib/web/fetch/body.js +509 -0
  140. package/lib/web/fetch/constants.js +131 -0
  141. package/lib/web/fetch/data-url.js +596 -0
  142. package/lib/web/fetch/formdata-parser.js +575 -0
  143. package/lib/web/fetch/formdata.js +259 -0
  144. package/lib/web/fetch/global.js +40 -0
  145. package/lib/web/fetch/headers.js +719 -0
  146. package/lib/web/fetch/index.js +2378 -0
  147. package/lib/web/fetch/request.js +1115 -0
  148. package/lib/web/fetch/response.js +641 -0
  149. package/lib/web/fetch/util.js +1520 -0
  150. package/lib/web/infra/index.js +229 -0
  151. package/lib/web/subresource-integrity/Readme.md +9 -0
  152. package/lib/web/subresource-integrity/subresource-integrity.js +307 -0
  153. package/lib/web/webidl/index.js +1006 -0
  154. package/lib/web/websocket/connection.js +329 -0
  155. package/lib/web/websocket/constants.js +126 -0
  156. package/lib/web/websocket/events.js +331 -0
  157. package/lib/web/websocket/frame.js +133 -0
  158. package/lib/web/websocket/permessage-deflate.js +118 -0
  159. package/lib/web/websocket/receiver.js +450 -0
  160. package/lib/web/websocket/sender.js +109 -0
  161. package/lib/web/websocket/stream/websocketerror.js +104 -0
  162. package/lib/web/websocket/stream/websocketstream.js +497 -0
  163. package/lib/web/websocket/util.js +347 -0
  164. package/lib/web/websocket/websocket.js +739 -0
  165. package/package.json +163 -0
  166. package/scripts/strip-comments.js +10 -0
  167. package/types/README.md +6 -0
  168. package/types/agent.d.ts +32 -0
  169. package/types/api.d.ts +43 -0
  170. package/types/balanced-pool.d.ts +30 -0
  171. package/types/cache-interceptor.d.ts +179 -0
  172. package/types/cache.d.ts +36 -0
  173. package/types/client-stats.d.ts +15 -0
  174. package/types/client.d.ts +123 -0
  175. package/types/connector.d.ts +36 -0
  176. package/types/content-type.d.ts +21 -0
  177. package/types/cookies.d.ts +30 -0
  178. package/types/diagnostics-channel.d.ts +74 -0
  179. package/types/dispatcher.d.ts +279 -0
  180. package/types/env-http-proxy-agent.d.ts +22 -0
  181. package/types/errors.d.ts +177 -0
  182. package/types/eventsource.d.ts +66 -0
  183. package/types/fetch.d.ts +211 -0
  184. package/types/formdata.d.ts +108 -0
  185. package/types/global-dispatcher.d.ts +9 -0
  186. package/types/global-origin.d.ts +7 -0
  187. package/types/h2c-client.d.ts +73 -0
  188. package/types/handlers.d.ts +15 -0
  189. package/types/header.d.ts +160 -0
  190. package/types/index.d.ts +91 -0
  191. package/types/interceptors.d.ts +80 -0
  192. package/types/mock-agent.d.ts +68 -0
  193. package/types/mock-call-history.d.ts +111 -0
  194. package/types/mock-client.d.ts +27 -0
  195. package/types/mock-errors.d.ts +12 -0
  196. package/types/mock-interceptor.d.ts +94 -0
  197. package/types/mock-pool.d.ts +27 -0
  198. package/types/patch.d.ts +29 -0
  199. package/types/pool-stats.d.ts +19 -0
  200. package/types/pool.d.ts +41 -0
  201. package/types/proxy-agent.d.ts +29 -0
  202. package/types/readable.d.ts +68 -0
  203. package/types/retry-agent.d.ts +8 -0
  204. package/types/retry-handler.d.ts +125 -0
  205. package/types/round-robin-pool.d.ts +41 -0
  206. package/types/snapshot-agent.d.ts +109 -0
  207. package/types/socks5-proxy-agent.d.ts +25 -0
  208. package/types/util.d.ts +18 -0
  209. package/types/utility.d.ts +7 -0
  210. package/types/webidl.d.ts +347 -0
  211. package/types/websocket.d.ts +188 -0
@@ -0,0 +1,285 @@
1
+ # Class: Client
2
+
3
+ Extends: `undici.Dispatcher`
4
+
5
+ A basic HTTP/1.1 client, mapped on top a single TCP/TLS connection. Pipelining is disabled by default.
6
+
7
+ Requests are not guaranteed to be dispatched in order of invocation.
8
+
9
+ ## `new Client(url[, options])`
10
+
11
+ Arguments:
12
+
13
+ * **url** `URL | string` - Should only include the **protocol, hostname, and port**.
14
+ * **options** `ClientOptions` (optional)
15
+
16
+ Returns: `Client`
17
+
18
+ ### Parameter: `ClientOptions`
19
+
20
+ * **bodyTimeout** `number | null` (optional) - Default: `300e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 300 seconds. Please note the `timeout` will be reset if you keep writing data to the socket everytime.
21
+ * **headersTimeout** `number | null` (optional) - Default: `300e3` - The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 300 seconds.
22
+ * **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout`, in milliseconds, when overridden by *keep-alive* hints from the server. Defaults to 10 minutes.
23
+ * **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout, in milliseconds, after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds.
24
+ * **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `2e3` - A number of milliseconds subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 2 seconds.
25
+ * **maxHeaderSize** `number | null` (optional) - Default: `--max-http-header-size` or `16384` - The maximum length of request headers in bytes. Defaults to Node.js' --max-http-header-size or 16KiB.
26
+ * **maxResponseSize** `number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable.
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
+ * **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. **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
+ * **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
+ * **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
+ * **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.
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.
35
+ * **initialWindowSize**: `number` (optional) - Default: `262144` (256KB). Sets the HTTP/2 stream-level flow-control window size (SETTINGS_INITIAL_WINDOW_SIZE). Must be a positive integer greater than 0. This default is higher than Node.js core's default (65535 bytes) to improve throughput, Node's choice is very conservative for current high-bandwith networks. See [RFC 7540 Section 6.9.2](https://datatracker.ietf.org/doc/html/rfc7540#section-6.9.2) for more details.
36
+ * **connectionWindowSize**: `number` (optional) - Default `524288` (512KB). Sets the HTTP/2 connection-level flow-control window size using `ClientHttp2Session.setLocalWindowSize()`. Must be a positive integer greater than 0. This provides better flow control for the entire connection across multiple streams. See [Node.js HTTP/2 documentation](https://nodejs.org/api/http2.html#clienthttp2sessionsetlocalwindowsize) for more details.
37
+ * **pingInterval**: `number` - Default: `60e3`. The time interval in milliseconds between PING frames sent to the server. Set to `0` to disable PING frames. This is only applicable for HTTP/2 connections. This will emit a `ping` event on the client with the duration of the ping in milliseconds.
38
+
39
+ > **Notes about HTTP/2**
40
+ > - It only works under TLS connections. h2c is not supported.
41
+ > - The server must support HTTP/2 and choose it as the protocol during the ALPN negotiation.
42
+ > - The server must not have a bigger priority for HTTP/1.1 than HTTP/2.
43
+ > - Pseudo headers are automatically attached to the request. If you try to set them, they will be overwritten.
44
+ > - The `:path` header is automatically set to the request path.
45
+ > - The `:method` header is automatically set to the request method.
46
+ > - The `:scheme` header is automatically set to the request scheme.
47
+ > - The `:authority` header is automatically set to the request `host[:port]`.
48
+ > - `PUSH` frames are yet not supported.
49
+
50
+ #### Parameter: `ConnectOptions`
51
+
52
+ Every Tls option, see [here](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
53
+ Furthermore, the following options can be passed:
54
+
55
+ * **socketPath** `string | null` (optional) - Default: `null` - An IPC endpoint, either Unix domain socket or Windows named pipe.
56
+ * **maxCachedSessions** `number | null` (optional) - Default: `100` - Maximum number of TLS cached sessions. Use 0 to disable TLS session caching. Default: 100.
57
+ * **timeout** `number | null` (optional) - In milliseconds, Default `10e3`.
58
+ * **servername** `string | null` (optional)
59
+ * **keepAlive** `boolean | null` (optional) - Default: `true` - TCP keep-alive enabled
60
+ * **keepAliveInitialDelay** `number | null` (optional) - Default: `60000` - TCP keep-alive interval for the socket in milliseconds
61
+
62
+ ### Example - Basic Client instantiation
63
+
64
+ This will instantiate the undici Client, but it will not connect to the origin until something is queued. Consider using `client.connect` to prematurely connect to the origin, or just call `client.request`.
65
+
66
+ ```js
67
+ 'use strict'
68
+ import { Client } from 'undici'
69
+
70
+ const client = new Client('http://localhost:3000')
71
+ ```
72
+
73
+ ### Example - Custom connector
74
+
75
+ This will allow you to perform some additional check on the socket that will be used for the next request.
76
+
77
+ ```js
78
+ 'use strict'
79
+ import { Client, buildConnector } from 'undici'
80
+
81
+ const connector = buildConnector({ rejectUnauthorized: false })
82
+ const client = new Client('https://localhost:3000', {
83
+ connect (opts, cb) {
84
+ connector(opts, (err, socket) => {
85
+ if (err) {
86
+ cb(err)
87
+ } else if (/* assertion */) {
88
+ socket.destroy()
89
+ cb(new Error('kaboom'))
90
+ } else {
91
+ cb(null, socket)
92
+ }
93
+ })
94
+ }
95
+ })
96
+ ```
97
+
98
+ ## Instance Methods
99
+
100
+ ### `Client.close([callback])`
101
+
102
+ Implements [`Dispatcher.close([callback])`](/docs/docs/api/Dispatcher.md#dispatcherclosecallback-promise).
103
+
104
+ ### `Client.destroy([error, callback])`
105
+
106
+ Implements [`Dispatcher.destroy([error, callback])`](/docs/docs/api/Dispatcher.md#dispatcherdestroyerror-callback-promise).
107
+
108
+ Waits until socket is closed before invoking the callback (or returning a promise if no callback is provided).
109
+
110
+ ### `Client.connect(options[, callback])`
111
+
112
+ See [`Dispatcher.connect(options[, callback])`](/docs/docs/api/Dispatcher.md#dispatcherconnectoptions-callback).
113
+
114
+ ### `Client.dispatch(options, handlers)`
115
+
116
+ Implements [`Dispatcher.dispatch(options, handlers)`](/docs/docs/api/Dispatcher.md#dispatcherdispatchoptions-handler).
117
+
118
+ ### `Client.pipeline(options, handler)`
119
+
120
+ See [`Dispatcher.pipeline(options, handler)`](/docs/docs/api/Dispatcher.md#dispatcherpipelineoptions-handler).
121
+
122
+ ### `Client.request(options[, callback])`
123
+
124
+ See [`Dispatcher.request(options [, callback])`](/docs/docs/api/Dispatcher.md#dispatcherrequestoptions-callback).
125
+
126
+ ### `Client.stream(options, factory[, callback])`
127
+
128
+ See [`Dispatcher.stream(options, factory[, callback])`](/docs/docs/api/Dispatcher.md#dispatcherstreamoptions-factory-callback).
129
+
130
+ ### `Client.upgrade(options[, callback])`
131
+
132
+ See [`Dispatcher.upgrade(options[, callback])`](/docs/docs/api/Dispatcher.md#dispatcherupgradeoptions-callback).
133
+
134
+ ## Instance Properties
135
+
136
+ ### `Client.closed`
137
+
138
+ * `boolean`
139
+
140
+ `true` after `client.close()` has been called.
141
+
142
+ ### `Client.destroyed`
143
+
144
+ * `boolean`
145
+
146
+ `true` after `client.destroyed()` has been called or `client.close()` has been called and the client shutdown has completed.
147
+
148
+ ### `Client.pipelining`
149
+
150
+ * `number`
151
+
152
+ Property to get and set the pipelining factor.
153
+
154
+ ## Instance Events
155
+
156
+ ### Event: `'connect'`
157
+
158
+ See [Dispatcher Event: `'connect'`](/docs/docs/api/Dispatcher.md#event-connect).
159
+
160
+ Parameters:
161
+
162
+ * **origin** `URL`
163
+ * **targets** `Array<Dispatcher>`
164
+
165
+ Emitted when a socket has been created and connected. The client will connect once `client.size > 0`.
166
+
167
+ #### Example - Client connect event
168
+
169
+ ```js
170
+ import { createServer } from 'http'
171
+ import { Client } from 'undici'
172
+ import { once } from 'events'
173
+
174
+ const server = createServer((request, response) => {
175
+ response.end('Hello, World!')
176
+ }).listen()
177
+
178
+ await once(server, 'listening')
179
+
180
+ const client = new Client(`http://localhost:${server.address().port}`)
181
+
182
+ client.on('connect', (origin) => {
183
+ console.log(`Connected to ${origin}`) // should print before the request body statement
184
+ })
185
+
186
+ try {
187
+ const { body } = await client.request({
188
+ path: '/',
189
+ method: 'GET'
190
+ })
191
+ body.setEncoding('utf-8')
192
+ body.on('data', console.log)
193
+ client.close()
194
+ server.close()
195
+ } catch (error) {
196
+ console.error(error)
197
+ client.close()
198
+ server.close()
199
+ }
200
+ ```
201
+
202
+ ### Event: `'disconnect'`
203
+
204
+ See [Dispatcher Event: `'disconnect'`](/docs/docs/api/Dispatcher.md#event-disconnect).
205
+
206
+ Parameters:
207
+
208
+ * **origin** `URL`
209
+ * **targets** `Array<Dispatcher>`
210
+ * **error** `Error`
211
+
212
+ Emitted when socket has disconnected. The error argument of the event is the error which caused the socket to disconnect. The client will reconnect if or once `client.size > 0`.
213
+
214
+ #### Example - Client disconnect event
215
+
216
+ ```js
217
+ import { createServer } from 'http'
218
+ import { Client } from 'undici'
219
+ import { once } from 'events'
220
+
221
+ const server = createServer((request, response) => {
222
+ response.destroy()
223
+ }).listen()
224
+
225
+ await once(server, 'listening')
226
+
227
+ const client = new Client(`http://localhost:${server.address().port}`)
228
+
229
+ client.on('disconnect', (origin) => {
230
+ console.log(`Disconnected from ${origin}`)
231
+ })
232
+
233
+ try {
234
+ await client.request({
235
+ path: '/',
236
+ method: 'GET'
237
+ })
238
+ } catch (error) {
239
+ console.error(error.message)
240
+ client.close()
241
+ server.close()
242
+ }
243
+ ```
244
+
245
+ ### Event: `'drain'`
246
+
247
+ Emitted when pipeline is no longer busy.
248
+
249
+ See [Dispatcher Event: `'drain'`](/docs/docs/api/Dispatcher.md#event-drain).
250
+
251
+ #### Example - Client drain event
252
+
253
+ ```js
254
+ import { createServer } from 'http'
255
+ import { Client } from 'undici'
256
+ import { once } from 'events'
257
+
258
+ const server = createServer((request, response) => {
259
+ response.end('Hello, World!')
260
+ }).listen()
261
+
262
+ await once(server, 'listening')
263
+
264
+ const client = new Client(`http://localhost:${server.address().port}`)
265
+
266
+ client.on('drain', () => {
267
+ console.log('drain event')
268
+ client.close()
269
+ server.close()
270
+ })
271
+
272
+ const requests = [
273
+ client.request({ path: '/', method: 'GET' }),
274
+ client.request({ path: '/', method: 'GET' }),
275
+ client.request({ path: '/', method: 'GET' })
276
+ ]
277
+
278
+ await Promise.all(requests)
279
+
280
+ console.log('requests completed')
281
+ ```
282
+
283
+ ### Event: `'error'`
284
+
285
+ Invoked for users errors such as throwing in the `onError` handler.
@@ -0,0 +1,27 @@
1
+ # Class: ClientStats
2
+
3
+ Stats for a [Client](/docs/docs/api/Client.md).
4
+
5
+ ## `new ClientStats(client)`
6
+
7
+ Arguments:
8
+
9
+ * **client** `Client` - Client from which to return stats.
10
+
11
+ ## Instance Properties
12
+
13
+ ### `ClientStats.connected`
14
+
15
+ Boolean if socket as open connection by this client.
16
+
17
+ ### `ClientStats.pending`
18
+
19
+ Number of pending requests of this client.
20
+
21
+ ### `ClientStats.running`
22
+
23
+ Number of currently active requests across this client.
24
+
25
+ ### `ClientStats.size`
26
+
27
+ Number of active, pending, or queued requests of this clients.
@@ -0,0 +1,115 @@
1
+ # Connector
2
+
3
+ Undici creates the underlying socket via the connector builder.
4
+ Normally, this happens automatically and you don't need to care about this,
5
+ but if you need to perform some additional check over the currently used socket,
6
+ this is the right place.
7
+
8
+ If you want to create a custom connector, you must import the `buildConnector` utility.
9
+
10
+ #### Parameter: `buildConnector.BuildOptions`
11
+
12
+ Every Tls option, see [here](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
13
+ Furthermore, the following options can be passed:
14
+
15
+ * **socketPath** `string | null` (optional) - Default: `null` - An IPC endpoint, either Unix domain socket or Windows named pipe.
16
+ * **maxCachedSessions** `number | null` (optional) - Default: `100` - Maximum number of TLS cached sessions. Use 0 to disable TLS session caching. Default: `100`.
17
+ * **timeout** `number | null` (optional) - In milliseconds. Default `10e3`.
18
+ * **servername** `string | null` (optional)
19
+
20
+ Once you call `buildConnector`, it will return a connector function, which takes the following parameters.
21
+
22
+ #### Parameter: `connector.Options`
23
+
24
+ * **hostname** `string` (required)
25
+ * **host** `string` (optional)
26
+ * **protocol** `string` (required)
27
+ * **port** `string` (required)
28
+ * **servername** `string` (optional)
29
+ * **localAddress** `string | null` (optional) Local address the socket should connect from.
30
+ * **httpSocket** `Socket` (optional) Establish secure connection on a given socket rather than creating a new socket. It can only be sent on TLS update.
31
+
32
+ ### Basic example
33
+
34
+ ```js
35
+ 'use strict'
36
+
37
+ import { Client, buildConnector } from 'undici'
38
+
39
+ const connector = buildConnector({ rejectUnauthorized: false })
40
+ const client = new Client('https://localhost:3000', {
41
+ connect (opts, cb) {
42
+ connector(opts, (err, socket) => {
43
+ if (err) {
44
+ cb(err)
45
+ } else if (/* assertion */) {
46
+ socket.destroy()
47
+ cb(new Error('kaboom'))
48
+ } else {
49
+ cb(null, socket)
50
+ }
51
+ })
52
+ }
53
+ })
54
+ ```
55
+
56
+ ### Example: validate the CA fingerprint
57
+
58
+ ```js
59
+ 'use strict'
60
+
61
+ import { Client, buildConnector } from 'undici'
62
+
63
+ const caFingerprint = 'FO:OB:AR'
64
+ const connector = buildConnector({ rejectUnauthorized: false })
65
+ const client = new Client('https://localhost:3000', {
66
+ connect (opts, cb) {
67
+ connector(opts, (err, socket) => {
68
+ if (err) {
69
+ cb(err)
70
+ } else if (getIssuerCertificate(socket).fingerprint256 !== caFingerprint) {
71
+ socket.destroy()
72
+ cb(new Error('Fingerprint does not match or malformed certificate'))
73
+ } else {
74
+ cb(null, socket)
75
+ }
76
+ })
77
+ }
78
+ })
79
+
80
+ client.request({
81
+ path: '/',
82
+ method: 'GET'
83
+ }, (err, data) => {
84
+ if (err) throw err
85
+
86
+ const bufs = []
87
+ data.body.on('data', (buf) => {
88
+ bufs.push(buf)
89
+ })
90
+ data.body.on('end', () => {
91
+ console.log(Buffer.concat(bufs).toString('utf8'))
92
+ client.close()
93
+ })
94
+ })
95
+
96
+ function getIssuerCertificate (socket) {
97
+ let certificate = socket.getPeerCertificate(true)
98
+ while (certificate && Object.keys(certificate).length > 0) {
99
+ // invalid certificate
100
+ if (certificate.issuerCertificate == null) {
101
+ return null
102
+ }
103
+
104
+ // We have reached the root certificate.
105
+ // In case of self-signed certificates, `issuerCertificate` may be a circular reference.
106
+ if (certificate.fingerprint256 === certificate.issuerCertificate.fingerprint256) {
107
+ break
108
+ }
109
+
110
+ // continue the loop
111
+ certificate = certificate.issuerCertificate
112
+ }
113
+ return certificate
114
+ }
115
+ ```
@@ -0,0 +1,57 @@
1
+ # MIME Type Parsing
2
+
3
+ ## `MIMEType` interface
4
+
5
+ * **type** `string`
6
+ * **subtype** `string`
7
+ * **parameters** `Map<string, string>`
8
+ * **essence** `string`
9
+
10
+ ## `parseMIMEType(input)`
11
+
12
+ Implements [parse a MIME type](https://mimesniff.spec.whatwg.org/#parse-a-mime-type).
13
+
14
+ Parses a MIME type, returning its type, subtype, and any associated parameters. If the parser can't parse an input it returns the string literal `'failure'`.
15
+
16
+ ```js
17
+ import { parseMIMEType } from 'undici'
18
+
19
+ parseMIMEType('text/html; charset=gbk')
20
+ // {
21
+ // type: 'text',
22
+ // subtype: 'html',
23
+ // parameters: Map(1) { 'charset' => 'gbk' },
24
+ // essence: 'text/html'
25
+ // }
26
+ ```
27
+
28
+ Arguments:
29
+
30
+ * **input** `string`
31
+
32
+ Returns: `MIMEType|'failure'`
33
+
34
+ ## `serializeAMimeType(input)`
35
+
36
+ Implements [serialize a MIME type](https://mimesniff.spec.whatwg.org/#serialize-a-mime-type).
37
+
38
+ Serializes a MIMEType object.
39
+
40
+ ```js
41
+ import { serializeAMimeType } from 'undici'
42
+
43
+ serializeAMimeType({
44
+ type: 'text',
45
+ subtype: 'html',
46
+ parameters: new Map([['charset', 'gbk']]),
47
+ essence: 'text/html'
48
+ })
49
+ // text/html;charset=gbk
50
+
51
+ ```
52
+
53
+ Arguments:
54
+
55
+ * **mimeType** `MIMEType`
56
+
57
+ Returns: `string`
@@ -0,0 +1,101 @@
1
+ # Cookie Handling
2
+
3
+ ## `Cookie` interface
4
+
5
+ * **name** `string`
6
+ * **value** `string`
7
+ * **expires** `Date|number` (optional)
8
+ * **maxAge** `number` (optional)
9
+ * **domain** `string` (optional)
10
+ * **path** `string` (optional)
11
+ * **secure** `boolean` (optional)
12
+ * **httpOnly** `boolean` (optional)
13
+ * **sameSite** `'String'|'Lax'|'None'` (optional)
14
+ * **unparsed** `string[]` (optional) Left over attributes that weren't parsed.
15
+
16
+ ## `deleteCookie(headers, name[, attributes])`
17
+
18
+ Sets the expiry time of the cookie to the unix epoch, causing browsers to delete it when received.
19
+
20
+ ```js
21
+ import { deleteCookie, Headers } from 'undici'
22
+
23
+ const headers = new Headers()
24
+ deleteCookie(headers, 'name')
25
+
26
+ console.log(headers.get('set-cookie')) // name=; Expires=Thu, 01 Jan 1970 00:00:00 GMT
27
+ ```
28
+
29
+ Arguments:
30
+
31
+ * **headers** `Headers`
32
+ * **name** `string`
33
+ * **attributes** `{ path?: string, domain?: string }` (optional)
34
+
35
+ Returns: `void`
36
+
37
+ ## `getCookies(headers)`
38
+
39
+ Parses the `Cookie` header and returns a list of attributes and values.
40
+
41
+ ```js
42
+ import { getCookies, Headers } from 'undici'
43
+
44
+ const headers = new Headers({
45
+ cookie: 'get=cookies; and=attributes'
46
+ })
47
+
48
+ console.log(getCookies(headers)) // { get: 'cookies', and: 'attributes' }
49
+ ```
50
+
51
+ Arguments:
52
+
53
+ * **headers** `Headers`
54
+
55
+ Returns: `Record<string, string>`
56
+
57
+ ## `getSetCookies(headers)`
58
+
59
+ Parses all `Set-Cookie` headers.
60
+
61
+ ```js
62
+ import { getSetCookies, Headers } from 'undici'
63
+
64
+ const headers = new Headers({ 'set-cookie': 'undici=getSetCookies; Secure' })
65
+
66
+ console.log(getSetCookies(headers))
67
+ // [
68
+ // {
69
+ // name: 'undici',
70
+ // value: 'getSetCookies',
71
+ // secure: true
72
+ // }
73
+ // ]
74
+
75
+ ```
76
+
77
+ Arguments:
78
+
79
+ * **headers** `Headers`
80
+
81
+ Returns: `Cookie[]`
82
+
83
+ ## `setCookie(headers, cookie)`
84
+
85
+ Appends a cookie to the `Set-Cookie` header.
86
+
87
+ ```js
88
+ import { setCookie, Headers } from 'undici'
89
+
90
+ const headers = new Headers()
91
+ setCookie(headers, { name: 'undici', value: 'setCookie' })
92
+
93
+ console.log(headers.get('Set-Cookie')) // undici=setCookie
94
+ ```
95
+
96
+ Arguments:
97
+
98
+ * **headers** `Headers`
99
+ * **cookie** `Cookie`
100
+
101
+ Returns: `void`
@@ -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 available 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
+ ```