undici 6.11.0 → 6.12.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/docs/docs/api/DiagnosticsChannel.md +2 -0
- package/docs/docs/api/Dispatcher.md +6 -0
- package/lib/api/abort-signal.js +4 -1
- package/lib/api/api-connect.js +7 -3
- package/lib/api/api-pipeline.js +6 -4
- package/lib/api/api-request.js +7 -6
- package/lib/api/api-stream.js +7 -7
- package/lib/api/api-upgrade.js +6 -3
- package/lib/core/request.js +10 -29
- package/lib/core/util.js +41 -8
- package/lib/dispatcher/client-h1.js +64 -69
- package/lib/dispatcher/client-h2.js +52 -68
- package/lib/dispatcher/client.js +7 -13
- package/lib/dispatcher/proxy-agent.js +11 -9
- package/lib/handler/redirect-handler.js +2 -2
- package/lib/mock/mock-interceptor.js +18 -17
- package/lib/mock/mock-utils.js +5 -5
- package/lib/web/fetch/constants.js +2 -2
- package/lib/web/fetch/util.js +105 -33
- package/lib/web/websocket/receiver.js +2 -3
- package/lib/web/websocket/util.js +31 -2
- package/package.json +12 -8
- package/types/dispatcher.d.ts +1 -1
- package/types/fetch.d.ts +1 -1
|
@@ -22,7 +22,6 @@ const {
|
|
|
22
22
|
kSocket,
|
|
23
23
|
kStrictContentLength,
|
|
24
24
|
kOnError,
|
|
25
|
-
// HTTP2
|
|
26
25
|
kMaxConcurrentStreams,
|
|
27
26
|
kHTTP2Session,
|
|
28
27
|
kResume
|
|
@@ -55,14 +54,20 @@ const {
|
|
|
55
54
|
} = http2
|
|
56
55
|
|
|
57
56
|
function parseH2Headers (headers) {
|
|
58
|
-
// set-cookie is always an array. Duplicates are added to the array.
|
|
59
|
-
// For duplicate cookie headers, the values are joined together with '; '.
|
|
60
|
-
headers = Object.entries(headers).flat(2)
|
|
61
|
-
|
|
62
57
|
const result = []
|
|
63
58
|
|
|
64
|
-
for (const
|
|
65
|
-
|
|
59
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
60
|
+
// h2 may concat the header value by array
|
|
61
|
+
// e.g. Set-Cookie
|
|
62
|
+
if (Array.isArray(value)) {
|
|
63
|
+
for (const subvalue of value) {
|
|
64
|
+
// we need to provide each header value of header name
|
|
65
|
+
// because the headers handler expect name-value pair
|
|
66
|
+
result.push(Buffer.from(name), Buffer.from(subvalue))
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
result.push(Buffer.from(name), Buffer.from(value))
|
|
70
|
+
}
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
return result
|
|
@@ -86,16 +91,18 @@ async function connectH2 (client, socket) {
|
|
|
86
91
|
session[kOpenStreams] = 0
|
|
87
92
|
session[kClient] = client
|
|
88
93
|
session[kSocket] = socket
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
|
|
95
|
+
util.addListener(session, 'error', onHttp2SessionError)
|
|
96
|
+
util.addListener(session, 'frameError', onHttp2FrameError)
|
|
97
|
+
util.addListener(session, 'end', onHttp2SessionEnd)
|
|
98
|
+
util.addListener(session, 'goaway', onHTTP2GoAway)
|
|
99
|
+
util.addListener(session, 'close', function () {
|
|
94
100
|
const { [kClient]: client } = this
|
|
95
101
|
|
|
96
|
-
const err = this[kError] || new SocketError('closed', util.getSocketInfo(this))
|
|
102
|
+
const err = this[kSocket][kError] || new SocketError('closed', util.getSocketInfo(this))
|
|
97
103
|
|
|
98
104
|
client[kSocket] = null
|
|
105
|
+
client[kHTTP2Session] = null
|
|
99
106
|
|
|
100
107
|
assert(client[kPending] === 0)
|
|
101
108
|
|
|
@@ -103,7 +110,7 @@ async function connectH2 (client, socket) {
|
|
|
103
110
|
const requests = client[kQueue].splice(client[kRunningIdx])
|
|
104
111
|
for (let i = 0; i < requests.length; i++) {
|
|
105
112
|
const request = requests[i]
|
|
106
|
-
errorRequest(client, request, err)
|
|
113
|
+
util.errorRequest(client, request, err)
|
|
107
114
|
}
|
|
108
115
|
|
|
109
116
|
client[kPendingIdx] = client[kRunningIdx]
|
|
@@ -114,19 +121,21 @@ async function connectH2 (client, socket) {
|
|
|
114
121
|
|
|
115
122
|
client[kResume]()
|
|
116
123
|
})
|
|
124
|
+
|
|
117
125
|
session.unref()
|
|
118
126
|
|
|
119
127
|
client[kHTTP2Session] = session
|
|
120
128
|
socket[kHTTP2Session] = session
|
|
121
129
|
|
|
122
|
-
|
|
130
|
+
util.addListener(socket, 'error', function (err) {
|
|
123
131
|
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
|
124
132
|
|
|
125
133
|
this[kError] = err
|
|
126
134
|
|
|
127
135
|
this[kClient][kOnError](err)
|
|
128
136
|
})
|
|
129
|
-
|
|
137
|
+
|
|
138
|
+
util.addListener(socket, 'end', function () {
|
|
130
139
|
util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this)))
|
|
131
140
|
})
|
|
132
141
|
|
|
@@ -166,67 +175,42 @@ function onHttp2SessionError (err) {
|
|
|
166
175
|
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
|
167
176
|
|
|
168
177
|
this[kSocket][kError] = err
|
|
169
|
-
|
|
170
178
|
this[kClient][kOnError](err)
|
|
171
179
|
}
|
|
172
180
|
|
|
173
181
|
function onHttp2FrameError (type, code, id) {
|
|
174
|
-
const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)
|
|
175
|
-
|
|
176
182
|
if (id === 0) {
|
|
183
|
+
const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)
|
|
177
184
|
this[kSocket][kError] = err
|
|
178
185
|
this[kClient][kOnError](err)
|
|
179
186
|
}
|
|
180
187
|
}
|
|
181
188
|
|
|
182
189
|
function onHttp2SessionEnd () {
|
|
183
|
-
|
|
184
|
-
|
|
190
|
+
const err = new SocketError('other side closed', util.getSocketInfo(this[kSocket]))
|
|
191
|
+
this.destroy(err)
|
|
192
|
+
util.destroy(this[kSocket], err)
|
|
185
193
|
}
|
|
186
194
|
|
|
195
|
+
/**
|
|
196
|
+
* This is the root cause of #3011
|
|
197
|
+
* We need to handle GOAWAY frames properly, and trigger the session close
|
|
198
|
+
* along with the socket right away
|
|
199
|
+
* Find a way to trigger the close cycle from here on.
|
|
200
|
+
*/
|
|
187
201
|
function onHTTP2GoAway (code) {
|
|
188
|
-
const client = this[kClient]
|
|
189
202
|
const err = new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${code}`)
|
|
190
|
-
client[kSocket] = null
|
|
191
|
-
client[kHTTP2Session] = null
|
|
192
203
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
for (let i = 0; i < requests.length; i++) {
|
|
199
|
-
const request = requests[i]
|
|
200
|
-
errorRequest(this, request, err)
|
|
201
|
-
}
|
|
202
|
-
} else if (client[kRunning] > 0) {
|
|
203
|
-
// Fail head of pipeline.
|
|
204
|
-
const request = client[kQueue][client[kRunningIdx]]
|
|
205
|
-
client[kQueue][client[kRunningIdx]++] = null
|
|
206
|
-
|
|
207
|
-
errorRequest(client, request, err)
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
client[kPendingIdx] = client[kRunningIdx]
|
|
211
|
-
|
|
212
|
-
assert(client[kRunning] === 0)
|
|
213
|
-
|
|
214
|
-
client.emit('disconnect',
|
|
215
|
-
client[kUrl],
|
|
216
|
-
[client],
|
|
217
|
-
err
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
client[kResume]()
|
|
221
|
-
}
|
|
204
|
+
// We need to trigger the close cycle right away
|
|
205
|
+
// We need to destroy the session and the socket
|
|
206
|
+
// Requests should be failed with the error after the current one is handled
|
|
207
|
+
this[kSocket][kError] = err
|
|
208
|
+
this[kClient][kOnError](err)
|
|
222
209
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
} catch (err) {
|
|
228
|
-
client.emit('error', err)
|
|
229
|
-
}
|
|
210
|
+
this.unref()
|
|
211
|
+
// We send the GOAWAY frame response as no error
|
|
212
|
+
this.destroy()
|
|
213
|
+
util.destroy(this[kSocket], err)
|
|
230
214
|
}
|
|
231
215
|
|
|
232
216
|
// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2
|
|
@@ -239,7 +223,7 @@ function writeH2 (client, request) {
|
|
|
239
223
|
const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request
|
|
240
224
|
|
|
241
225
|
if (upgrade) {
|
|
242
|
-
errorRequest(client, request, new Error('Upgrade not supported for H2'))
|
|
226
|
+
util.errorRequest(client, request, new Error('Upgrade not supported for H2'))
|
|
243
227
|
return false
|
|
244
228
|
}
|
|
245
229
|
|
|
@@ -292,10 +276,10 @@ function writeH2 (client, request) {
|
|
|
292
276
|
}
|
|
293
277
|
}
|
|
294
278
|
|
|
295
|
-
errorRequest(client, request, err)
|
|
279
|
+
util.errorRequest(client, request, err)
|
|
296
280
|
})
|
|
297
281
|
} catch (err) {
|
|
298
|
-
errorRequest(client, request, err)
|
|
282
|
+
util.errorRequest(client, request, err)
|
|
299
283
|
}
|
|
300
284
|
|
|
301
285
|
if (method === 'CONNECT') {
|
|
@@ -370,7 +354,7 @@ function writeH2 (client, request) {
|
|
|
370
354
|
// A user agent may send a Content-Length header with 0 value, this should be allowed.
|
|
371
355
|
if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) {
|
|
372
356
|
if (client[kStrictContentLength]) {
|
|
373
|
-
errorRequest(client, request, new RequestContentLengthMismatchError())
|
|
357
|
+
util.errorRequest(client, request, new RequestContentLengthMismatchError())
|
|
374
358
|
return false
|
|
375
359
|
}
|
|
376
360
|
|
|
@@ -412,7 +396,7 @@ function writeH2 (client, request) {
|
|
|
412
396
|
// as there's no value to keep it open.
|
|
413
397
|
if (request.aborted || request.completed) {
|
|
414
398
|
const err = new RequestAbortedError()
|
|
415
|
-
errorRequest(client, request, err)
|
|
399
|
+
util.errorRequest(client, request, err)
|
|
416
400
|
util.destroy(stream, err)
|
|
417
401
|
return
|
|
418
402
|
}
|
|
@@ -446,13 +430,12 @@ function writeH2 (client, request) {
|
|
|
446
430
|
}
|
|
447
431
|
|
|
448
432
|
const err = new InformationalError('HTTP/2: stream half-closed (remote)')
|
|
449
|
-
errorRequest(client, request, err)
|
|
433
|
+
util.errorRequest(client, request, err)
|
|
450
434
|
util.destroy(stream, err)
|
|
451
435
|
})
|
|
452
436
|
|
|
453
437
|
stream.once('close', () => {
|
|
454
438
|
session[kOpenStreams] -= 1
|
|
455
|
-
// TODO(HTTP/2): unref only if current streams count is 0
|
|
456
439
|
if (session[kOpenStreams] === 0) {
|
|
457
440
|
session.unref()
|
|
458
441
|
}
|
|
@@ -461,13 +444,14 @@ function writeH2 (client, request) {
|
|
|
461
444
|
stream.once('error', function (err) {
|
|
462
445
|
if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) {
|
|
463
446
|
session[kOpenStreams] -= 1
|
|
447
|
+
util.errorRequest(client, request, err)
|
|
464
448
|
util.destroy(stream, err)
|
|
465
449
|
}
|
|
466
450
|
})
|
|
467
451
|
|
|
468
452
|
stream.once('frameError', (type, code) => {
|
|
469
453
|
const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)
|
|
470
|
-
errorRequest(client, request, err)
|
|
454
|
+
util.errorRequest(client, request, err)
|
|
471
455
|
|
|
472
456
|
if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) {
|
|
473
457
|
session[kOpenStreams] -= 1
|
package/lib/dispatcher/client.js
CHANGED
|
@@ -338,7 +338,7 @@ class Client extends DispatcherBase {
|
|
|
338
338
|
const requests = this[kQueue].splice(this[kPendingIdx])
|
|
339
339
|
for (let i = 0; i < requests.length; i++) {
|
|
340
340
|
const request = requests[i]
|
|
341
|
-
errorRequest(this, request, err)
|
|
341
|
+
util.errorRequest(this, request, err)
|
|
342
342
|
}
|
|
343
343
|
|
|
344
344
|
const callback = () => {
|
|
@@ -378,7 +378,7 @@ function onError (client, err) {
|
|
|
378
378
|
const requests = client[kQueue].splice(client[kRunningIdx])
|
|
379
379
|
for (let i = 0; i < requests.length; i++) {
|
|
380
380
|
const request = requests[i]
|
|
381
|
-
errorRequest(client, request, err)
|
|
381
|
+
util.errorRequest(client, request, err)
|
|
382
382
|
}
|
|
383
383
|
assert(client[kSize] === 0)
|
|
384
384
|
}
|
|
@@ -502,7 +502,7 @@ async function connect (client) {
|
|
|
502
502
|
assert(client[kRunning] === 0)
|
|
503
503
|
while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) {
|
|
504
504
|
const request = client[kQueue][client[kPendingIdx]++]
|
|
505
|
-
errorRequest(client, request, err)
|
|
505
|
+
util.errorRequest(client, request, err)
|
|
506
506
|
}
|
|
507
507
|
} else {
|
|
508
508
|
onError(client, err)
|
|
@@ -581,7 +581,10 @@ function _resume (client, sync) {
|
|
|
581
581
|
}
|
|
582
582
|
|
|
583
583
|
client[kServerName] = request.servername
|
|
584
|
-
client[kHTTPContext]?.destroy(new InformationalError('servername changed'))
|
|
584
|
+
client[kHTTPContext]?.destroy(new InformationalError('servername changed'), () => {
|
|
585
|
+
client[kHTTPContext] = null
|
|
586
|
+
resume(client)
|
|
587
|
+
})
|
|
585
588
|
}
|
|
586
589
|
|
|
587
590
|
if (client[kConnecting]) {
|
|
@@ -609,13 +612,4 @@ function _resume (client, sync) {
|
|
|
609
612
|
}
|
|
610
613
|
}
|
|
611
614
|
|
|
612
|
-
function errorRequest (client, request, err) {
|
|
613
|
-
try {
|
|
614
|
-
request.onError(err)
|
|
615
|
-
assert(request.aborted)
|
|
616
|
-
} catch (err) {
|
|
617
|
-
client.emit('error', err)
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
|
|
621
615
|
module.exports = Client
|
|
@@ -64,19 +64,19 @@ class ProxyAgent extends DispatcherBase {
|
|
|
64
64
|
this[kAgent] = new Agent({
|
|
65
65
|
...opts,
|
|
66
66
|
connect: async (opts, callback) => {
|
|
67
|
-
let
|
|
67
|
+
let requestedPath = opts.host
|
|
68
68
|
if (!opts.port) {
|
|
69
|
-
|
|
69
|
+
requestedPath += `:${defaultProtocolPort(opts.protocol)}`
|
|
70
70
|
}
|
|
71
71
|
try {
|
|
72
72
|
const { socket, statusCode } = await this[kClient].connect({
|
|
73
73
|
origin,
|
|
74
74
|
port,
|
|
75
|
-
path:
|
|
75
|
+
path: requestedPath,
|
|
76
76
|
signal: opts.signal,
|
|
77
77
|
headers: {
|
|
78
78
|
...this[kProxyHeaders],
|
|
79
|
-
host:
|
|
79
|
+
host: opts.host
|
|
80
80
|
},
|
|
81
81
|
servername: this[kProxyTls]?.servername || proxyHostname
|
|
82
82
|
})
|
|
@@ -108,16 +108,18 @@ class ProxyAgent extends DispatcherBase {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
dispatch (opts, handler) {
|
|
111
|
-
const { host } = new URL(opts.origin)
|
|
112
111
|
const headers = buildHeaders(opts.headers)
|
|
113
112
|
throwIfProxyAuthIsSent(headers)
|
|
113
|
+
|
|
114
|
+
if (headers && !('host' in headers) && !('Host' in headers)) {
|
|
115
|
+
const { host } = new URL(opts.origin)
|
|
116
|
+
headers.host = host
|
|
117
|
+
}
|
|
118
|
+
|
|
114
119
|
return this[kAgent].dispatch(
|
|
115
120
|
{
|
|
116
121
|
...opts,
|
|
117
|
-
headers
|
|
118
|
-
...headers,
|
|
119
|
-
host
|
|
120
|
-
}
|
|
122
|
+
headers
|
|
121
123
|
},
|
|
122
124
|
handler
|
|
123
125
|
)
|
|
@@ -201,9 +201,9 @@ function shouldRemoveHeader (header, removeContent, unknownOrigin) {
|
|
|
201
201
|
if (removeContent && util.headerNameToString(header).startsWith('content-')) {
|
|
202
202
|
return true
|
|
203
203
|
}
|
|
204
|
-
if (unknownOrigin && (header.length === 13 || header.length === 6)) {
|
|
204
|
+
if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) {
|
|
205
205
|
const name = util.headerNameToString(header)
|
|
206
|
-
return name === 'authorization' || name === 'cookie'
|
|
206
|
+
return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
|
|
207
207
|
}
|
|
208
208
|
return false
|
|
209
209
|
}
|
|
@@ -90,7 +90,7 @@ class MockInterceptor {
|
|
|
90
90
|
this[kContentLength] = false
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
createMockScopeDispatchData (statusCode, data, responseOptions
|
|
93
|
+
createMockScopeDispatchData ({ statusCode, data, responseOptions }) {
|
|
94
94
|
const responseData = getResponseData(data)
|
|
95
95
|
const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {}
|
|
96
96
|
const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers }
|
|
@@ -99,14 +99,11 @@ class MockInterceptor {
|
|
|
99
99
|
return { statusCode, data, headers, trailers }
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
validateReplyParameters (
|
|
103
|
-
if (typeof statusCode === 'undefined') {
|
|
102
|
+
validateReplyParameters (replyParameters) {
|
|
103
|
+
if (typeof replyParameters.statusCode === 'undefined') {
|
|
104
104
|
throw new InvalidArgumentError('statusCode must be defined')
|
|
105
105
|
}
|
|
106
|
-
if (typeof
|
|
107
|
-
throw new InvalidArgumentError('data must be defined')
|
|
108
|
-
}
|
|
109
|
-
if (typeof responseOptions !== 'object' || responseOptions === null) {
|
|
106
|
+
if (typeof replyParameters.responseOptions !== 'object' || replyParameters.responseOptions === null) {
|
|
110
107
|
throw new InvalidArgumentError('responseOptions must be an object')
|
|
111
108
|
}
|
|
112
109
|
}
|
|
@@ -114,28 +111,28 @@ class MockInterceptor {
|
|
|
114
111
|
/**
|
|
115
112
|
* Mock an undici request with a defined reply.
|
|
116
113
|
*/
|
|
117
|
-
reply (
|
|
114
|
+
reply (replyOptionsCallbackOrStatusCode) {
|
|
118
115
|
// Values of reply aren't available right now as they
|
|
119
116
|
// can only be available when the reply callback is invoked.
|
|
120
|
-
if (typeof
|
|
117
|
+
if (typeof replyOptionsCallbackOrStatusCode === 'function') {
|
|
121
118
|
// We'll first wrap the provided callback in another function,
|
|
122
119
|
// this function will properly resolve the data from the callback
|
|
123
120
|
// when invoked.
|
|
124
121
|
const wrappedDefaultsCallback = (opts) => {
|
|
125
122
|
// Our reply options callback contains the parameter for statusCode, data and options.
|
|
126
|
-
const resolvedData =
|
|
123
|
+
const resolvedData = replyOptionsCallbackOrStatusCode(opts)
|
|
127
124
|
|
|
128
125
|
// Check if it is in the right format
|
|
129
|
-
if (typeof resolvedData !== 'object') {
|
|
126
|
+
if (typeof resolvedData !== 'object' || resolvedData === null) {
|
|
130
127
|
throw new InvalidArgumentError('reply options callback must return an object')
|
|
131
128
|
}
|
|
132
129
|
|
|
133
|
-
const {
|
|
134
|
-
this.validateReplyParameters(
|
|
130
|
+
const replyParameters = { data: '', responseOptions: {}, ...resolvedData }
|
|
131
|
+
this.validateReplyParameters(replyParameters)
|
|
135
132
|
// Since the values can be obtained immediately we return them
|
|
136
133
|
// from this higher order function that will be resolved later.
|
|
137
134
|
return {
|
|
138
|
-
...this.createMockScopeDispatchData(
|
|
135
|
+
...this.createMockScopeDispatchData(replyParameters)
|
|
139
136
|
}
|
|
140
137
|
}
|
|
141
138
|
|
|
@@ -148,11 +145,15 @@ class MockInterceptor {
|
|
|
148
145
|
// we should have 1-3 parameters. So we spread the arguments of
|
|
149
146
|
// this function to obtain the parameters, since replyData will always
|
|
150
147
|
// just be the statusCode.
|
|
151
|
-
const
|
|
152
|
-
|
|
148
|
+
const replyParameters = {
|
|
149
|
+
statusCode: replyOptionsCallbackOrStatusCode,
|
|
150
|
+
data: arguments[1] === undefined ? '' : arguments[1],
|
|
151
|
+
responseOptions: arguments[2] === undefined ? {} : arguments[2]
|
|
152
|
+
}
|
|
153
|
+
this.validateReplyParameters(replyParameters)
|
|
153
154
|
|
|
154
155
|
// Send in-already provided data like usual
|
|
155
|
-
const dispatchData = this.createMockScopeDispatchData(
|
|
156
|
+
const dispatchData = this.createMockScopeDispatchData(replyParameters)
|
|
156
157
|
const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData)
|
|
157
158
|
return new MockScope(newMockDispatch)
|
|
158
159
|
}
|
package/lib/mock/mock-utils.js
CHANGED
|
@@ -8,7 +8,7 @@ const {
|
|
|
8
8
|
kOrigin,
|
|
9
9
|
kGetNetConnect
|
|
10
10
|
} = require('./mock-symbols')
|
|
11
|
-
const { buildURL
|
|
11
|
+
const { buildURL } = require('../core/util')
|
|
12
12
|
const { STATUS_CODES } = require('node:http')
|
|
13
13
|
const {
|
|
14
14
|
types: {
|
|
@@ -285,10 +285,10 @@ function mockDispatch (opts, handler) {
|
|
|
285
285
|
const responseHeaders = generateKeyValues(headers)
|
|
286
286
|
const responseTrailers = generateKeyValues(trailers)
|
|
287
287
|
|
|
288
|
-
handler.
|
|
289
|
-
handler.onHeaders(statusCode, responseHeaders, resume, getStatusText(statusCode))
|
|
290
|
-
handler.onData(Buffer.from(responseData))
|
|
291
|
-
handler.onComplete(responseTrailers)
|
|
288
|
+
handler.onConnect?.(err => handler.onError(err), null)
|
|
289
|
+
handler.onHeaders?.(statusCode, responseHeaders, resume, getStatusText(statusCode))
|
|
290
|
+
handler.onData?.(Buffer.from(responseData))
|
|
291
|
+
handler.onComplete?.(responseTrailers)
|
|
292
292
|
deleteMockDispatch(mockDispatches, key)
|
|
293
293
|
}
|
|
294
294
|
|
|
@@ -14,8 +14,8 @@ const badPorts = [
|
|
|
14
14
|
'87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137',
|
|
15
15
|
'139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532',
|
|
16
16
|
'540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723',
|
|
17
|
-
'2049', '3659', '4045', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '
|
|
18
|
-
'10080'
|
|
17
|
+
'2049', '3659', '4045', '4190', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6679',
|
|
18
|
+
'6697', '10080'
|
|
19
19
|
]
|
|
20
20
|
|
|
21
21
|
const badPortsSet = new Set(badPorts)
|