undici 4.8.0 → 4.9.1

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.
@@ -0,0 +1,100 @@
1
+ # Class: ProxyAgent
2
+
3
+ Extends: `undici.Dispatcher`
4
+
5
+ A Proxy Agent class that implements the Agent API. It allows the connection through proxy in a simple way.
6
+
7
+ ## `new ProxyAgent([options])`
8
+
9
+ Arguments:
10
+
11
+ * **options** `ProxyAgentOptions` (required) - It extends the `Agent` options.
12
+
13
+ Returns: `ProxyAgent`
14
+
15
+ ### Parameter: `ProxyAgentOptions`
16
+
17
+ Extends: [`AgentOptions`](docs/api/Agent.md#parameter-agentoptions)
18
+
19
+ * **uri** `string` (required) - It can be passed either by a string or a object containing `uri` as string.
20
+
21
+ Examples:
22
+
23
+ ```js
24
+ import { ProxyAgent } from 'undici'
25
+
26
+ const proxyAgent = new ProxyAgent('my.proxy.server')
27
+ // or
28
+ const proxyAgent = new ProxyAgent({ uri: 'my.proxy.server' })
29
+ ```
30
+
31
+ #### Example - Basic ProxyAgent instantiation
32
+
33
+ This will instantiate the ProxyAgent. It will not do anything until registered as the agent to use with requests.
34
+
35
+ ```js
36
+ import { ProxyAgent } from 'undici'
37
+
38
+ const proxyAgent = new ProxyAgent('my.proxy.server')
39
+ ```
40
+
41
+ #### Example - Basic Proxy Request with global agent dispatcher
42
+
43
+ ```js
44
+ import { setGlobalDispatcher, request, ProxyAgent } from 'undici'
45
+
46
+ const proxyAgent = new ProxyAgent('my.proxy.server')
47
+ setGlobalDispatcher(proxyAgent)
48
+
49
+ const { statusCode, body } = await request('http://localhost:3000/foo')
50
+
51
+ console.log('response received', statusCode) // response received 200
52
+
53
+ for await (const data of body) {
54
+ console.log('data', data.toString('utf8')) // data foo
55
+ }
56
+ ```
57
+
58
+ #### Example - Basic Proxy Request with local agent dispatcher
59
+
60
+ ```js
61
+ import { ProxyAgent, request } from 'undici'
62
+
63
+ const proxyAgent = new ProxyAgent('my.proxy.server')
64
+
65
+ const {
66
+ statusCode,
67
+ body
68
+ } = await request('http://localhost:3000/foo', { dispatcher: proxyAgent })
69
+
70
+ console.log('response received', statusCode) // response received 200
71
+
72
+ for await (const data of body) {
73
+ console.log('data', data.toString('utf8')) // data foo
74
+ }
75
+ ```
76
+
77
+ ### `ProxyAgent.close()`
78
+
79
+ Closes the proxy agent and waits for registered pools and clients to also close before resolving.
80
+
81
+ Returns: `Promise<void>`
82
+
83
+ #### Example - clean up after tests are complete
84
+
85
+ ```js
86
+ import { ProxyAgent, setGlobalDispatcher } from 'undici'
87
+
88
+ const proxyAgent = new ProxyAgent('my.proxy.server')
89
+ setGlobalDispatcher(proxyAgent)
90
+
91
+ await proxyAgent.close()
92
+ ```
93
+
94
+ ### `ProxyAgent.dispatch(options, handlers)`
95
+
96
+ Implements [`Agent.dispatch(options, handlers)`](docs/api/Agent.md#parameter-agentdispatchoptions).
97
+
98
+ ### `ProxyAgent.request(options[, callback])`
99
+
100
+ See [`Dispatcher.request(options [, callback])`](docs/api/Dispatcher.md#clientrequestoptions--callback).
@@ -1,6 +1,9 @@
1
1
  # Connecting through a proxy
2
2
 
3
- Connecting through a proxy is possible by properly configuring the `Client` or `Pool` constructor and request.
3
+ Connecting through a proxy is possible by:
4
+
5
+ - Using [AgentProxy](docs/api/ProxyAgent.md).
6
+ - Configuring `Client` or `Pool` constructor.
4
7
 
5
8
  The proxy url should be passed to the `Client` or `Pool` constructor, while the upstream server url
6
9
  should be added to every request call in the `path`.
package/index.d.ts CHANGED
@@ -10,13 +10,14 @@ import MockClient = require('./types/mock-client')
10
10
  import MockPool = require('./types/mock-pool')
11
11
  import MockAgent = require('./types/mock-agent')
12
12
  import mockErrors = require('./types/mock-errors')
13
+ import ProxyAgent from './types/proxy-agent'
13
14
  import { request, pipeline, stream, connect, upgrade } from './types/api'
14
15
 
15
16
  export * from './types/fetch'
16
17
  export * from './types/file'
17
18
  export * from './types/formdata'
18
19
 
19
- export { Dispatcher, BalancedPool, Pool, Client, buildConnector, errors, Agent, request, stream, pipeline, connect, upgrade, setGlobalDispatcher, getGlobalDispatcher, MockClient, MockPool, MockAgent, mockErrors }
20
+ export { Dispatcher, BalancedPool, Pool, Client, buildConnector, errors, Agent, request, stream, pipeline, connect, upgrade, setGlobalDispatcher, getGlobalDispatcher, MockClient, MockPool, MockAgent, mockErrors, ProxyAgent }
20
21
  export default Undici
21
22
 
22
23
  declare function Undici(url: string, opts: Pool.Options): Pool
package/index.js CHANGED
@@ -14,6 +14,7 @@ const MockClient = require('./lib/mock/mock-client')
14
14
  const MockAgent = require('./lib/mock/mock-agent')
15
15
  const MockPool = require('./lib/mock/mock-pool')
16
16
  const mockErrors = require('./lib/mock/mock-errors')
17
+ const ProxyAgent = require('./lib/proxy-agent')
17
18
 
18
19
  const nodeVersion = process.versions.node.split('.')
19
20
  const nodeMajor = Number(nodeVersion[0])
@@ -26,6 +27,7 @@ module.exports.Client = Client
26
27
  module.exports.Pool = Pool
27
28
  module.exports.BalancedPool = BalancedPool
28
29
  module.exports.Agent = Agent
30
+ module.exports.ProxyAgent = ProxyAgent
29
31
 
30
32
  module.exports.buildConnector = buildConnector
31
33
  module.exports.errors = errors
@@ -91,8 +93,11 @@ module.exports.setGlobalDispatcher = setGlobalDispatcher
91
93
  module.exports.getGlobalDispatcher = getGlobalDispatcher
92
94
 
93
95
  if (nodeMajor > 16 || (nodeMajor === 16 && nodeMinor >= 5)) {
94
- const fetchImpl = require('./lib/fetch')
96
+ let fetchImpl = null
95
97
  module.exports.fetch = async function fetch (resource, init) {
98
+ if (!fetchImpl) {
99
+ fetchImpl = require('./lib/fetch')
100
+ }
96
101
  const dispatcher = getGlobalDispatcher()
97
102
  return fetchImpl.call(dispatcher, resource, init)
98
103
  }
package/lib/client.js CHANGED
@@ -62,7 +62,9 @@ const {
62
62
  kBodyTimeout,
63
63
  kStrictContentLength,
64
64
  kConnector,
65
- kMaxRedirections
65
+ kMaxRedirections,
66
+ kMaxRequests,
67
+ kCounter
66
68
  } = require('./core/symbols')
67
69
 
68
70
  const channels = {}
@@ -100,7 +102,8 @@ class Client extends Dispatcher {
100
102
  strictContentLength,
101
103
  maxCachedSessions,
102
104
  maxRedirections,
103
- connect
105
+ connect,
106
+ maxRequestsPerClient
104
107
  } = {}) {
105
108
  super()
106
109
 
@@ -164,6 +167,10 @@ class Client extends Dispatcher {
164
167
  throw new InvalidArgumentError('maxRedirections must be a positive number')
165
168
  }
166
169
 
170
+ if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) {
171
+ throw new InvalidArgumentError('maxRequestsPerClient must be a positive number')
172
+ }
173
+
167
174
  if (typeof connect !== 'function') {
168
175
  connect = buildConnector({
169
176
  ...tls,
@@ -194,6 +201,7 @@ class Client extends Dispatcher {
194
201
  this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 30e3
195
202
  this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength
196
203
  this[kMaxRedirections] = maxRedirections
204
+ this[kMaxRequests] = maxRequestsPerClient
197
205
 
198
206
  // kQueue is built up of 3 sections separated by
199
207
  // the kRunningIdx and kPendingIdx indices.
@@ -397,76 +405,77 @@ class Client extends Dispatcher {
397
405
  }
398
406
  }
399
407
 
400
- const { resolve } = require('path')
401
- const { readFileSync } = require('fs')
402
408
  const constants = require('./llhttp/constants')
403
409
  const EMPTY_BUF = Buffer.alloc(0)
404
410
 
411
+ let llhttpPromise
405
412
  let llhttpInstance
406
- function lazyllhttp () {
407
- if (!llhttpInstance) {
408
- let mod
409
- try {
410
- mod = new WebAssembly.Module(readFileSync(resolve(__dirname, './llhttp/llhttp_simd.wasm')))
411
- } catch (e) {
412
- /* istanbul ignore next */
413
+ async function lazyllhttp () {
414
+ const { resolve } = require('path')
415
+ const { readFile } = require('fs').promises
413
416
 
414
- // We could check if the error was caused by the simd option not
415
- // being enabled, but the occurring of this other error
416
- // * https://github.com/emscripten-core/emscripten/issues/11495
417
- // got me to remove that check to avoid breaking Node 12.
418
- mod = new WebAssembly.Module(readFileSync(resolve(__dirname, './llhttp/llhttp.wasm')))
419
- }
417
+ let mod
418
+ try {
419
+ mod = await WebAssembly.compile(await readFile(resolve(__dirname, './llhttp/llhttp_simd.wasm')))
420
+ } catch (e) {
421
+ /* istanbul ignore next */
420
422
 
421
- llhttpInstance = new WebAssembly.Instance(mod, {
422
- env: {
423
- /* eslint-disable camelcase */
423
+ // We could check if the error was caused by the simd option not
424
+ // being enabled, but the occurring of this other error
425
+ // * https://github.com/emscripten-core/emscripten/issues/11495
426
+ // got me to remove that check to avoid breaking Node 12.
427
+ mod = await WebAssembly.compile(await readFile(resolve(__dirname, './llhttp/llhttp.wasm')))
428
+ }
424
429
 
425
- wasm_on_url: (p, at, len) => {
426
- /* istanbul ignore next */
427
- return 0
428
- },
429
- wasm_on_status: (p, at, len) => {
430
- assert.strictEqual(currentParser.ptr, p)
431
- const start = at - currentBufferPtr
432
- const end = start + len
433
- return currentParser.onStatus(currentBufferRef.slice(start, end)) || 0
434
- },
435
- wasm_on_message_begin: (p) => {
436
- assert.strictEqual(currentParser.ptr, p)
437
- return currentParser.onMessageBegin() || 0
438
- },
439
- wasm_on_header_field: (p, at, len) => {
440
- assert.strictEqual(currentParser.ptr, p)
441
- const start = at - currentBufferPtr
442
- const end = start + len
443
- return currentParser.onHeaderField(currentBufferRef.slice(start, end)) || 0
444
- },
445
- wasm_on_header_value: (p, at, len) => {
446
- assert.strictEqual(currentParser.ptr, p)
447
- const start = at - currentBufferPtr
448
- const end = start + len
449
- return currentParser.onHeaderValue(currentBufferRef.slice(start, end)) || 0
450
- },
451
- wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => {
452
- assert.strictEqual(currentParser.ptr, p)
453
- return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0
454
- },
455
- wasm_on_body: (p, at, len) => {
456
- assert.strictEqual(currentParser.ptr, p)
457
- const start = at - currentBufferPtr
458
- const end = start + len
459
- return currentParser.onBody(currentBufferRef.slice(start, end)) || 0
460
- },
461
- wasm_on_message_complete: (p) => {
462
- assert.strictEqual(currentParser.ptr, p)
463
- return currentParser.onMessageComplete() || 0
464
- }
430
+ llhttpInstance = new WebAssembly.Instance(mod, {
431
+ env: {
432
+ /* eslint-disable camelcase */
465
433
 
466
- /* eslint-enable camelcase */
434
+ wasm_on_url: (p, at, len) => {
435
+ /* istanbul ignore next */
436
+ return 0
437
+ },
438
+ wasm_on_status: (p, at, len) => {
439
+ assert.strictEqual(currentParser.ptr, p)
440
+ const start = at - currentBufferPtr
441
+ const end = start + len
442
+ return currentParser.onStatus(currentBufferRef.slice(start, end)) || 0
443
+ },
444
+ wasm_on_message_begin: (p) => {
445
+ assert.strictEqual(currentParser.ptr, p)
446
+ return currentParser.onMessageBegin() || 0
447
+ },
448
+ wasm_on_header_field: (p, at, len) => {
449
+ assert.strictEqual(currentParser.ptr, p)
450
+ const start = at - currentBufferPtr
451
+ const end = start + len
452
+ return currentParser.onHeaderField(currentBufferRef.slice(start, end)) || 0
453
+ },
454
+ wasm_on_header_value: (p, at, len) => {
455
+ assert.strictEqual(currentParser.ptr, p)
456
+ const start = at - currentBufferPtr
457
+ const end = start + len
458
+ return currentParser.onHeaderValue(currentBufferRef.slice(start, end)) || 0
459
+ },
460
+ wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => {
461
+ assert.strictEqual(currentParser.ptr, p)
462
+ return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0
463
+ },
464
+ wasm_on_body: (p, at, len) => {
465
+ assert.strictEqual(currentParser.ptr, p)
466
+ const start = at - currentBufferPtr
467
+ const end = start + len
468
+ return currentParser.onBody(currentBufferRef.slice(start, end)) || 0
469
+ },
470
+ wasm_on_message_complete: (p) => {
471
+ assert.strictEqual(currentParser.ptr, p)
472
+ return currentParser.onMessageComplete() || 0
467
473
  }
468
- })
469
- }
474
+
475
+ /* eslint-enable camelcase */
476
+ }
477
+ })
478
+
470
479
  return llhttpInstance
471
480
  }
472
481
 
@@ -480,10 +489,10 @@ const TIMEOUT_BODY = 2
480
489
  const TIMEOUT_IDLE = 3
481
490
 
482
491
  class Parser {
483
- constructor (client, socket) {
492
+ constructor (client, socket, { exports }) {
484
493
  assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0)
485
494
 
486
- this.llhttp = lazyllhttp().exports
495
+ this.llhttp = exports
487
496
  this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE)
488
497
  this.client = client
489
498
  this.socket = socket
@@ -1096,7 +1105,7 @@ function onSocketClose () {
1096
1105
  resume(client)
1097
1106
  }
1098
1107
 
1099
- function connect (client) {
1108
+ async function connect (client) {
1100
1109
  assert(!client[kConnecting])
1101
1110
  assert(!client[kSocket])
1102
1111
 
@@ -1128,78 +1137,98 @@ function connect (client) {
1128
1137
  })
1129
1138
  }
1130
1139
 
1131
- client[kConnector]({
1132
- host,
1133
- hostname,
1134
- protocol,
1135
- port,
1136
- servername: client[kServerName]
1137
- }, function (err, socket) {
1138
- client[kConnecting] = false
1139
-
1140
- if (err) {
1141
- if (channels.connectError.hasSubscribers) {
1142
- channels.connectError.publish({
1143
- connectParams: {
1144
- host,
1145
- hostname,
1146
- protocol,
1147
- port,
1148
- servername: client[kServerName]
1149
- },
1150
- connector: client[kConnector],
1151
- error: err
1152
- })
1140
+ try {
1141
+ if (!llhttpInstance) {
1142
+ if (!llhttpPromise) {
1143
+ llhttpPromise = lazyllhttp()
1153
1144
  }
1145
+ await llhttpPromise
1146
+ assert(llhttpInstance)
1147
+ llhttpPromise = null
1148
+ }
1154
1149
 
1155
- if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') {
1156
- assert(client[kRunning] === 0)
1157
- while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) {
1158
- const request = client[kQueue][client[kPendingIdx]++]
1159
- errorRequest(client, request, err)
1150
+ const socket = await new Promise((resolve, reject) => {
1151
+ client[kConnector]({
1152
+ host,
1153
+ hostname,
1154
+ protocol,
1155
+ port,
1156
+ servername: client[kServerName]
1157
+ }, (err, socket) => {
1158
+ if (err) {
1159
+ reject(err)
1160
+ } else {
1161
+ resolve(socket)
1160
1162
  }
1161
- } else {
1162
- onError(client, err)
1163
- }
1163
+ })
1164
+ })
1164
1165
 
1165
- client.emit('connectionError', client[kUrl], [client], err)
1166
- } else {
1167
- assert(socket)
1166
+ client[kConnecting] = false
1168
1167
 
1169
- client[kSocket] = socket
1168
+ assert(socket)
1170
1169
 
1171
- socket[kNoRef] = false
1172
- socket[kWriting] = false
1173
- socket[kReset] = false
1174
- socket[kBlocking] = false
1175
- socket[kError] = null
1176
- socket[kParser] = new Parser(client, socket)
1177
- socket[kClient] = client
1178
- socket
1179
- .on('error', onSocketError)
1180
- .on('readable', onSocketReadable)
1181
- .on('end', onSocketEnd)
1182
- .on('close', onSocketClose)
1183
-
1184
- if (channels.connected.hasSubscribers) {
1185
- channels.connected.publish({
1186
- connectParams: {
1187
- host,
1188
- hostname,
1189
- protocol,
1190
- port,
1191
- servername: client[kServerName]
1192
- },
1193
- connector: client[kConnector],
1194
- socket
1195
- })
1196
- }
1170
+ client[kSocket] = socket
1197
1171
 
1198
- client.emit('connect', client[kUrl], [client])
1172
+ socket[kNoRef] = false
1173
+ socket[kWriting] = false
1174
+ socket[kReset] = false
1175
+ socket[kBlocking] = false
1176
+ socket[kError] = null
1177
+ socket[kParser] = new Parser(client, socket, llhttpInstance)
1178
+ socket[kClient] = client
1179
+ socket[kCounter] = 0
1180
+ socket[kMaxRequests] = client[kMaxRequests]
1181
+ socket
1182
+ .on('error', onSocketError)
1183
+ .on('readable', onSocketReadable)
1184
+ .on('end', onSocketEnd)
1185
+ .on('close', onSocketClose)
1186
+
1187
+ if (channels.connected.hasSubscribers) {
1188
+ channels.connected.publish({
1189
+ connectParams: {
1190
+ host,
1191
+ hostname,
1192
+ protocol,
1193
+ port,
1194
+ servername: client[kServerName]
1195
+ },
1196
+ connector: client[kConnector],
1197
+ socket
1198
+ })
1199
1199
  }
1200
+ client.emit('connect', client[kUrl], [client])
1201
+ } catch (err) {
1202
+ client[kConnecting] = false
1200
1203
 
1201
- resume(client)
1202
- })
1204
+ if (channels.connectError.hasSubscribers) {
1205
+ channels.connectError.publish({
1206
+ connectParams: {
1207
+ host,
1208
+ hostname,
1209
+ protocol,
1210
+ port,
1211
+ servername: client[kServerName]
1212
+ },
1213
+ connector: client[kConnector],
1214
+ error: err
1215
+ })
1216
+ }
1217
+
1218
+ if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') {
1219
+ assert(client[kRunning] === 0)
1220
+ while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) {
1221
+ const request = client[kQueue][client[kPendingIdx]++]
1222
+ errorRequest(client, request, err)
1223
+ }
1224
+ } else {
1225
+ onError(client, err)
1226
+ }
1227
+
1228
+ client.emit('connectionError', client[kUrl], [client], err)
1229
+ }
1230
+
1231
+ resume(client)
1203
1232
  }
1204
1233
 
1205
1234
  function emitDrain (client) {
@@ -1213,6 +1242,7 @@ function resume (client, sync) {
1213
1242
  }
1214
1243
 
1215
1244
  client[kResuming] = 2
1245
+
1216
1246
  _resume(client, sync)
1217
1247
  client[kResuming] = 0
1218
1248
 
@@ -1445,6 +1475,10 @@ function write (client, request) {
1445
1475
  socket[kReset] = true
1446
1476
  }
1447
1477
 
1478
+ if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) {
1479
+ socket[kReset] = true
1480
+ }
1481
+
1448
1482
  if (blocking) {
1449
1483
  socket[kBlocking] = true
1450
1484
  }
@@ -40,5 +40,8 @@ module.exports = {
40
40
  kHostHeader: Symbol('host header'),
41
41
  kConnector: Symbol('connector'),
42
42
  kStrictContentLength: Symbol('strict content length'),
43
- kMaxRedirections: Symbol('maxRedirections')
43
+ kMaxRedirections: Symbol('maxRedirections'),
44
+ kMaxRequests: Symbol('maxRequestsPerClient'),
45
+ kProxy: Symbol('proxy agent options'),
46
+ kCounter: Symbol('socket request counter')
44
47
  }
@@ -171,7 +171,7 @@ async function fetch (...args) {
171
171
 
172
172
  // 3. If response is a network error, then reject p with a TypeError
173
173
  // and terminate these substeps.
174
- if (response.status === 0) {
174
+ if (response.type === 'error') {
175
175
  p.reject(
176
176
  Object.assign(new TypeError('fetch failed'), { cause: response.error })
177
177
  )
@@ -0,0 +1,59 @@
1
+ 'use strict'
2
+
3
+ const { kClients, kProxy } = require('./core/symbols')
4
+ const url = require('url')
5
+ const Agent = require('./agent')
6
+ const Dispatcher = require('./dispatcher')
7
+ const { InvalidArgumentError } = require('./core/errors')
8
+
9
+ const kAgent = Symbol('proxy agent')
10
+
11
+ class ProxyAgent extends Dispatcher {
12
+ constructor (opts) {
13
+ super(opts)
14
+ this[kProxy] = buildProxyOptions(opts)
15
+
16
+ const agent = new Agent(opts)
17
+ this[kAgent] = agent
18
+
19
+ this[kClients] = agent[kClients]
20
+ }
21
+
22
+ dispatch (opts, handler) {
23
+ const { host } = url.parse(opts.origin)
24
+ return this[kAgent].dispatch(
25
+ {
26
+ ...opts,
27
+ origin: this[kProxy].uri,
28
+ path: opts.origin + opts.path,
29
+ headers: {
30
+ ...opts.headers,
31
+ host
32
+ },
33
+ },
34
+ handler
35
+ )
36
+ }
37
+
38
+ async close () {
39
+ await this[kAgent].close()
40
+ this[kClients].clear()
41
+ }
42
+ }
43
+
44
+ function buildProxyOptions(opts) {
45
+ if (typeof opts === 'string') {
46
+ opts = { uri: opts }
47
+ }
48
+
49
+ if (!opts || !opts.uri) {
50
+ throw new InvalidArgumentError('Proxy opts.uri is mandatory')
51
+ }
52
+
53
+ return {
54
+ uri: opts.uri,
55
+ protocol: opts.protocol || 'https'
56
+ }
57
+ }
58
+
59
+ module.exports = ProxyAgent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "undici",
3
- "version": "4.8.0",
3
+ "version": "4.9.1",
4
4
  "description": "An HTTP/1.1 client, written from scratch for Node.js",
5
5
  "homepage": "https://undici.nodejs.org",
6
6
  "bugs": {
package/types/client.d.ts CHANGED
@@ -39,6 +39,8 @@ declare namespace Client {
39
39
  strictContentLength?: boolean;
40
40
  /** @deprecated use the connect option instead */
41
41
  tls?: TlsOptions | null;
42
+ /** */
43
+ maxRequestsPerClient?: number;
42
44
  }
43
45
 
44
46
  export interface SocketInfo {
@@ -0,0 +1,17 @@
1
+ import Agent = require('./agent')
2
+ import Dispatcher = require('./dispatcher')
3
+
4
+ export = ProxyAgent
5
+
6
+ declare class ProxyAgent extends Dispatcher {
7
+ constructor(options: ProxyAgent.Options | string)
8
+
9
+ dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandlers): void;
10
+ close(): Promise<void>;
11
+ }
12
+
13
+ declare namespace ProxyAgent {
14
+ export interface Options extends Agent.Options {
15
+ uri: string;
16
+ }
17
+ }