undici 8.0.3 → 8.2.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/Client.md +2 -0
- package/docs/docs/api/Dispatcher.md +2 -2
- package/lib/api/api-connect.js +1 -1
- package/lib/api/api-pipeline.js +2 -2
- package/lib/api/api-request.js +2 -2
- package/lib/api/api-stream.js +1 -1
- package/lib/api/api-upgrade.js +8 -2
- package/lib/api/readable.js +3 -2
- package/lib/cache/memory-cache-store.js +1 -1
- package/lib/cache/sqlite-cache-store.js +6 -4
- package/lib/core/connect.js +16 -0
- package/lib/core/constants.js +1 -24
- package/lib/core/errors.js +2 -2
- package/lib/core/request.js +17 -2
- package/lib/core/socks5-client.js +24 -9
- package/lib/core/socks5-utils.js +32 -23
- package/lib/core/util.js +28 -3
- package/lib/dispatcher/agent.js +38 -40
- package/lib/dispatcher/balanced-pool.js +21 -23
- package/lib/dispatcher/client-h1.js +34 -16
- package/lib/dispatcher/client-h2.js +400 -147
- package/lib/dispatcher/client.js +3 -2
- package/lib/dispatcher/dispatcher-base.js +18 -0
- package/lib/dispatcher/h2c-client.js +4 -4
- package/lib/dispatcher/pool-base.js +6 -6
- package/lib/dispatcher/pool.js +8 -3
- package/lib/dispatcher/proxy-agent.js +2 -0
- package/lib/dispatcher/round-robin-pool.js +5 -6
- package/lib/dispatcher/socks5-proxy-agent.js +23 -14
- package/lib/handler/cache-handler.js +1 -1
- package/lib/handler/redirect-handler.js +4 -0
- package/lib/interceptor/redirect.js +3 -3
- package/lib/llhttp/llhttp-wasm.js +1 -1
- package/lib/llhttp/llhttp_simd-wasm.js +1 -1
- package/lib/mock/mock-agent.js +8 -8
- package/lib/mock/mock-call-history.js +15 -15
- package/lib/util/cache.js +1 -1
- package/lib/web/eventsource/eventsource-stream.js +245 -150
- package/lib/web/fetch/formdata-parser.js +17 -6
- package/lib/web/fetch/index.js +38 -28
- package/lib/web/webidl/index.js +5 -5
- package/lib/web/websocket/frame.js +1 -7
- package/lib/web/websocket/permessage-deflate.js +13 -31
- package/lib/web/websocket/receiver.js +62 -22
- package/lib/web/websocket/stream/websocketstream.js +6 -5
- package/lib/web/websocket/websocket.js +6 -1
- package/package.json +1 -1
- package/types/client.d.ts +11 -0
- package/types/dispatcher.d.ts +4 -4
- package/types/header.d.ts +5 -0
- package/types/interceptors.d.ts +1 -1
- package/types/proxy-agent.d.ts +2 -2
- package/types/socks5-proxy-agent.d.ts +2 -2
- package/lib/llhttp/.gitkeep +0 -0
|
@@ -164,35 +164,14 @@ class BalancedPool extends PoolBase {
|
|
|
164
164
|
throw new BalancedPoolMissingUpstreamError()
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
const dispatcher = this[kClients].find(dispatcher => (
|
|
168
|
-
!dispatcher[kNeedDrain] &&
|
|
169
|
-
dispatcher.closed !== true &&
|
|
170
|
-
dispatcher.destroyed !== true
|
|
171
|
-
))
|
|
172
|
-
|
|
173
|
-
if (!dispatcher) {
|
|
174
|
-
return
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const allClientsBusy = this[kClients].map(pool => pool[kNeedDrain]).reduce((a, b) => a && b, true)
|
|
178
|
-
|
|
179
|
-
if (allClientsBusy) {
|
|
180
|
-
return
|
|
181
|
-
}
|
|
182
|
-
|
|
183
167
|
let counter = 0
|
|
184
168
|
|
|
185
|
-
let maxWeightIndex =
|
|
169
|
+
let maxWeightIndex = -1
|
|
186
170
|
|
|
187
171
|
while (counter++ < this[kClients].length) {
|
|
188
172
|
this[kIndex] = (this[kIndex] + 1) % this[kClients].length
|
|
189
173
|
const pool = this[kClients][this[kIndex]]
|
|
190
174
|
|
|
191
|
-
// find pool index with the largest weight
|
|
192
|
-
if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) {
|
|
193
|
-
maxWeightIndex = this[kIndex]
|
|
194
|
-
}
|
|
195
|
-
|
|
196
175
|
// decrease the current weight every `this[kClients].length`.
|
|
197
176
|
if (this[kIndex] === 0) {
|
|
198
177
|
// Set the current weight to the next lower weight.
|
|
@@ -202,11 +181,30 @@ class BalancedPool extends PoolBase {
|
|
|
202
181
|
this[kCurrentWeight] = this[kMaxWeightPerServer]
|
|
203
182
|
}
|
|
204
183
|
}
|
|
205
|
-
|
|
184
|
+
|
|
185
|
+
// Skip unavailable pools after updating the current weight for this cycle.
|
|
186
|
+
if (
|
|
187
|
+
pool[kNeedDrain] ||
|
|
188
|
+
pool.closed === true ||
|
|
189
|
+
pool.destroyed === true
|
|
190
|
+
) {
|
|
191
|
+
continue
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Track the best fallback if no pool matches the current weight.
|
|
195
|
+
if (maxWeightIndex === -1 || pool[kWeight] > this[kClients][maxWeightIndex][kWeight]) {
|
|
196
|
+
maxWeightIndex = this[kIndex]
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (pool[kWeight] >= this[kCurrentWeight]) {
|
|
206
200
|
return pool
|
|
207
201
|
}
|
|
208
202
|
}
|
|
209
203
|
|
|
204
|
+
if (maxWeightIndex === -1) {
|
|
205
|
+
return
|
|
206
|
+
}
|
|
207
|
+
|
|
210
208
|
this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight]
|
|
211
209
|
this[kIndex] = maxWeightIndex
|
|
212
210
|
return this[kClients][maxWeightIndex]
|
|
@@ -69,9 +69,9 @@ function lazyllhttp () {
|
|
|
69
69
|
let useWasmSIMD = process.arch !== 'ppc64'
|
|
70
70
|
// The Env Variable UNDICI_NO_WASM_SIMD allows explicitly overriding the default behavior
|
|
71
71
|
if (process.env.UNDICI_NO_WASM_SIMD === '1') {
|
|
72
|
-
useWasmSIMD = true
|
|
73
|
-
} else if (process.env.UNDICI_NO_WASM_SIMD === '0') {
|
|
74
72
|
useWasmSIMD = false
|
|
73
|
+
} else if (process.env.UNDICI_NO_WASM_SIMD === '0') {
|
|
74
|
+
useWasmSIMD = true
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
if (useWasmSIMD) {
|
|
@@ -188,6 +188,7 @@ let currentBufferRef = null
|
|
|
188
188
|
*/
|
|
189
189
|
let currentBufferSize = 0
|
|
190
190
|
let currentBufferPtr = null
|
|
191
|
+
let currentBuffer = null
|
|
191
192
|
|
|
192
193
|
const USE_NATIVE_TIMER = 0
|
|
193
194
|
const USE_FAST_TIMER = 1
|
|
@@ -216,6 +217,7 @@ class Parser {
|
|
|
216
217
|
*/
|
|
217
218
|
this.socket = socket
|
|
218
219
|
this.timeout = null
|
|
220
|
+
this.timeoutWeakRef = new WeakRef(this)
|
|
219
221
|
this.timeoutValue = null
|
|
220
222
|
this.timeoutType = null
|
|
221
223
|
this.statusCode = 0
|
|
@@ -231,8 +233,8 @@ class Parser {
|
|
|
231
233
|
this.bytesRead = 0
|
|
232
234
|
|
|
233
235
|
this.keepAlive = ''
|
|
234
|
-
this.contentLength =
|
|
235
|
-
this.
|
|
236
|
+
this.contentLength = -1
|
|
237
|
+
this.connectionKeepAlive = false
|
|
236
238
|
this.maxResponseSize = client[kMaxResponseSize]
|
|
237
239
|
}
|
|
238
240
|
|
|
@@ -253,9 +255,9 @@ class Parser {
|
|
|
253
255
|
|
|
254
256
|
if (delay) {
|
|
255
257
|
if (type & USE_FAST_TIMER) {
|
|
256
|
-
this.timeout = timers.setFastTimeout(onParserTimeout, delay,
|
|
258
|
+
this.timeout = timers.setFastTimeout(onParserTimeout, delay, this.timeoutWeakRef)
|
|
257
259
|
} else {
|
|
258
|
-
this.timeout = setTimeout(onParserTimeout, delay,
|
|
260
|
+
this.timeout = setTimeout(onParserTimeout, delay, this.timeoutWeakRef)
|
|
259
261
|
this.timeout?.unref()
|
|
260
262
|
}
|
|
261
263
|
}
|
|
@@ -322,7 +324,16 @@ class Parser {
|
|
|
322
324
|
currentBufferPtr = llhttp.malloc(currentBufferSize)
|
|
323
325
|
}
|
|
324
326
|
|
|
325
|
-
|
|
327
|
+
if (
|
|
328
|
+
currentBuffer === null ||
|
|
329
|
+
currentBuffer.buffer !== llhttp.memory.buffer ||
|
|
330
|
+
currentBuffer.byteOffset !== currentBufferPtr ||
|
|
331
|
+
currentBuffer.byteLength !== currentBufferSize
|
|
332
|
+
) {
|
|
333
|
+
currentBuffer = new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
currentBuffer.set(chunk)
|
|
326
337
|
|
|
327
338
|
// Call `execute` on the wasm parser.
|
|
328
339
|
// We pass the `llhttp_parser` pointer address, the pointer address of buffer view data,
|
|
@@ -447,10 +458,17 @@ class Parser {
|
|
|
447
458
|
if (headerName === 'keep-alive') {
|
|
448
459
|
this.keepAlive += buf.toString()
|
|
449
460
|
} else if (headerName === 'connection') {
|
|
450
|
-
this.
|
|
461
|
+
this.connectionKeepAlive =
|
|
462
|
+
this.headers[len - 1].length === 10 &&
|
|
463
|
+
util.bufferToLowerCasedHeaderName(this.headers[len - 1]) === 'keep-alive'
|
|
451
464
|
}
|
|
452
465
|
} else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === 'content-length') {
|
|
453
|
-
this.contentLength
|
|
466
|
+
if (this.contentLength === -1) {
|
|
467
|
+
this.contentLength = 0
|
|
468
|
+
}
|
|
469
|
+
for (let i = 0; i < buf.length; i++) {
|
|
470
|
+
this.contentLength = (this.contentLength * 10) + (buf[i] - 0x30)
|
|
471
|
+
}
|
|
454
472
|
}
|
|
455
473
|
|
|
456
474
|
this.trackHeader(buf.length)
|
|
@@ -554,7 +572,7 @@ class Parser {
|
|
|
554
572
|
this.shouldKeepAlive = (
|
|
555
573
|
shouldKeepAlive ||
|
|
556
574
|
// Override llhttp value which does not allow keepAlive for HEAD.
|
|
557
|
-
(request.method === 'HEAD' && !socket[kReset] && this.
|
|
575
|
+
(request.method === 'HEAD' && !socket[kReset] && this.connectionKeepAlive)
|
|
558
576
|
)
|
|
559
577
|
|
|
560
578
|
if (this.statusCode >= 200) {
|
|
@@ -687,9 +705,9 @@ class Parser {
|
|
|
687
705
|
this.statusCode = 0
|
|
688
706
|
this.statusText = ''
|
|
689
707
|
this.bytesRead = 0
|
|
690
|
-
this.contentLength =
|
|
708
|
+
this.contentLength = -1
|
|
691
709
|
this.keepAlive = ''
|
|
692
|
-
this.
|
|
710
|
+
this.connectionKeepAlive = false
|
|
693
711
|
|
|
694
712
|
this.headers = []
|
|
695
713
|
this.headersSize = 0
|
|
@@ -698,7 +716,7 @@ class Parser {
|
|
|
698
716
|
return 0
|
|
699
717
|
}
|
|
700
718
|
|
|
701
|
-
if (request.method !== 'HEAD' && contentLength && bytesRead !==
|
|
719
|
+
if (request.method !== 'HEAD' && contentLength !== -1 && bytesRead !== contentLength) {
|
|
702
720
|
util.destroy(socket, new ResponseContentLengthMismatchError())
|
|
703
721
|
return -1
|
|
704
722
|
}
|
|
@@ -1106,7 +1124,7 @@ function writeH1 (client, request) {
|
|
|
1106
1124
|
socket[kReset] = reset
|
|
1107
1125
|
}
|
|
1108
1126
|
|
|
1109
|
-
if (client[kMaxRequests] && socket[kCounter]
|
|
1127
|
+
if (client[kMaxRequests] && ++socket[kCounter] >= client[kMaxRequests]) {
|
|
1110
1128
|
socket[kReset] = true
|
|
1111
1129
|
}
|
|
1112
1130
|
|
|
@@ -1477,7 +1495,7 @@ class AsyncWriter {
|
|
|
1477
1495
|
}
|
|
1478
1496
|
|
|
1479
1497
|
/**
|
|
1480
|
-
* @param {
|
|
1498
|
+
* @param {string|Uint8Array} chunk
|
|
1481
1499
|
* @returns
|
|
1482
1500
|
*/
|
|
1483
1501
|
write (chunk) {
|
|
@@ -1491,7 +1509,7 @@ class AsyncWriter {
|
|
|
1491
1509
|
return false
|
|
1492
1510
|
}
|
|
1493
1511
|
|
|
1494
|
-
const len = Buffer.byteLength(chunk)
|
|
1512
|
+
const len = chunk instanceof Uint8Array ? chunk.byteLength : Buffer.byteLength(chunk)
|
|
1495
1513
|
if (!len) {
|
|
1496
1514
|
return true
|
|
1497
1515
|
}
|