undici 6.5.0 → 6.6.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/best-practices/client-certificate.md +3 -3
- package/lib/agent.js +5 -7
- package/lib/api/api-connect.js +2 -2
- package/lib/api/api-pipeline.js +4 -4
- package/lib/api/api-request.js +2 -2
- package/lib/api/api-stream.js +4 -4
- package/lib/api/api-upgrade.js +3 -3
- package/lib/api/readable.js +2 -2
- package/lib/api/util.js +1 -1
- package/lib/balanced-pool.js +1 -1
- package/lib/cache/cache.js +4 -10
- package/lib/cache/util.js +1 -1
- package/lib/client.js +14 -14
- package/lib/cookies/parse.js +1 -1
- package/lib/cookies/util.js +1 -1
- package/lib/core/connect.js +3 -3
- package/lib/core/diagnostics.js +2 -2
- package/lib/core/request.js +18 -13
- package/lib/core/tree.js +3 -5
- package/lib/core/util.js +15 -15
- package/lib/dispatcher.js +1 -1
- package/lib/eventsource/eventsource-stream.js +1 -1
- package/lib/eventsource/eventsource.js +2 -2
- package/lib/eventsource/util.js +9 -1
- package/lib/fetch/body.js +29 -21
- package/lib/fetch/dataURL.js +97 -17
- package/lib/fetch/file.js +5 -5
- package/lib/fetch/formdata.js +1 -1
- package/lib/fetch/headers.js +1 -1
- package/lib/fetch/index.js +28 -37
- package/lib/fetch/request.js +3 -2
- package/lib/fetch/response.js +31 -39
- package/lib/fetch/util.js +196 -36
- package/lib/fetch/webidl.js +1 -1
- package/lib/fileapi/util.js +2 -2
- package/lib/handler/RedirectHandler.js +2 -2
- package/lib/handler/RetryHandler.js +3 -3
- package/lib/llhttp/llhttp-wasm.js +3 -1
- package/lib/llhttp/llhttp_simd-wasm.js +3 -1
- package/lib/mock/mock-agent.js +2 -2
- package/lib/mock/mock-client.js +1 -1
- package/lib/mock/mock-pool.js +1 -1
- package/lib/mock/mock-utils.js +2 -2
- package/lib/mock/pending-interceptors-formatter.js +2 -2
- package/lib/pool.js +7 -8
- package/lib/proxy-agent.js +2 -2
- package/lib/timers.js +1 -1
- package/lib/websocket/connection.js +1 -1
- package/lib/websocket/events.js +1 -1
- package/lib/websocket/frame.js +1 -1
- package/lib/websocket/receiver.js +7 -6
- package/lib/websocket/util.js +1 -1
- package/lib/websocket/websocket.js +1 -1
- package/package.json +4 -7
package/lib/fetch/util.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { Transform } = require('node:stream')
|
|
4
|
+
const zlib = require('node:zlib')
|
|
3
5
|
const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require('./constants')
|
|
4
6
|
const { getGlobalOrigin } = require('./global')
|
|
5
|
-
const {
|
|
7
|
+
const { collectASequenceOfCodePoints, collectAnHTTPQuotedString, removeChars, parseMIMEType } = require('./dataURL')
|
|
8
|
+
const { performance } = require('node:perf_hooks')
|
|
6
9
|
const { isBlobLike, toUSVString, ReadableStreamFrom, isValidHTTPToken } = require('../core/util')
|
|
7
|
-
const assert = require('assert')
|
|
10
|
+
const assert = require('node:assert')
|
|
8
11
|
const { isUint8Array } = require('util/types')
|
|
9
12
|
|
|
10
13
|
// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable
|
|
@@ -12,7 +15,7 @@ const { isUint8Array } = require('util/types')
|
|
|
12
15
|
let crypto
|
|
13
16
|
|
|
14
17
|
try {
|
|
15
|
-
crypto = require('crypto')
|
|
18
|
+
crypto = require('node:crypto')
|
|
16
19
|
} catch {
|
|
17
20
|
|
|
18
21
|
}
|
|
@@ -272,7 +275,7 @@ function coarsenTime (timestamp, crossOriginIsolatedCapability) {
|
|
|
272
275
|
}
|
|
273
276
|
|
|
274
277
|
// https://fetch.spec.whatwg.org/#clamp-and-coarsen-connection-timing-info
|
|
275
|
-
function
|
|
278
|
+
function clampAndCoarsenConnectionTimingInfo (connectionTimingInfo, defaultStartTime, crossOriginIsolatedCapability) {
|
|
276
279
|
if (!connectionTimingInfo?.startTime || connectionTimingInfo.startTime < defaultStartTime) {
|
|
277
280
|
return {
|
|
278
281
|
domainLookupStartTime: defaultStartTime,
|
|
@@ -887,29 +890,6 @@ function isReadableStreamLike (stream) {
|
|
|
887
890
|
)
|
|
888
891
|
}
|
|
889
892
|
|
|
890
|
-
/**
|
|
891
|
-
* @see https://infra.spec.whatwg.org/#isomorphic-decode
|
|
892
|
-
* @param {Uint8Array} input
|
|
893
|
-
*/
|
|
894
|
-
function isomorphicDecode (input) {
|
|
895
|
-
// 1. To isomorphic decode a byte sequence input, return a string whose code point
|
|
896
|
-
// length is equal to input’s length and whose code points have the same values
|
|
897
|
-
// as the values of input’s bytes, in the same order.
|
|
898
|
-
const length = input.length
|
|
899
|
-
if ((2 << 15) - 1 > length) {
|
|
900
|
-
return String.fromCharCode.apply(null, input)
|
|
901
|
-
}
|
|
902
|
-
let result = ''; let i = 0
|
|
903
|
-
let addition = (2 << 15) - 1
|
|
904
|
-
while (i < length) {
|
|
905
|
-
if (i + addition > length) {
|
|
906
|
-
addition = length - i
|
|
907
|
-
}
|
|
908
|
-
result += String.fromCharCode.apply(null, input.subarray(i, i += addition))
|
|
909
|
-
}
|
|
910
|
-
return result
|
|
911
|
-
}
|
|
912
|
-
|
|
913
893
|
/**
|
|
914
894
|
* @param {ReadableStreamController<Uint8Array>} controller
|
|
915
895
|
*/
|
|
@@ -1007,18 +987,12 @@ function urlIsHttpHttpsScheme (url) {
|
|
|
1007
987
|
return protocol === 'http:' || protocol === 'https:'
|
|
1008
988
|
}
|
|
1009
989
|
|
|
1010
|
-
/** @type {import('./dataURL')['collectASequenceOfCodePoints']} */
|
|
1011
|
-
let collectASequenceOfCodePoints
|
|
1012
|
-
|
|
1013
990
|
/**
|
|
1014
991
|
* @see https://fetch.spec.whatwg.org/#simple-range-header-value
|
|
1015
992
|
* @param {string} value
|
|
1016
993
|
* @param {boolean} allowWhitespace
|
|
1017
994
|
*/
|
|
1018
995
|
function simpleRangeHeaderValue (value, allowWhitespace) {
|
|
1019
|
-
// Note: avoid circular require
|
|
1020
|
-
collectASequenceOfCodePoints ??= require('./dataURL').collectASequenceOfCodePoints
|
|
1021
|
-
|
|
1022
996
|
// 1. Let data be the isomorphic decoding of value.
|
|
1023
997
|
// Note: isomorphic decoding takes a sequence of bytes (ie. a Uint8Array) and turns it into a string,
|
|
1024
998
|
// nothing more. We obviously don't need to do that if value is a string already.
|
|
@@ -1174,6 +1148,191 @@ function buildContentRange (rangeStart, rangeEnd, fullLength) {
|
|
|
1174
1148
|
return contentRange
|
|
1175
1149
|
}
|
|
1176
1150
|
|
|
1151
|
+
// A Stream, which pipes the response to zlib.createInflate() or
|
|
1152
|
+
// zlib.createInflateRaw() depending on the first byte of the Buffer.
|
|
1153
|
+
// If the lower byte of the first byte is 0x08, then the stream is
|
|
1154
|
+
// interpreted as a zlib stream, otherwise it's interpreted as a
|
|
1155
|
+
// raw deflate stream.
|
|
1156
|
+
class InflateStream extends Transform {
|
|
1157
|
+
_transform (chunk, encoding, callback) {
|
|
1158
|
+
if (!this._inflateStream) {
|
|
1159
|
+
if (chunk.length === 0) {
|
|
1160
|
+
callback()
|
|
1161
|
+
return
|
|
1162
|
+
}
|
|
1163
|
+
this._inflateStream = (chunk[0] & 0x0F) === 0x08
|
|
1164
|
+
? zlib.createInflate()
|
|
1165
|
+
: zlib.createInflateRaw()
|
|
1166
|
+
|
|
1167
|
+
this._inflateStream.on('data', this.push.bind(this))
|
|
1168
|
+
this._inflateStream.on('end', () => this.push(null))
|
|
1169
|
+
this._inflateStream.on('error', (err) => this.destroy(err))
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
this._inflateStream.write(chunk, encoding, callback)
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
_final (callback) {
|
|
1176
|
+
if (this._inflateStream) {
|
|
1177
|
+
this._inflateStream.end()
|
|
1178
|
+
this._inflateStream = null
|
|
1179
|
+
}
|
|
1180
|
+
callback()
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
function createInflate () {
|
|
1185
|
+
return new InflateStream()
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
/**
|
|
1189
|
+
* @see https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
|
|
1190
|
+
* @param {import('./headers').HeadersList} headers
|
|
1191
|
+
*/
|
|
1192
|
+
function extractMimeType (headers) {
|
|
1193
|
+
// 1. Let charset be null.
|
|
1194
|
+
let charset = null
|
|
1195
|
+
|
|
1196
|
+
// 2. Let essence be null.
|
|
1197
|
+
let essence = null
|
|
1198
|
+
|
|
1199
|
+
// 3. Let mimeType be null.
|
|
1200
|
+
let mimeType = null
|
|
1201
|
+
|
|
1202
|
+
// 4. Let values be the result of getting, decoding, and splitting `Content-Type` from headers.
|
|
1203
|
+
const values = getDecodeSplit('content-type', headers)
|
|
1204
|
+
|
|
1205
|
+
// 5. If values is null, then return failure.
|
|
1206
|
+
if (values === null) {
|
|
1207
|
+
return 'failure'
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
// 6. For each value of values:
|
|
1211
|
+
for (const value of values) {
|
|
1212
|
+
// 6.1. Let temporaryMimeType be the result of parsing value.
|
|
1213
|
+
const temporaryMimeType = parseMIMEType(value)
|
|
1214
|
+
|
|
1215
|
+
// 6.2. If temporaryMimeType is failure or its essence is "*/*", then continue.
|
|
1216
|
+
if (temporaryMimeType === 'failure' || temporaryMimeType.essence === '*/*') {
|
|
1217
|
+
continue
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
// 6.3. Set mimeType to temporaryMimeType.
|
|
1221
|
+
mimeType = temporaryMimeType
|
|
1222
|
+
|
|
1223
|
+
// 6.4. If mimeType’s essence is not essence, then:
|
|
1224
|
+
if (mimeType.essence !== essence) {
|
|
1225
|
+
// 6.4.1. Set charset to null.
|
|
1226
|
+
charset = null
|
|
1227
|
+
|
|
1228
|
+
// 6.4.2. If mimeType’s parameters["charset"] exists, then set charset to
|
|
1229
|
+
// mimeType’s parameters["charset"].
|
|
1230
|
+
if (mimeType.parameters.has('charset')) {
|
|
1231
|
+
charset = mimeType.parameters.get('charset')
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// 6.4.3. Set essence to mimeType’s essence.
|
|
1235
|
+
essence = mimeType.essence
|
|
1236
|
+
} else if (!mimeType.parameters.has('charset') && charset !== null) {
|
|
1237
|
+
// 6.5. Otherwise, if mimeType’s parameters["charset"] does not exist, and
|
|
1238
|
+
// charset is non-null, set mimeType’s parameters["charset"] to charset.
|
|
1239
|
+
mimeType.parameters.set('charset', charset)
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
// 7. If mimeType is null, then return failure.
|
|
1244
|
+
if (mimeType == null) {
|
|
1245
|
+
return 'failure'
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
// 8. Return mimeType.
|
|
1249
|
+
return mimeType
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
/**
|
|
1253
|
+
* @see https://fetch.spec.whatwg.org/#header-value-get-decode-and-split
|
|
1254
|
+
* @param {string|null} value
|
|
1255
|
+
*/
|
|
1256
|
+
function gettingDecodingSplitting (value) {
|
|
1257
|
+
// 1. Let input be the result of isomorphic decoding value.
|
|
1258
|
+
const input = value
|
|
1259
|
+
|
|
1260
|
+
// 2. Let position be a position variable for input, initially pointing at the start of input.
|
|
1261
|
+
const position = { position: 0 }
|
|
1262
|
+
|
|
1263
|
+
// 3. Let values be a list of strings, initially empty.
|
|
1264
|
+
const values = []
|
|
1265
|
+
|
|
1266
|
+
// 4. Let temporaryValue be the empty string.
|
|
1267
|
+
let temporaryValue = ''
|
|
1268
|
+
|
|
1269
|
+
// 5. While position is not past the end of input:
|
|
1270
|
+
while (position.position < input.length) {
|
|
1271
|
+
// 5.1. Append the result of collecting a sequence of code points that are not U+0022 (")
|
|
1272
|
+
// or U+002C (,) from input, given position, to temporaryValue.
|
|
1273
|
+
temporaryValue += collectASequenceOfCodePoints(
|
|
1274
|
+
(char) => char !== '"' && char !== ',',
|
|
1275
|
+
input,
|
|
1276
|
+
position
|
|
1277
|
+
)
|
|
1278
|
+
|
|
1279
|
+
// 5.2. If position is not past the end of input, then:
|
|
1280
|
+
if (position.position < input.length) {
|
|
1281
|
+
// 5.2.1. If the code point at position within input is U+0022 ("), then:
|
|
1282
|
+
if (input.charCodeAt(position.position) === 0x22) {
|
|
1283
|
+
// 5.2.1.1. Append the result of collecting an HTTP quoted string from input, given position, to temporaryValue.
|
|
1284
|
+
temporaryValue += collectAnHTTPQuotedString(
|
|
1285
|
+
input,
|
|
1286
|
+
position
|
|
1287
|
+
)
|
|
1288
|
+
|
|
1289
|
+
// 5.2.1.2. If position is not past the end of input, then continue.
|
|
1290
|
+
if (position.position < input.length) {
|
|
1291
|
+
continue
|
|
1292
|
+
}
|
|
1293
|
+
} else {
|
|
1294
|
+
// 5.2.2. Otherwise:
|
|
1295
|
+
|
|
1296
|
+
// 5.2.2.1. Assert: the code point at position within input is U+002C (,).
|
|
1297
|
+
assert(input.charCodeAt(position.position) === 0x2C)
|
|
1298
|
+
|
|
1299
|
+
// 5.2.2.2. Advance position by 1.
|
|
1300
|
+
position.position++
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
// 5.3. Remove all HTTP tab or space from the start and end of temporaryValue.
|
|
1305
|
+
temporaryValue = removeChars(temporaryValue, true, true, (char) => char === 0x9 || char === 0x20)
|
|
1306
|
+
|
|
1307
|
+
// 5.4. Append temporaryValue to values.
|
|
1308
|
+
values.push(temporaryValue)
|
|
1309
|
+
|
|
1310
|
+
// 5.6. Set temporaryValue to the empty string.
|
|
1311
|
+
temporaryValue = ''
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
// 6. Return values.
|
|
1315
|
+
return values
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
/**
|
|
1319
|
+
* @see https://fetch.spec.whatwg.org/#concept-header-list-get-decode-split
|
|
1320
|
+
* @param {string} name lowercase header name
|
|
1321
|
+
* @param {import('./headers').HeadersList} list
|
|
1322
|
+
*/
|
|
1323
|
+
function getDecodeSplit (name, list) {
|
|
1324
|
+
// 1. Let value be the result of getting name from list.
|
|
1325
|
+
const value = list.get(name, true)
|
|
1326
|
+
|
|
1327
|
+
// 2. If value is null, then return null.
|
|
1328
|
+
if (value === null) {
|
|
1329
|
+
return null
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
// 3. Return the result of getting, decoding, and splitting value.
|
|
1333
|
+
return gettingDecodingSplitting(value)
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1177
1336
|
module.exports = {
|
|
1178
1337
|
isAborted,
|
|
1179
1338
|
isCancelled,
|
|
@@ -1181,7 +1340,7 @@ module.exports = {
|
|
|
1181
1340
|
ReadableStreamFrom,
|
|
1182
1341
|
toUSVString,
|
|
1183
1342
|
tryUpgradeRequestToAPotentiallyTrustworthyURL,
|
|
1184
|
-
|
|
1343
|
+
clampAndCoarsenConnectionTimingInfo,
|
|
1185
1344
|
coarsenedSharedCurrentTime,
|
|
1186
1345
|
determineRequestsReferrer,
|
|
1187
1346
|
makePolicyContainer,
|
|
@@ -1213,7 +1372,6 @@ module.exports = {
|
|
|
1213
1372
|
isReadableStreamLike,
|
|
1214
1373
|
readableStreamClose,
|
|
1215
1374
|
isomorphicEncode,
|
|
1216
|
-
isomorphicDecode,
|
|
1217
1375
|
urlIsLocal,
|
|
1218
1376
|
urlHasHttpsScheme,
|
|
1219
1377
|
urlIsHttpHttpsScheme,
|
|
@@ -1221,5 +1379,7 @@ module.exports = {
|
|
|
1221
1379
|
normalizeMethodRecord,
|
|
1222
1380
|
simpleRangeHeaderValue,
|
|
1223
1381
|
buildContentRange,
|
|
1224
|
-
parseMetadata
|
|
1382
|
+
parseMetadata,
|
|
1383
|
+
createInflate,
|
|
1384
|
+
extractMimeType
|
|
1225
1385
|
}
|
package/lib/fetch/webidl.js
CHANGED
package/lib/fileapi/util.js
CHANGED
|
@@ -10,9 +10,9 @@ const {
|
|
|
10
10
|
const { ProgressEvent } = require('./progressevent')
|
|
11
11
|
const { getEncoding } = require('./encoding')
|
|
12
12
|
const { serializeAMimeType, parseMIMEType } = require('../fetch/dataURL')
|
|
13
|
-
const { types } = require('util')
|
|
13
|
+
const { types } = require('node:util')
|
|
14
14
|
const { StringDecoder } = require('string_decoder')
|
|
15
|
-
const { btoa } = require('buffer')
|
|
15
|
+
const { btoa } = require('node:buffer')
|
|
16
16
|
|
|
17
17
|
/** @type {PropertyDescriptor} */
|
|
18
18
|
const staticPropertyDescriptors = {
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const util = require('../core/util')
|
|
4
4
|
const { kBodyUsed } = require('../core/symbols')
|
|
5
|
-
const assert = require('assert')
|
|
5
|
+
const assert = require('node:assert')
|
|
6
6
|
const { InvalidArgumentError } = require('../core/errors')
|
|
7
|
-
const EE = require('events')
|
|
7
|
+
const EE = require('node:events')
|
|
8
8
|
|
|
9
9
|
const redirectableStatusCodes = [300, 301, 302, 303, 307, 308]
|
|
10
10
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const assert = require('assert')
|
|
1
|
+
const assert = require('node:assert')
|
|
2
2
|
|
|
3
3
|
const { kRetryHandlerDefaultRetry } = require('../core/symbols')
|
|
4
4
|
const { RequestRetryError } = require('../core/errors')
|
|
@@ -148,10 +148,10 @@ class RetryHandler {
|
|
|
148
148
|
return
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
let retryAfterHeader = headers
|
|
151
|
+
let retryAfterHeader = headers?.['retry-after']
|
|
152
152
|
if (retryAfterHeader) {
|
|
153
153
|
retryAfterHeader = Number(retryAfterHeader)
|
|
154
|
-
retryAfterHeader = isNaN(retryAfterHeader)
|
|
154
|
+
retryAfterHeader = Number.isNaN(retryAfterHeader)
|
|
155
155
|
? calculateRetryAfterHeader(retryAfterHeader)
|
|
156
156
|
: retryAfterHeader * 1e3 // Retry-After is in seconds
|
|
157
157
|
}
|