undici 7.0.0-alpha.3 → 7.0.0-alpha.4
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.
- package/README.md +2 -1
- package/docs/docs/api/BalancedPool.md +1 -1
- package/docs/docs/api/CacheStore.md +16 -32
- package/docs/docs/api/Dispatcher.md +22 -2
- package/docs/docs/api/MockClient.md +1 -1
- package/docs/docs/api/Pool.md +1 -1
- package/docs/docs/api/api-lifecycle.md +2 -2
- package/docs/docs/best-practices/mocking-request.md +2 -2
- package/docs/docs/best-practices/proxy.md +1 -1
- package/index.d.ts +1 -1
- package/index.js +2 -1
- package/lib/api/api-request.js +1 -1
- package/lib/cache/memory-cache-store.js +108 -200
- package/lib/core/connect.js +5 -0
- package/lib/core/request.js +2 -2
- package/lib/core/util.js +13 -40
- package/lib/dispatcher/client-h2.js +53 -33
- package/lib/handler/cache-handler.js +112 -82
- package/lib/handler/cache-revalidation-handler.js +45 -13
- package/lib/handler/redirect-handler.js +5 -3
- package/lib/handler/retry-handler.js +3 -3
- package/lib/interceptor/cache.js +115 -94
- package/lib/interceptor/dns.js +71 -48
- package/lib/util/cache.js +38 -13
- package/lib/web/cookies/index.js +12 -1
- package/lib/web/cookies/parse.js +6 -1
- package/lib/web/fetch/body.js +1 -5
- package/lib/web/fetch/formdata-parser.js +70 -43
- package/lib/web/fetch/headers.js +1 -1
- package/lib/web/fetch/index.js +4 -6
- package/lib/web/fetch/webidl.js +12 -4
- package/package.json +2 -3
- package/types/cache-interceptor.d.ts +36 -32
- package/types/cookies.d.ts +2 -0
- package/types/dispatcher.d.ts +1 -1
- package/types/index.d.ts +0 -1
- package/types/interceptors.d.ts +0 -1
package/README.md
CHANGED
|
@@ -402,7 +402,8 @@ Refs: https://tools.ietf.org/html/rfc7231#section-5.1.1
|
|
|
402
402
|
### Pipelining
|
|
403
403
|
|
|
404
404
|
Undici will only use pipelining if configured with a `pipelining` factor
|
|
405
|
-
greater than `1`.
|
|
405
|
+
greater than `1`. Also it is important to pass `blocking: false` to the
|
|
406
|
+
request options to properly pipeline requests.
|
|
406
407
|
|
|
407
408
|
Undici always assumes that connections are persistent and will immediately
|
|
408
409
|
pipeline requests, without checking whether the connection is persistent.
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
A Cache Store is responsible for storing and retrieving cached responses.
|
|
4
4
|
It is also responsible for deciding which specific response to use based off of
|
|
5
|
-
a response's `Vary` header (if present).
|
|
5
|
+
a response's `Vary` header (if present). It is expected to be compliant with
|
|
6
|
+
[RFC-9111](https://www.rfc-editor.org/rfc/rfc9111.html).
|
|
6
7
|
|
|
7
8
|
## Pre-built Cache Stores
|
|
8
9
|
|
|
@@ -21,27 +22,33 @@ The store must implement the following functions:
|
|
|
21
22
|
|
|
22
23
|
### Getter: `isFull`
|
|
23
24
|
|
|
24
|
-
This tells the cache interceptor if the store is full or not. If this is true,
|
|
25
|
+
Optional. This tells the cache interceptor if the store is full or not. If this is true,
|
|
25
26
|
the cache interceptor will not attempt to cache the response.
|
|
26
27
|
|
|
27
|
-
### Function: `
|
|
28
|
+
### Function: `get`
|
|
28
29
|
|
|
29
30
|
Parameters:
|
|
30
31
|
|
|
31
32
|
* **req** `Dispatcher.RequestOptions` - Incoming request
|
|
32
33
|
|
|
33
|
-
Returns: `
|
|
34
|
+
Returns: `GetResult | Promise<GetResult | undefined> | undefined` - If the request is cached, the cached response is returned. If the request's method is anything other than HEAD, the response is also returned.
|
|
35
|
+
If the request isn't cached, `undefined` is returned.
|
|
36
|
+
|
|
37
|
+
Response properties:
|
|
38
|
+
|
|
39
|
+
* **response** `CachedResponse` - The cached response data.
|
|
40
|
+
* **body** `Readable | undefined` - The response's body.
|
|
34
41
|
|
|
35
42
|
### Function: `createWriteStream`
|
|
36
43
|
|
|
37
44
|
Parameters:
|
|
38
45
|
|
|
39
46
|
* **req** `Dispatcher.RequestOptions` - Incoming request
|
|
40
|
-
* **value** `
|
|
47
|
+
* **value** `CachedResponse` - Response to store
|
|
41
48
|
|
|
42
|
-
Returns: `
|
|
49
|
+
Returns: `Writable | undefined` - If the store is full, return `undefined`. Otherwise, return a writable so that the cache interceptor can stream the body and trailers to the store.
|
|
43
50
|
|
|
44
|
-
## `
|
|
51
|
+
## `CachedResponse`
|
|
45
52
|
|
|
46
53
|
This is an interface containing the majority of a response's data (minus the body).
|
|
47
54
|
|
|
@@ -55,15 +62,11 @@ This is an interface containing the majority of a response's data (minus the bod
|
|
|
55
62
|
|
|
56
63
|
### Property `rawHeaders`
|
|
57
64
|
|
|
58
|
-
`
|
|
59
|
-
|
|
60
|
-
### Property `rawTrailers`
|
|
61
|
-
|
|
62
|
-
`string[] | undefined` - The response's trailers.
|
|
65
|
+
`Buffer[]` - The response's headers.
|
|
63
66
|
|
|
64
67
|
### Property `vary`
|
|
65
68
|
|
|
66
|
-
`Record<string, string> | undefined` - The headers defined by the response's `Vary` header
|
|
69
|
+
`Record<string, string | string[]> | undefined` - The headers defined by the response's `Vary` header
|
|
67
70
|
and their respective values for later comparison
|
|
68
71
|
|
|
69
72
|
For example, for a response like
|
|
@@ -95,22 +98,3 @@ This would be
|
|
|
95
98
|
is either the same sa staleAt or the `max-stale` caching directive.
|
|
96
99
|
|
|
97
100
|
The store must not return a response after the time defined in this property.
|
|
98
|
-
|
|
99
|
-
## `CacheStoreReadable`
|
|
100
|
-
|
|
101
|
-
This extends Node's [`Readable`](https://nodejs.org/api/stream.html#class-streamreadable)
|
|
102
|
-
and defines extra properties relevant to the cache interceptor.
|
|
103
|
-
|
|
104
|
-
### Getter: `value`
|
|
105
|
-
|
|
106
|
-
The response's [`CacheStoreValue`](#cachestorevalue)
|
|
107
|
-
|
|
108
|
-
## `CacheStoreWriteable`
|
|
109
|
-
|
|
110
|
-
This extends Node's [`Writable`](https://nodejs.org/api/stream.html#class-streamwritable)
|
|
111
|
-
and defines extra properties relevant to the cache interceptor.
|
|
112
|
-
|
|
113
|
-
### Setter: `rawTrailers`
|
|
114
|
-
|
|
115
|
-
If the response has trailers, the cache interceptor will pass them to the cache
|
|
116
|
-
interceptor through this method.
|
|
@@ -197,7 +197,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
|
|
|
197
197
|
* **headers** `UndiciHeaders | string[]` (optional) - Default: `null`.
|
|
198
198
|
* **query** `Record<string, any> | null` (optional) - Default: `null` - Query string params to be embedded in the request URL. Note that both keys and values of query are encoded using `encodeURIComponent`. If for some reason you need to send them unencoded, embed query params into path directly instead.
|
|
199
199
|
* **idempotent** `boolean` (optional) - Default: `true` if `method` is `'HEAD'` or `'GET'` - Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceding requests in the pipeline has completed.
|
|
200
|
-
* **blocking** `boolean` (optional) - Default: `
|
|
200
|
+
* **blocking** `boolean` (optional) - Default: `method !== 'HEAD'` - Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received.
|
|
201
201
|
* **upgrade** `string | null` (optional) - Default: `null` - Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`.
|
|
202
202
|
* **bodyTimeout** `number | null` (optional) - 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.
|
|
203
203
|
* **headersTimeout** `number | null` (optional) - 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.
|
|
@@ -527,6 +527,7 @@ try {
|
|
|
527
527
|
console.log('headers', headers)
|
|
528
528
|
body.setEncoding('utf8')
|
|
529
529
|
body.on('data', console.log)
|
|
530
|
+
body.on('error', console.error)
|
|
530
531
|
body.on('end', () => {
|
|
531
532
|
console.log('trailers', trailers)
|
|
532
533
|
})
|
|
@@ -630,6 +631,25 @@ try {
|
|
|
630
631
|
}
|
|
631
632
|
```
|
|
632
633
|
|
|
634
|
+
#### Example 3 - Conditionally reading the body
|
|
635
|
+
|
|
636
|
+
Remember to fully consume the body even in the case when it is not read.
|
|
637
|
+
|
|
638
|
+
```js
|
|
639
|
+
const { body, statusCode } = await client.request({
|
|
640
|
+
path: '/',
|
|
641
|
+
method: 'GET'
|
|
642
|
+
})
|
|
643
|
+
|
|
644
|
+
if (statusCode === 200) {
|
|
645
|
+
return await body.arrayBuffer()
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
await body.dump()
|
|
649
|
+
|
|
650
|
+
return null
|
|
651
|
+
```
|
|
652
|
+
|
|
633
653
|
### `Dispatcher.stream(options, factory[, callback])`
|
|
634
654
|
|
|
635
655
|
A faster version of `Dispatcher.request`. This method expects the second argument `factory` to return a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream which the response will be written to. This improves performance by avoiding creating an intermediate [`stream.Readable`](https://nodejs.org/api/stream.html#stream_readable_streams) stream when the user expects to directly pipe the response body to a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream.
|
|
@@ -1001,7 +1021,7 @@ The `dns` interceptor enables you to cache DNS lookups for a given duration, per
|
|
|
1001
1021
|
- It can be either `'4` or `6`.
|
|
1002
1022
|
- It will only take effect if `dualStack` is `false`.
|
|
1003
1023
|
- `lookup: (hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, addresses: DNSInterceptorRecord[]) => void) => void` - Custom lookup function. Default: `dns.lookup`.
|
|
1004
|
-
- For more info see [dns.lookup](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback).
|
|
1024
|
+
- For more info see [dns.lookup](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback).
|
|
1005
1025
|
- `pick: (origin: URL, records: DNSInterceptorRecords, affinity: 4 | 6) => DNSInterceptorRecord` - Custom pick function. Default: `RoundRobin`.
|
|
1006
1026
|
- The function should return a single record from the records array.
|
|
1007
1027
|
- By default a simplified version of Round Robin is used.
|
package/docs/docs/api/Pool.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Extends: `undici.Dispatcher`
|
|
4
4
|
|
|
5
|
-
A pool of [Client](Client.md) instances connected to the same upstream target.
|
|
5
|
+
A pool of [Client](/docs/docs/api/Client.md) instances connected to the same upstream target.
|
|
6
6
|
|
|
7
7
|
Requests are not guaranteed to be dispatched in order of invocation.
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Client Lifecycle
|
|
2
2
|
|
|
3
|
-
An Undici [Client](Client.md) can be best described as a state machine. The following list is a summary of the various state transitions the `Client` will go through in its lifecycle. This document also contains detailed breakdowns of each state.
|
|
3
|
+
An Undici [Client](/docs/docs/api/Client.md) can be best described as a state machine. The following list is a summary of the various state transitions the `Client` will go through in its lifecycle. This document also contains detailed breakdowns of each state.
|
|
4
4
|
|
|
5
5
|
> This diagram is not a perfect representation of the undici Client. Since the Client class is not actually implemented as a state-machine, actual execution may deviate slightly from what is described below. Consider this as a general resource for understanding the inner workings of the Undici client rather than some kind of formal specification.
|
|
6
6
|
|
|
@@ -28,7 +28,7 @@ stateDiagram-v2
|
|
|
28
28
|
[*] --> idle
|
|
29
29
|
idle --> pending : connect
|
|
30
30
|
idle --> destroyed : destroy/close
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
pending --> idle : timeout
|
|
33
33
|
pending --> destroyed : destroy
|
|
34
34
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Mocking Request
|
|
2
2
|
|
|
3
|
-
Undici has its own mocking [utility](
|
|
3
|
+
Undici has its own mocking [utility](/docs/docs/api/MockAgent.md). It allow us to intercept undici HTTP requests and return mocked values instead. It can be useful for testing purposes.
|
|
4
4
|
|
|
5
5
|
Example:
|
|
6
6
|
|
|
@@ -73,7 +73,7 @@ const badRequest = await bankTransfer('1234567890', '100')
|
|
|
73
73
|
assert.deepEqual(badRequest, { message: 'bank account not found' })
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
Explore other MockAgent functionality [here](
|
|
76
|
+
Explore other MockAgent functionality [here](/docs/docs/api/MockAgent.md)
|
|
77
77
|
|
|
78
78
|
## Debug Mock Value
|
|
79
79
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Connecting through a proxy is possible by:
|
|
4
4
|
|
|
5
|
-
- Using [ProxyAgent](
|
|
5
|
+
- Using [ProxyAgent](/docs/docs/api/ProxyAgent.md).
|
|
6
6
|
- Configuring `Client` or `Pool` constructor.
|
|
7
7
|
|
|
8
8
|
The proxy url should be passed to the `Client` or `Pool` constructor, while the upstream server url
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -136,12 +136,13 @@ const { kConstruct } = require('./lib/core/symbols')
|
|
|
136
136
|
// in an older version of Node, it doesn't have any use without fetch.
|
|
137
137
|
module.exports.caches = new CacheStorage(kConstruct)
|
|
138
138
|
|
|
139
|
-
const { deleteCookie, getCookies, getSetCookies, setCookie } = require('./lib/web/cookies')
|
|
139
|
+
const { deleteCookie, getCookies, getSetCookies, setCookie, parseCookie } = require('./lib/web/cookies')
|
|
140
140
|
|
|
141
141
|
module.exports.deleteCookie = deleteCookie
|
|
142
142
|
module.exports.getCookies = getCookies
|
|
143
143
|
module.exports.getSetCookies = getSetCookies
|
|
144
144
|
module.exports.setCookie = setCookie
|
|
145
|
+
module.exports.parseCookie = parseCookie
|
|
145
146
|
|
|
146
147
|
const { parseMIMEType, serializeAMimeType } = require('./lib/web/fetch/data-url')
|
|
147
148
|
|
package/lib/api/api-request.js
CHANGED