undici 5.11.0 → 5.13.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.
- package/README.md +7 -5
- package/docs/api/Client.md +1 -0
- package/docs/api/Errors.md +1 -0
- package/docs/api/ProxyAgent.md +22 -0
- package/docs/assets/lifecycle-diagram.png +0 -0
- package/index-fetch.js +1 -3
- package/index.d.ts +24 -23
- package/index.js +3 -2
- package/lib/api/api-stream.js +1 -1
- package/lib/client.js +40 -23
- package/lib/core/connect.js +3 -1
- package/lib/core/errors.js +12 -1
- package/lib/core/symbols.js +3 -1
- package/lib/fetch/body.js +251 -181
- package/lib/fetch/constants.js +43 -1
- package/lib/fetch/dataURL.js +11 -72
- package/lib/fetch/file.js +59 -46
- package/lib/fetch/formdata.js +44 -96
- package/lib/fetch/headers.js +52 -100
- package/lib/fetch/index.js +146 -109
- package/lib/fetch/request.js +77 -105
- package/lib/fetch/response.js +50 -57
- package/lib/fetch/util.js +190 -31
- package/lib/fetch/webidl.js +101 -71
- package/lib/fileapi/encoding.js +286 -0
- package/lib/fileapi/filereader.js +314 -0
- package/lib/fileapi/progressevent.js +78 -0
- package/lib/fileapi/symbols.js +10 -0
- package/lib/fileapi/util.js +398 -0
- package/lib/handler/RedirectHandler.js +1 -0
- package/lib/llhttp/llhttp.wasm +0 -0
- package/lib/llhttp/llhttp.wasm.js +1 -1
- package/lib/llhttp/llhttp_simd.wasm +0 -0
- package/lib/llhttp/llhttp_simd.wasm.js +1 -1
- package/lib/mock/mock-utils.js +22 -4
- package/lib/proxy-agent.js +6 -1
- package/package.json +5 -4
- package/types/agent.d.ts +4 -5
- package/types/api.d.ts +1 -1
- package/types/balanced-pool.d.ts +3 -4
- package/types/client.d.ts +7 -5
- package/types/connector.d.ts +3 -3
- package/types/diagnostics-channel.d.ts +4 -4
- package/types/dispatcher.d.ts +23 -23
- package/types/errors.d.ts +9 -3
- package/types/fetch.d.ts +5 -1
- package/types/filereader.d.ts +54 -0
- package/types/global-dispatcher.d.ts +1 -1
- package/types/interceptors.d.ts +2 -2
- package/types/mock-agent.d.ts +3 -3
- package/types/mock-client.d.ts +4 -4
- package/types/mock-errors.d.ts +3 -3
- package/types/mock-interceptor.d.ts +1 -1
- package/types/mock-pool.d.ts +4 -4
- package/types/patch.d.ts +51 -0
- package/types/pool-stats.d.ts +2 -2
- package/types/pool.d.ts +5 -6
- package/types/proxy-agent.d.ts +7 -3
- package/types/readable.d.ts +1 -1
- package/types/webidl.d.ts +213 -0
package/README.md
CHANGED
|
@@ -178,10 +178,6 @@ Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method).
|
|
|
178
178
|
|
|
179
179
|
Only supported on Node 16.8+.
|
|
180
180
|
|
|
181
|
-
This is [experimental](https://nodejs.org/api/documentation.html#documentation_stability_index) and is not yet fully compliant with the Fetch Standard.
|
|
182
|
-
We plan to ship breaking changes to this feature until it is out of experimental.
|
|
183
|
-
Help us improve the test coverage by following instructions at [nodejs/undici/#951](https://github.com/nodejs/undici/issues/951).
|
|
184
|
-
|
|
185
181
|
Basic usage example:
|
|
186
182
|
|
|
187
183
|
```js
|
|
@@ -234,9 +230,15 @@ const data = {
|
|
|
234
230
|
},
|
|
235
231
|
}
|
|
236
232
|
|
|
237
|
-
await fetch('https://example.com', { body: data, method: 'POST' })
|
|
233
|
+
await fetch('https://example.com', { body: data, method: 'POST', duplex: 'half' })
|
|
238
234
|
```
|
|
239
235
|
|
|
236
|
+
#### `request.duplex`
|
|
237
|
+
|
|
238
|
+
- half
|
|
239
|
+
|
|
240
|
+
In this implementation of fetch, `request.duplex` must be set if `request.body` is `ReadableStream` or `Async Iterables`. And fetch requests are currently always be full duplex. More detail refer to [Fetch Standard.](https://fetch.spec.whatwg.org/#dom-requestinit-duplex)
|
|
241
|
+
|
|
240
242
|
#### `response.body`
|
|
241
243
|
|
|
242
244
|
Nodejs has two kinds of streams: [web streams](https://nodejs.org/dist/latest-v16.x/docs/api/webstreams.html), which follow the API of the WHATWG web standard found in browsers, and an older Node-specific [streams API](https://nodejs.org/api/stream.html). `response.body` returns a readable web stream. If you would prefer to work with a Node stream you can convert a web stream using `.fromWeb()`.
|
package/docs/api/Client.md
CHANGED
|
@@ -23,6 +23,7 @@ Returns: `Client`
|
|
|
23
23
|
* **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout 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
24
|
* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second.
|
|
25
25
|
* **maxHeaderSize** `number | null` (optional) - Default: `16384` - The maximum length of request headers in bytes. Defaults to 16KiB.
|
|
26
|
+
* **maxResponseSize** `number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable.
|
|
26
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.
|
|
27
28
|
* **connect** `ConnectOptions | Function | null` (optional) - Default: `null`.
|
|
28
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.
|
package/docs/api/Errors.md
CHANGED
|
@@ -19,6 +19,7 @@ import { errors } from 'undici'
|
|
|
19
19
|
| `RequestContentLengthMismatchError` | `UND_ERR_REQ_CONTENT_LENGTH_MISMATCH` | request body does not match content-length header |
|
|
20
20
|
| `ResponseContentLengthMismatchError` | `UND_ERR_RES_CONTENT_LENGTH_MISMATCH` | response body does not match content-length header |
|
|
21
21
|
| `InformationalError` | `UND_ERR_INFO` | expected error with reason |
|
|
22
|
+
| `ResponseExceededMaxSizeError` | `UND_ERR_RES_EXCEEDED_MAX_SIZE` | response body exceed the max size allowed |
|
|
22
23
|
|
|
23
24
|
### `SocketError`
|
|
24
25
|
|
package/docs/api/ProxyAgent.md
CHANGED
|
@@ -17,6 +17,8 @@ Returns: `ProxyAgent`
|
|
|
17
17
|
Extends: [`AgentOptions`](Agent.md#parameter-agentoptions)
|
|
18
18
|
|
|
19
19
|
* **uri** `string` (required) - It can be passed either by a string or a object containing `uri` as string.
|
|
20
|
+
* **token** `string` (optional) - It can be passed by a string of token for authentication.
|
|
21
|
+
* **auth** `string` (**deprecated**) - Use token.
|
|
20
22
|
|
|
21
23
|
Examples:
|
|
22
24
|
|
|
@@ -74,6 +76,26 @@ for await (const data of body) {
|
|
|
74
76
|
}
|
|
75
77
|
```
|
|
76
78
|
|
|
79
|
+
#### Example - Basic Proxy Request with authentication
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
import { setGlobalDispatcher, request, ProxyAgent } from 'undici';
|
|
83
|
+
|
|
84
|
+
const proxyAgent = new ProxyAgent({
|
|
85
|
+
uri: 'my.proxy.server',
|
|
86
|
+
token: 'Bearer xxxx'
|
|
87
|
+
});
|
|
88
|
+
setGlobalDispatcher(proxyAgent);
|
|
89
|
+
|
|
90
|
+
const { statusCode, body } = await request('http://localhost:3000/foo');
|
|
91
|
+
|
|
92
|
+
console.log('response received', statusCode); // response received 200
|
|
93
|
+
|
|
94
|
+
for await (const data of body) {
|
|
95
|
+
console.log('data', data.toString('utf8')); // data foo
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
77
99
|
### `ProxyAgent.close()`
|
|
78
100
|
|
|
79
101
|
Closes the proxy agent and waits for registered pools and clients to also close before resolving.
|
|
Binary file
|
package/index-fetch.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { getGlobalDispatcher } = require('./lib/global')
|
|
4
3
|
const fetchImpl = require('./lib/fetch').fetch
|
|
5
4
|
|
|
6
5
|
module.exports.fetch = async function fetch (resource) {
|
|
7
|
-
const dispatcher = (arguments[1] && arguments[1].dispatcher) || getGlobalDispatcher()
|
|
8
6
|
try {
|
|
9
|
-
return await fetchImpl
|
|
7
|
+
return await fetchImpl(...arguments)
|
|
10
8
|
} catch (err) {
|
|
11
9
|
Error.captureStackTrace(err, this)
|
|
12
10
|
throw err
|
package/index.d.ts
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
import Dispatcher
|
|
1
|
+
import Dispatcher from'./types/dispatcher'
|
|
2
2
|
import { setGlobalDispatcher, getGlobalDispatcher } from './types/global-dispatcher'
|
|
3
3
|
import { setGlobalOrigin, getGlobalOrigin } from './types/global-origin'
|
|
4
|
-
import Pool
|
|
4
|
+
import Pool from'./types/pool'
|
|
5
5
|
import { RedirectHandler, DecoratorHandler } from './types/handlers'
|
|
6
6
|
|
|
7
|
-
import BalancedPool
|
|
8
|
-
import Client
|
|
9
|
-
import buildConnector
|
|
10
|
-
import errors
|
|
11
|
-
import Agent
|
|
12
|
-
import MockClient
|
|
13
|
-
import MockPool
|
|
14
|
-
import MockAgent
|
|
15
|
-
import mockErrors
|
|
16
|
-
import ProxyAgent
|
|
7
|
+
import BalancedPool from './types/balanced-pool'
|
|
8
|
+
import Client from'./types/client'
|
|
9
|
+
import buildConnector from'./types/connector'
|
|
10
|
+
import errors from'./types/errors'
|
|
11
|
+
import Agent from'./types/agent'
|
|
12
|
+
import MockClient from'./types/mock-client'
|
|
13
|
+
import MockPool from'./types/mock-pool'
|
|
14
|
+
import MockAgent from'./types/mock-agent'
|
|
15
|
+
import mockErrors from'./types/mock-errors'
|
|
16
|
+
import ProxyAgent from'./types/proxy-agent'
|
|
17
17
|
import { request, pipeline, stream, connect, upgrade } from './types/api'
|
|
18
18
|
|
|
19
19
|
export * from './types/fetch'
|
|
20
20
|
export * from './types/file'
|
|
21
|
+
export * from './types/filereader'
|
|
21
22
|
export * from './types/formdata'
|
|
22
23
|
export * from './types/diagnostics-channel'
|
|
23
24
|
export { Interceptable } from './types/mock-interceptor'
|
|
@@ -26,16 +27,16 @@ export { Dispatcher, BalancedPool, Pool, Client, buildConnector, errors, Agent,
|
|
|
26
27
|
export default Undici
|
|
27
28
|
|
|
28
29
|
declare namespace Undici {
|
|
29
|
-
var Dispatcher: typeof import('./types/dispatcher')
|
|
30
|
-
var Pool: typeof import('./types/pool');
|
|
30
|
+
var Dispatcher: typeof import('./types/dispatcher').default
|
|
31
|
+
var Pool: typeof import('./types/pool').default;
|
|
31
32
|
var RedirectHandler: typeof import ('./types/handlers').RedirectHandler
|
|
32
33
|
var DecoratorHandler: typeof import ('./types/handlers').DecoratorHandler
|
|
33
34
|
var createRedirectInterceptor: typeof import ('./types/interceptors').createRedirectInterceptor
|
|
34
|
-
var BalancedPool: typeof import('./types/balanced-pool');
|
|
35
|
-
var Client: typeof import('./types/client');
|
|
36
|
-
var buildConnector: typeof import('./types/connector');
|
|
37
|
-
var errors: typeof import('./types/errors');
|
|
38
|
-
var Agent: typeof import('./types/agent');
|
|
35
|
+
var BalancedPool: typeof import('./types/balanced-pool').default;
|
|
36
|
+
var Client: typeof import('./types/client').default;
|
|
37
|
+
var buildConnector: typeof import('./types/connector').default;
|
|
38
|
+
var errors: typeof import('./types/errors').default;
|
|
39
|
+
var Agent: typeof import('./types/agent').default;
|
|
39
40
|
var setGlobalDispatcher: typeof import('./types/global-dispatcher').setGlobalDispatcher;
|
|
40
41
|
var getGlobalDispatcher: typeof import('./types/global-dispatcher').getGlobalDispatcher;
|
|
41
42
|
var request: typeof import('./types/api').request;
|
|
@@ -43,9 +44,9 @@ declare namespace Undici {
|
|
|
43
44
|
var pipeline: typeof import('./types/api').pipeline;
|
|
44
45
|
var connect: typeof import('./types/api').connect;
|
|
45
46
|
var upgrade: typeof import('./types/api').upgrade;
|
|
46
|
-
var MockClient: typeof import('./types/mock-client');
|
|
47
|
-
var MockPool: typeof import('./types/mock-pool');
|
|
48
|
-
var MockAgent: typeof import('./types/mock-agent');
|
|
49
|
-
var mockErrors: typeof import('./types/mock-errors');
|
|
47
|
+
var MockClient: typeof import('./types/mock-client').default;
|
|
48
|
+
var MockPool: typeof import('./types/mock-pool').default;
|
|
49
|
+
var MockAgent: typeof import('./types/mock-agent').default;
|
|
50
|
+
var mockErrors: typeof import('./types/mock-errors').default;
|
|
50
51
|
var fetch: typeof import('./types/fetch').fetch;
|
|
51
52
|
}
|
package/index.js
CHANGED
|
@@ -98,9 +98,9 @@ if (nodeMajor > 16 || (nodeMajor === 16 && nodeMinor >= 8)) {
|
|
|
98
98
|
if (!fetchImpl) {
|
|
99
99
|
fetchImpl = require('./lib/fetch').fetch
|
|
100
100
|
}
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
try {
|
|
103
|
-
return await fetchImpl
|
|
103
|
+
return await fetchImpl(...arguments)
|
|
104
104
|
} catch (err) {
|
|
105
105
|
Error.captureStackTrace(err, this)
|
|
106
106
|
throw err
|
|
@@ -111,6 +111,7 @@ if (nodeMajor > 16 || (nodeMajor === 16 && nodeMinor >= 8)) {
|
|
|
111
111
|
module.exports.Request = require('./lib/fetch/request').Request
|
|
112
112
|
module.exports.FormData = require('./lib/fetch/formdata').FormData
|
|
113
113
|
module.exports.File = require('./lib/fetch/file').File
|
|
114
|
+
module.exports.FileReader = require('./lib/fileapi/filereader').FileReader
|
|
114
115
|
|
|
115
116
|
const { setGlobalOrigin, getGlobalOrigin } = require('./lib/fetch/global')
|
|
116
117
|
|
package/lib/api/api-stream.js
CHANGED
|
@@ -106,7 +106,7 @@ class StreamHandler extends AsyncResource {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
res.on('drain', resume)
|
|
109
|
-
// TODO: Avoid finished. It registers an
|
|
109
|
+
// TODO: Avoid finished. It registers an unnecessary amount of listeners.
|
|
110
110
|
finished(res, { readable: false }, (err) => {
|
|
111
111
|
const { callback, res, opaque, trailers, abort } = this
|
|
112
112
|
|
package/lib/client.js
CHANGED
|
@@ -17,7 +17,8 @@ const {
|
|
|
17
17
|
SocketError,
|
|
18
18
|
InformationalError,
|
|
19
19
|
BodyTimeoutError,
|
|
20
|
-
HTTPParserError
|
|
20
|
+
HTTPParserError,
|
|
21
|
+
ResponseExceededMaxSizeError
|
|
21
22
|
} = require('./core/errors')
|
|
22
23
|
const buildConnector = require('./core/connect')
|
|
23
24
|
const {
|
|
@@ -60,7 +61,9 @@ const {
|
|
|
60
61
|
kClose,
|
|
61
62
|
kDestroy,
|
|
62
63
|
kDispatch,
|
|
63
|
-
kInterceptors
|
|
64
|
+
kInterceptors,
|
|
65
|
+
kLocalAddress,
|
|
66
|
+
kMaxResponseSize
|
|
64
67
|
} = require('./core/symbols')
|
|
65
68
|
|
|
66
69
|
const kClosedResolve = Symbol('kClosedResolve')
|
|
@@ -102,7 +105,9 @@ class Client extends DispatcherBase {
|
|
|
102
105
|
maxCachedSessions,
|
|
103
106
|
maxRedirections,
|
|
104
107
|
connect,
|
|
105
|
-
maxRequestsPerClient
|
|
108
|
+
maxRequestsPerClient,
|
|
109
|
+
localAddress,
|
|
110
|
+
maxResponseSize
|
|
106
111
|
} = {}) {
|
|
107
112
|
super()
|
|
108
113
|
|
|
@@ -170,6 +175,14 @@ class Client extends DispatcherBase {
|
|
|
170
175
|
throw new InvalidArgumentError('maxRequestsPerClient must be a positive number')
|
|
171
176
|
}
|
|
172
177
|
|
|
178
|
+
if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) {
|
|
179
|
+
throw new InvalidArgumentError('localAddress must be valid string IP address')
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) {
|
|
183
|
+
throw new InvalidArgumentError('maxResponseSize must be a positive number')
|
|
184
|
+
}
|
|
185
|
+
|
|
173
186
|
if (typeof connect !== 'function') {
|
|
174
187
|
connect = buildConnector({
|
|
175
188
|
...tls,
|
|
@@ -193,6 +206,7 @@ class Client extends DispatcherBase {
|
|
|
193
206
|
this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 1e3 : keepAliveTimeoutThreshold
|
|
194
207
|
this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout]
|
|
195
208
|
this[kServerName] = null
|
|
209
|
+
this[kLocalAddress] = localAddress != null ? localAddress : null
|
|
196
210
|
this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming
|
|
197
211
|
this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming
|
|
198
212
|
this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n`
|
|
@@ -202,6 +216,7 @@ class Client extends DispatcherBase {
|
|
|
202
216
|
this[kMaxRedirections] = maxRedirections
|
|
203
217
|
this[kMaxRequests] = maxRequestsPerClient
|
|
204
218
|
this[kClosedResolve] = null
|
|
219
|
+
this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1
|
|
205
220
|
|
|
206
221
|
// kQueue is built up of 3 sections separated by
|
|
207
222
|
// the kRunningIdx and kPendingIdx indices.
|
|
@@ -426,6 +441,7 @@ class Parser {
|
|
|
426
441
|
|
|
427
442
|
this.keepAlive = ''
|
|
428
443
|
this.contentLength = ''
|
|
444
|
+
this.maxResponseSize = client[kMaxResponseSize]
|
|
429
445
|
}
|
|
430
446
|
|
|
431
447
|
setTimeout (value, type) {
|
|
@@ -542,19 +558,6 @@ class Parser {
|
|
|
542
558
|
}
|
|
543
559
|
}
|
|
544
560
|
|
|
545
|
-
finish () {
|
|
546
|
-
try {
|
|
547
|
-
try {
|
|
548
|
-
currentParser = this
|
|
549
|
-
} finally {
|
|
550
|
-
currentParser = null
|
|
551
|
-
}
|
|
552
|
-
} catch (err) {
|
|
553
|
-
/* istanbul ignore next: difficult to make a test case for */
|
|
554
|
-
util.destroy(this.socket, err)
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
561
|
destroy () {
|
|
559
562
|
assert(this.ptr != null)
|
|
560
563
|
assert(currentParser == null)
|
|
@@ -783,7 +786,7 @@ class Parser {
|
|
|
783
786
|
}
|
|
784
787
|
|
|
785
788
|
onBody (buf) {
|
|
786
|
-
const { client, socket, statusCode } = this
|
|
789
|
+
const { client, socket, statusCode, maxResponseSize } = this
|
|
787
790
|
|
|
788
791
|
if (socket.destroyed) {
|
|
789
792
|
return -1
|
|
@@ -802,6 +805,11 @@ class Parser {
|
|
|
802
805
|
|
|
803
806
|
assert(statusCode >= 200)
|
|
804
807
|
|
|
808
|
+
if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) {
|
|
809
|
+
util.destroy(socket, new ResponseExceededMaxSizeError())
|
|
810
|
+
return -1
|
|
811
|
+
}
|
|
812
|
+
|
|
805
813
|
this.bytesRead += buf.length
|
|
806
814
|
|
|
807
815
|
try {
|
|
@@ -917,7 +925,7 @@ function onSocketError (err) {
|
|
|
917
925
|
// to the user.
|
|
918
926
|
if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
|
|
919
927
|
// We treat all incoming data so for as a valid response.
|
|
920
|
-
parser.
|
|
928
|
+
parser.onMessageComplete()
|
|
921
929
|
return
|
|
922
930
|
}
|
|
923
931
|
|
|
@@ -951,7 +959,7 @@ function onSocketEnd () {
|
|
|
951
959
|
|
|
952
960
|
if (parser.statusCode && !parser.shouldKeepAlive) {
|
|
953
961
|
// We treat all incoming data so far as a valid response.
|
|
954
|
-
parser.
|
|
962
|
+
parser.onMessageComplete()
|
|
955
963
|
return
|
|
956
964
|
}
|
|
957
965
|
|
|
@@ -961,6 +969,11 @@ function onSocketEnd () {
|
|
|
961
969
|
function onSocketClose () {
|
|
962
970
|
const { [kClient]: client } = this
|
|
963
971
|
|
|
972
|
+
if (!this[kError] && this[kParser].statusCode && !this[kParser].shouldKeepAlive) {
|
|
973
|
+
// We treat all incoming data so far as a valid response.
|
|
974
|
+
this[kParser].onMessageComplete()
|
|
975
|
+
}
|
|
976
|
+
|
|
964
977
|
this[kParser].destroy()
|
|
965
978
|
this[kParser] = null
|
|
966
979
|
|
|
@@ -1020,7 +1033,8 @@ async function connect (client) {
|
|
|
1020
1033
|
hostname,
|
|
1021
1034
|
protocol,
|
|
1022
1035
|
port,
|
|
1023
|
-
servername: client[kServerName]
|
|
1036
|
+
servername: client[kServerName],
|
|
1037
|
+
localAddress: client[kLocalAddress]
|
|
1024
1038
|
},
|
|
1025
1039
|
connector: client[kConnector]
|
|
1026
1040
|
})
|
|
@@ -1033,7 +1047,8 @@ async function connect (client) {
|
|
|
1033
1047
|
hostname,
|
|
1034
1048
|
protocol,
|
|
1035
1049
|
port,
|
|
1036
|
-
servername: client[kServerName]
|
|
1050
|
+
servername: client[kServerName],
|
|
1051
|
+
localAddress: client[kLocalAddress]
|
|
1037
1052
|
}, (err, socket) => {
|
|
1038
1053
|
if (err) {
|
|
1039
1054
|
reject(err)
|
|
@@ -1076,7 +1091,8 @@ async function connect (client) {
|
|
|
1076
1091
|
hostname,
|
|
1077
1092
|
protocol,
|
|
1078
1093
|
port,
|
|
1079
|
-
servername: client[kServerName]
|
|
1094
|
+
servername: client[kServerName],
|
|
1095
|
+
localAddress: client[kLocalAddress]
|
|
1080
1096
|
},
|
|
1081
1097
|
connector: client[kConnector],
|
|
1082
1098
|
socket
|
|
@@ -1093,7 +1109,8 @@ async function connect (client) {
|
|
|
1093
1109
|
hostname,
|
|
1094
1110
|
protocol,
|
|
1095
1111
|
port,
|
|
1096
|
-
servername: client[kServerName]
|
|
1112
|
+
servername: client[kServerName],
|
|
1113
|
+
localAddress: client[kLocalAddress]
|
|
1097
1114
|
},
|
|
1098
1115
|
connector: client[kConnector],
|
|
1099
1116
|
error: err
|
package/lib/core/connect.js
CHANGED
|
@@ -21,7 +21,7 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
|
|
|
21
21
|
timeout = timeout == null ? 10e3 : timeout
|
|
22
22
|
maxCachedSessions = maxCachedSessions == null ? 100 : maxCachedSessions
|
|
23
23
|
|
|
24
|
-
return function connect ({ hostname, host, protocol, port, servername, httpSocket }, callback) {
|
|
24
|
+
return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) {
|
|
25
25
|
let socket
|
|
26
26
|
if (protocol === 'https:') {
|
|
27
27
|
if (!tls) {
|
|
@@ -39,6 +39,7 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
|
|
|
39
39
|
...options,
|
|
40
40
|
servername,
|
|
41
41
|
session,
|
|
42
|
+
localAddress,
|
|
42
43
|
socket: httpSocket, // upgrade socket connection
|
|
43
44
|
port: port || 443,
|
|
44
45
|
host: hostname
|
|
@@ -70,6 +71,7 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
|
|
|
70
71
|
socket = net.connect({
|
|
71
72
|
highWaterMark: 64 * 1024, // Same as nodejs fs streams.
|
|
72
73
|
...options,
|
|
74
|
+
localAddress,
|
|
73
75
|
port: port || 80,
|
|
74
76
|
host: hostname
|
|
75
77
|
})
|
package/lib/core/errors.js
CHANGED
|
@@ -183,6 +183,16 @@ class HTTPParserError extends Error {
|
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
class ResponseExceededMaxSizeError extends UndiciError {
|
|
187
|
+
constructor (message) {
|
|
188
|
+
super(message)
|
|
189
|
+
Error.captureStackTrace(this, ResponseExceededMaxSizeError)
|
|
190
|
+
this.name = 'ResponseExceededMaxSizeError'
|
|
191
|
+
this.message = message || 'Response content exceeded max size'
|
|
192
|
+
this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE'
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
186
196
|
module.exports = {
|
|
187
197
|
HTTPParserError,
|
|
188
198
|
UndiciError,
|
|
@@ -201,5 +211,6 @@ module.exports = {
|
|
|
201
211
|
SocketError,
|
|
202
212
|
NotSupportedError,
|
|
203
213
|
ResponseContentLengthMismatchError,
|
|
204
|
-
BalancedPoolMissingUpstreamError
|
|
214
|
+
BalancedPoolMissingUpstreamError,
|
|
215
|
+
ResponseExceededMaxSizeError
|
|
205
216
|
}
|
package/lib/core/symbols.js
CHANGED
|
@@ -17,6 +17,7 @@ module.exports = {
|
|
|
17
17
|
kHeadersTimeout: Symbol('headers timeout'),
|
|
18
18
|
kBodyTimeout: Symbol('body timeout'),
|
|
19
19
|
kServerName: Symbol('server name'),
|
|
20
|
+
kLocalAddress: Symbol('local address'),
|
|
20
21
|
kHost: Symbol('host'),
|
|
21
22
|
kNoRef: Symbol('no ref'),
|
|
22
23
|
kBodyUsed: Symbol('used'),
|
|
@@ -49,5 +50,6 @@ module.exports = {
|
|
|
49
50
|
kMaxRequests: Symbol('maxRequestsPerClient'),
|
|
50
51
|
kProxy: Symbol('proxy agent options'),
|
|
51
52
|
kCounter: Symbol('socket request counter'),
|
|
52
|
-
kInterceptors: Symbol('dispatch interceptors')
|
|
53
|
+
kInterceptors: Symbol('dispatch interceptors'),
|
|
54
|
+
kMaxResponseSize: Symbol('max response size')
|
|
53
55
|
}
|