@infersec/conduit 1.86.0 → 1.86.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.
- package/dist/cli.js +1192 -302
- package/dist/cli.sea.cjs +1192 -302
- package/package.json +1 -1
package/dist/cli.sea.cjs
CHANGED
|
@@ -26930,7 +26930,13 @@ function requireRequest$2 () {
|
|
|
26930
26930
|
} else if (typeof val[i] === 'object') {
|
|
26931
26931
|
throw new InvalidArgumentError(`invalid ${key} header`)
|
|
26932
26932
|
} else {
|
|
26933
|
-
|
|
26933
|
+
// Coerce primitives (and reject unsafe coercions such as functions
|
|
26934
|
+
// with a crafted toString/Symbol.toPrimitive).
|
|
26935
|
+
const str = `${val[i]}`;
|
|
26936
|
+
if (!isValidHeaderValue(str)) {
|
|
26937
|
+
throw new InvalidArgumentError(`invalid ${key} header`)
|
|
26938
|
+
}
|
|
26939
|
+
arr.push(str);
|
|
26934
26940
|
}
|
|
26935
26941
|
}
|
|
26936
26942
|
val = arr;
|
|
@@ -26941,7 +26947,12 @@ function requireRequest$2 () {
|
|
|
26941
26947
|
} else if (val === null) {
|
|
26942
26948
|
val = '';
|
|
26943
26949
|
} else {
|
|
26950
|
+
// Coerce primitives (and reject unsafe coercions such as functions
|
|
26951
|
+
// with a crafted toString/Symbol.toPrimitive).
|
|
26944
26952
|
val = `${val}`;
|
|
26953
|
+
if (!isValidHeaderValue(val)) {
|
|
26954
|
+
throw new InvalidArgumentError(`invalid ${key} header`)
|
|
26955
|
+
}
|
|
26945
26956
|
}
|
|
26946
26957
|
|
|
26947
26958
|
if (headerName === 'host') {
|
|
@@ -33423,6 +33434,7 @@ function requireClientH1 () {
|
|
|
33423
33434
|
RequestContentLengthMismatchError,
|
|
33424
33435
|
ResponseContentLengthMismatchError,
|
|
33425
33436
|
RequestAbortedError,
|
|
33437
|
+
InvalidArgumentError,
|
|
33426
33438
|
HeadersTimeoutError,
|
|
33427
33439
|
HeadersOverflowError,
|
|
33428
33440
|
SocketError,
|
|
@@ -34547,8 +34559,16 @@ function requireClientH1 () {
|
|
|
34547
34559
|
}
|
|
34548
34560
|
body = bodyStream.stream;
|
|
34549
34561
|
contentLength = bodyStream.length;
|
|
34550
|
-
} else if (util.isBlobLike(body) && request.contentType == null
|
|
34551
|
-
|
|
34562
|
+
} else if (util.isBlobLike(body) && request.contentType == null) {
|
|
34563
|
+
const contentType = body.type;
|
|
34564
|
+
if (contentType) {
|
|
34565
|
+
const contentTypeValue = `${contentType}`;
|
|
34566
|
+
if (!util.isValidHeaderValue(contentTypeValue)) {
|
|
34567
|
+
util.errorRequest(client, request, new InvalidArgumentError('invalid content-type header'));
|
|
34568
|
+
return false
|
|
34569
|
+
}
|
|
34570
|
+
headers.push('content-type', contentTypeValue);
|
|
34571
|
+
}
|
|
34552
34572
|
}
|
|
34553
34573
|
|
|
34554
34574
|
if (body && typeof body.read === 'function') {
|
|
@@ -39259,6 +39279,26 @@ function requireRetryHandler () {
|
|
|
39259
39279
|
return isNaN(retryTime) ? 0 : retryTime - Date.now()
|
|
39260
39280
|
}
|
|
39261
39281
|
|
|
39282
|
+
function validatePartialResponseContentLength (headers, range, statusCode, retryCount) {
|
|
39283
|
+
const contentLength = headers['content-length'];
|
|
39284
|
+
if (contentLength == null) {
|
|
39285
|
+
return
|
|
39286
|
+
}
|
|
39287
|
+
|
|
39288
|
+
if (!Number.isFinite(range.start) || !Number.isFinite(range.end)) {
|
|
39289
|
+
return
|
|
39290
|
+
}
|
|
39291
|
+
|
|
39292
|
+
const length = Number(contentLength);
|
|
39293
|
+
const expectedLength = range.end - range.start + 1;
|
|
39294
|
+
if (!Number.isFinite(length) || length !== expectedLength) {
|
|
39295
|
+
throw new RequestRetryError('Content-Length mismatch', statusCode, {
|
|
39296
|
+
headers,
|
|
39297
|
+
data: { count: retryCount }
|
|
39298
|
+
})
|
|
39299
|
+
}
|
|
39300
|
+
}
|
|
39301
|
+
|
|
39262
39302
|
class RetryHandler {
|
|
39263
39303
|
constructor (opts, { dispatch, handler }) {
|
|
39264
39304
|
const { retryOptions, ...dispatchOpts } = opts;
|
|
@@ -39473,6 +39513,8 @@ function requireRetryHandler () {
|
|
|
39473
39513
|
})
|
|
39474
39514
|
}
|
|
39475
39515
|
|
|
39516
|
+
validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount);
|
|
39517
|
+
|
|
39476
39518
|
const { start, size, end = size ? size - 1 : null } = contentRange;
|
|
39477
39519
|
|
|
39478
39520
|
assert(this.start === start, 'content-range mismatch');
|
|
@@ -39497,6 +39539,8 @@ function requireRetryHandler () {
|
|
|
39497
39539
|
return
|
|
39498
39540
|
}
|
|
39499
39541
|
|
|
39542
|
+
validatePartialResponseContentLength(headers, range, statusCode, this.retryCount);
|
|
39543
|
+
|
|
39500
39544
|
const { start, size, end = size ? size - 1 : null } = range;
|
|
39501
39545
|
assert(
|
|
39502
39546
|
start != null && Number.isFinite(start),
|
|
@@ -45199,11 +45243,147 @@ function requireCache$2 () {
|
|
|
45199
45243
|
const {
|
|
45200
45244
|
safeHTTPMethods,
|
|
45201
45245
|
pathHasQueryOrFragment,
|
|
45202
|
-
hasSafeIterator
|
|
45246
|
+
hasSafeIterator,
|
|
45247
|
+
isValidHTTPToken
|
|
45203
45248
|
} = requireUtil$7();
|
|
45204
45249
|
|
|
45205
45250
|
const { serializePathWithQuery } = requireUtil$7();
|
|
45206
45251
|
|
|
45252
|
+
const MAX_DELTA_SECONDS = 2147483647;
|
|
45253
|
+
const RESTRICTIVE_DIRECTIVE_NAMES = ['no-store', 'private', 'no-cache'];
|
|
45254
|
+
const kInvalidCacheControlDirectives = Symbol('invalid cache-control directives');
|
|
45255
|
+
|
|
45256
|
+
function trimOWS (value) {
|
|
45257
|
+
return value.replace(/^[\t ]+|[\t ]+$/g, '')
|
|
45258
|
+
}
|
|
45259
|
+
|
|
45260
|
+
function arrayIncludes (array, value) {
|
|
45261
|
+
for (let i = 0; i < array.length; i++) {
|
|
45262
|
+
if (array[i] === value) {
|
|
45263
|
+
return true
|
|
45264
|
+
}
|
|
45265
|
+
}
|
|
45266
|
+
|
|
45267
|
+
return false
|
|
45268
|
+
}
|
|
45269
|
+
|
|
45270
|
+
function trimOWSStart (value) {
|
|
45271
|
+
return value.replace(/^[\t ]+/, '')
|
|
45272
|
+
}
|
|
45273
|
+
|
|
45274
|
+
function trimOWSEnd (value) {
|
|
45275
|
+
return value.replace(/[\t ]+$/, '')
|
|
45276
|
+
}
|
|
45277
|
+
|
|
45278
|
+
function findUnescapedQuote (value, start) {
|
|
45279
|
+
let escaped = false;
|
|
45280
|
+
for (let i = start; i < value.length; i++) {
|
|
45281
|
+
if (escaped) {
|
|
45282
|
+
escaped = false;
|
|
45283
|
+
} else if (value[i] === '\\') {
|
|
45284
|
+
escaped = true;
|
|
45285
|
+
} else if (value[i] === '"') {
|
|
45286
|
+
return i
|
|
45287
|
+
}
|
|
45288
|
+
}
|
|
45289
|
+
|
|
45290
|
+
return -1
|
|
45291
|
+
}
|
|
45292
|
+
|
|
45293
|
+
function splitCacheControlHeaderValue (value) {
|
|
45294
|
+
const directives = [];
|
|
45295
|
+
let start = 0;
|
|
45296
|
+
let quoteStart = -1;
|
|
45297
|
+
let inQuote = false;
|
|
45298
|
+
let escaped = false;
|
|
45299
|
+
|
|
45300
|
+
for (let i = 0; i < value.length; i++) {
|
|
45301
|
+
if (inQuote) {
|
|
45302
|
+
if (escaped) {
|
|
45303
|
+
escaped = false;
|
|
45304
|
+
} else if (value[i] === '\\') {
|
|
45305
|
+
escaped = true;
|
|
45306
|
+
} else if (value[i] === '"') {
|
|
45307
|
+
inQuote = false;
|
|
45308
|
+
quoteStart = -1;
|
|
45309
|
+
}
|
|
45310
|
+
} else if (value[i] === '"') {
|
|
45311
|
+
inQuote = true;
|
|
45312
|
+
quoteStart = i;
|
|
45313
|
+
} else if (value[i] === ',') {
|
|
45314
|
+
directives.push({ value: value.substring(start, i), fromMalformedQuote: false });
|
|
45315
|
+
start = i + 1;
|
|
45316
|
+
}
|
|
45317
|
+
}
|
|
45318
|
+
|
|
45319
|
+
if (!inQuote) {
|
|
45320
|
+
directives.push({ value: value.substring(start), fromMalformedQuote: false });
|
|
45321
|
+
return directives
|
|
45322
|
+
}
|
|
45323
|
+
|
|
45324
|
+
const tail = value.substring(start);
|
|
45325
|
+
const quoteOffset = quoteStart - start;
|
|
45326
|
+
let tailStart = 0;
|
|
45327
|
+
for (let i = 0; i < tail.length; i++) {
|
|
45328
|
+
if (tail[i] === ',') {
|
|
45329
|
+
directives.push({
|
|
45330
|
+
value: tail.substring(tailStart, i),
|
|
45331
|
+
fromMalformedQuote: tailStart > quoteOffset
|
|
45332
|
+
});
|
|
45333
|
+
tailStart = i + 1;
|
|
45334
|
+
}
|
|
45335
|
+
}
|
|
45336
|
+
|
|
45337
|
+
directives.push({
|
|
45338
|
+
value: tail.substring(tailStart),
|
|
45339
|
+
fromMalformedQuote: tailStart > quoteOffset
|
|
45340
|
+
});
|
|
45341
|
+
return directives
|
|
45342
|
+
}
|
|
45343
|
+
|
|
45344
|
+
function markInvalidCacheControlDirective (directives, key) {
|
|
45345
|
+
let invalidDirectives = directives[kInvalidCacheControlDirectives];
|
|
45346
|
+
|
|
45347
|
+
if (invalidDirectives === undefined) {
|
|
45348
|
+
invalidDirectives = new Set();
|
|
45349
|
+
Object.defineProperty(directives, kInvalidCacheControlDirectives, {
|
|
45350
|
+
value: invalidDirectives
|
|
45351
|
+
});
|
|
45352
|
+
}
|
|
45353
|
+
|
|
45354
|
+
invalidDirectives.add(key);
|
|
45355
|
+
}
|
|
45356
|
+
|
|
45357
|
+
function hasInvalidCacheControlDirective (directives, key) {
|
|
45358
|
+
return directives[kInvalidCacheControlDirectives]?.has(key) === true
|
|
45359
|
+
}
|
|
45360
|
+
|
|
45361
|
+
function getMalformedRestrictiveDirectiveName (key) {
|
|
45362
|
+
for (const directiveName of RESTRICTIVE_DIRECTIVE_NAMES) {
|
|
45363
|
+
if (
|
|
45364
|
+
key.startsWith(directiveName) &&
|
|
45365
|
+
key.length > directiveName.length &&
|
|
45366
|
+
!isValidHTTPToken(key[directiveName.length])
|
|
45367
|
+
) {
|
|
45368
|
+
return directiveName
|
|
45369
|
+
}
|
|
45370
|
+
}
|
|
45371
|
+
|
|
45372
|
+
let tokenOnlyKey = '';
|
|
45373
|
+
let hasInvalidTokenChar = false;
|
|
45374
|
+
for (let i = 0; i < key.length; i++) {
|
|
45375
|
+
if (isValidHTTPToken(key[i])) {
|
|
45376
|
+
tokenOnlyKey += key[i];
|
|
45377
|
+
} else {
|
|
45378
|
+
hasInvalidTokenChar = true;
|
|
45379
|
+
}
|
|
45380
|
+
}
|
|
45381
|
+
|
|
45382
|
+
if (hasInvalidTokenChar && arrayIncludes(RESTRICTIVE_DIRECTIVE_NAMES, tokenOnlyKey)) {
|
|
45383
|
+
return tokenOnlyKey
|
|
45384
|
+
}
|
|
45385
|
+
}
|
|
45386
|
+
|
|
45207
45387
|
/**
|
|
45208
45388
|
* @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts
|
|
45209
45389
|
*/
|
|
@@ -45226,6 +45406,20 @@ function requireCache$2 () {
|
|
|
45226
45406
|
}
|
|
45227
45407
|
}
|
|
45228
45408
|
|
|
45409
|
+
function appendHeader (headers, key, val) {
|
|
45410
|
+
const headerName = key.toLowerCase();
|
|
45411
|
+
const current = headers[headerName];
|
|
45412
|
+
const values = Array.isArray(val) ? val : [val];
|
|
45413
|
+
|
|
45414
|
+
if (current === undefined) {
|
|
45415
|
+
headers[headerName] = Array.isArray(val) ? val.slice() : val;
|
|
45416
|
+
} else if (Array.isArray(current)) {
|
|
45417
|
+
current.push(...values);
|
|
45418
|
+
} else {
|
|
45419
|
+
headers[headerName] = [current, ...values];
|
|
45420
|
+
}
|
|
45421
|
+
}
|
|
45422
|
+
|
|
45229
45423
|
/**
|
|
45230
45424
|
* @param {Record<string, string[] | string>}
|
|
45231
45425
|
* @returns {Record<string, string[] | string>}
|
|
@@ -45246,11 +45440,11 @@ function requireCache$2 () {
|
|
|
45246
45440
|
if (typeof key !== 'string' || typeof val !== 'string') {
|
|
45247
45441
|
throw new Error('opts.headers is not a valid header map')
|
|
45248
45442
|
}
|
|
45249
|
-
headers
|
|
45443
|
+
appendHeader(headers, key, val);
|
|
45250
45444
|
}
|
|
45251
45445
|
} else {
|
|
45252
45446
|
for (const key of Object.keys(opts.headers)) {
|
|
45253
|
-
headers
|
|
45447
|
+
appendHeader(headers, key, opts.headers[key]);
|
|
45254
45448
|
}
|
|
45255
45449
|
}
|
|
45256
45450
|
} else {
|
|
@@ -45322,29 +45516,37 @@ function requireCache$2 () {
|
|
|
45322
45516
|
* @type {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives}
|
|
45323
45517
|
*/
|
|
45324
45518
|
const output = {};
|
|
45519
|
+
const invalidNumericDirectives = new Set();
|
|
45520
|
+
const invalidNoArgumentDirectives = new Set();
|
|
45325
45521
|
|
|
45326
|
-
|
|
45327
|
-
if (Array.isArray(header)) {
|
|
45328
|
-
directives = [];
|
|
45329
|
-
|
|
45330
|
-
for (const directive of header) {
|
|
45331
|
-
directives.push(...directive.split(','));
|
|
45332
|
-
}
|
|
45333
|
-
} else {
|
|
45334
|
-
directives = header.split(',');
|
|
45335
|
-
}
|
|
45522
|
+
const directives = splitCacheControlHeaderValue(Array.isArray(header) ? header.join(',') : header);
|
|
45336
45523
|
|
|
45337
45524
|
for (let i = 0; i < directives.length; i++) {
|
|
45338
|
-
const
|
|
45525
|
+
const directiveRecord = directives[i];
|
|
45526
|
+
const directive = directiveRecord.value.toLowerCase();
|
|
45527
|
+
const fromMalformedQuote = directiveRecord.fromMalformedQuote;
|
|
45339
45528
|
const keyValueDelimiter = directive.indexOf('=');
|
|
45340
45529
|
|
|
45341
45530
|
let key;
|
|
45342
45531
|
let value;
|
|
45532
|
+
let keyHasTrailingWhitespace = false;
|
|
45533
|
+
let valueHasLeadingWhitespace = false;
|
|
45343
45534
|
if (keyValueDelimiter !== -1) {
|
|
45344
|
-
|
|
45345
|
-
|
|
45535
|
+
const rawKey = directive.substring(0, keyValueDelimiter);
|
|
45536
|
+
const rawValue = directive.substring(keyValueDelimiter + 1);
|
|
45537
|
+
|
|
45538
|
+
keyHasTrailingWhitespace = trimOWSEnd(rawKey) !== rawKey;
|
|
45539
|
+
valueHasLeadingWhitespace = trimOWSStart(rawValue) !== rawValue;
|
|
45540
|
+
key = trimOWS(rawKey);
|
|
45541
|
+
value = trimOWSStart(rawValue);
|
|
45346
45542
|
} else {
|
|
45347
|
-
key = directive
|
|
45543
|
+
key = trimOWS(directive);
|
|
45544
|
+
}
|
|
45545
|
+
|
|
45546
|
+
const malformedRestrictiveDirectiveName = getMalformedRestrictiveDirectiveName(key);
|
|
45547
|
+
if (malformedRestrictiveDirectiveName !== undefined) {
|
|
45548
|
+
output[malformedRestrictiveDirectiveName] = true;
|
|
45549
|
+
continue
|
|
45348
45550
|
}
|
|
45349
45551
|
|
|
45350
45552
|
switch (key) {
|
|
@@ -45354,7 +45556,14 @@ function requireCache$2 () {
|
|
|
45354
45556
|
case 's-maxage':
|
|
45355
45557
|
case 'stale-while-revalidate':
|
|
45356
45558
|
case 'stale-if-error': {
|
|
45357
|
-
if (
|
|
45559
|
+
if (fromMalformedQuote || invalidNumericDirectives.has(key)) {
|
|
45560
|
+
continue
|
|
45561
|
+
}
|
|
45562
|
+
|
|
45563
|
+
if (value === undefined || keyHasTrailingWhitespace || valueHasLeadingWhitespace) {
|
|
45564
|
+
delete output[key];
|
|
45565
|
+
invalidNumericDirectives.add(key);
|
|
45566
|
+
markInvalidCacheControlDirective(output, key);
|
|
45358
45567
|
continue
|
|
45359
45568
|
}
|
|
45360
45569
|
|
|
@@ -45366,22 +45575,37 @@ function requireCache$2 () {
|
|
|
45366
45575
|
value = value.substring(1, value.length - 1);
|
|
45367
45576
|
}
|
|
45368
45577
|
|
|
45369
|
-
|
|
45370
|
-
|
|
45371
|
-
|
|
45578
|
+
if (!/^[0-9]+$/.test(value)) {
|
|
45579
|
+
delete output[key];
|
|
45580
|
+
invalidNumericDirectives.add(key);
|
|
45581
|
+
markInvalidCacheControlDirective(output, key);
|
|
45372
45582
|
continue
|
|
45373
45583
|
}
|
|
45374
45584
|
|
|
45375
|
-
|
|
45376
|
-
continue
|
|
45377
|
-
}
|
|
45585
|
+
const parsedValue = Math.min(parseInt(value, 10), MAX_DELTA_SECONDS);
|
|
45378
45586
|
|
|
45379
|
-
|
|
45587
|
+
if (key === 'min-fresh') {
|
|
45588
|
+
if (!(key in output) || output[key] < parsedValue) {
|
|
45589
|
+
output[key] = parsedValue;
|
|
45590
|
+
}
|
|
45591
|
+
} else if (!(key in output) || output[key] > parsedValue) {
|
|
45592
|
+
output[key] = parsedValue;
|
|
45593
|
+
}
|
|
45380
45594
|
|
|
45381
45595
|
break
|
|
45382
45596
|
}
|
|
45383
45597
|
case 'private':
|
|
45384
45598
|
case 'no-cache': {
|
|
45599
|
+
if (fromMalformedQuote) {
|
|
45600
|
+
output[key] = true;
|
|
45601
|
+
break
|
|
45602
|
+
}
|
|
45603
|
+
|
|
45604
|
+
if (value !== undefined && value.length === 0) {
|
|
45605
|
+
output[key] = true;
|
|
45606
|
+
break
|
|
45607
|
+
}
|
|
45608
|
+
|
|
45385
45609
|
if (value) {
|
|
45386
45610
|
// The private and no-cache directives can be unqualified (aka just
|
|
45387
45611
|
// `private` or `no-cache`) or qualified (w/ a value). When they're
|
|
@@ -45389,45 +45613,64 @@ function requireCache$2 () {
|
|
|
45389
45613
|
// `no-cache="header1"`, or `no-cache="header1, header2"`
|
|
45390
45614
|
// If we're given multiple headers, the comma messes us up since
|
|
45391
45615
|
// we split the full header by commas. So, let's loop through the
|
|
45392
|
-
// remaining parts in front of us until we find one that
|
|
45393
|
-
// quote. We can then
|
|
45394
|
-
//
|
|
45395
|
-
// and continue parsing like normal.
|
|
45616
|
+
// remaining parts in front of us until we find one that contains a
|
|
45617
|
+
// closing quote. We can then skip the consumed quoted-list fragments and
|
|
45618
|
+
// continue parsing like normal.
|
|
45396
45619
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-no-cache-2
|
|
45397
45620
|
if (value[0] === '"') {
|
|
45398
45621
|
// Something like `no-cache="some-header"` OR `no-cache="some-header, another-header"`.
|
|
45622
|
+
value = trimOWSEnd(value);
|
|
45399
45623
|
|
|
45400
|
-
|
|
45401
|
-
|
|
45624
|
+
let fieldList = '';
|
|
45625
|
+
let lastQuotedPart = i;
|
|
45626
|
+
let foundEndingQuote = false;
|
|
45627
|
+
const closingQuote = findUnescapedQuote(value, 1);
|
|
45402
45628
|
|
|
45403
|
-
|
|
45404
|
-
|
|
45629
|
+
if (closingQuote !== -1) {
|
|
45630
|
+
fieldList = value.substring(1, closingQuote);
|
|
45631
|
+
foundEndingQuote = true;
|
|
45632
|
+
} else {
|
|
45405
45633
|
// Something like `no-cache="some-header, another-header"`
|
|
45406
45634
|
// This can still be something invalid, e.g. `no-cache="some-header, ...`
|
|
45635
|
+
const fieldListParts = [value.substring(1)];
|
|
45636
|
+
|
|
45407
45637
|
for (let j = i + 1; j < directives.length; j++) {
|
|
45408
|
-
const nextPart = directives[j];
|
|
45409
|
-
const
|
|
45638
|
+
const nextPart = trimOWS(directives[j].value);
|
|
45639
|
+
const closingQuote = findUnescapedQuote(nextPart, 0);
|
|
45410
45640
|
|
|
45411
|
-
|
|
45641
|
+
lastQuotedPart = j;
|
|
45412
45642
|
|
|
45413
|
-
if (
|
|
45643
|
+
if (closingQuote !== -1) {
|
|
45644
|
+
fieldListParts.push(nextPart.substring(0, closingQuote));
|
|
45414
45645
|
foundEndingQuote = true;
|
|
45415
45646
|
break
|
|
45416
45647
|
}
|
|
45648
|
+
|
|
45649
|
+
fieldListParts.push(nextPart);
|
|
45417
45650
|
}
|
|
45651
|
+
|
|
45652
|
+
fieldList = fieldListParts.join(',');
|
|
45418
45653
|
}
|
|
45419
45654
|
|
|
45420
|
-
if (foundEndingQuote) {
|
|
45421
|
-
|
|
45422
|
-
|
|
45423
|
-
|
|
45424
|
-
headers[headers.length - 1] = lastHeader;
|
|
45425
|
-
}
|
|
45655
|
+
if (!foundEndingQuote) {
|
|
45656
|
+
output[key] = true;
|
|
45657
|
+
break
|
|
45658
|
+
}
|
|
45426
45659
|
|
|
45427
|
-
|
|
45428
|
-
|
|
45660
|
+
i = lastQuotedPart;
|
|
45661
|
+
|
|
45662
|
+
const headers = fieldList.split(',');
|
|
45663
|
+
let validFieldNames = true;
|
|
45664
|
+
for (let j = 0; j < headers.length; j++) {
|
|
45665
|
+
headers[j] = trimOWS(headers[j]);
|
|
45666
|
+
if (!isValidHTTPToken(headers[j])) {
|
|
45667
|
+
validFieldNames = false;
|
|
45429
45668
|
}
|
|
45669
|
+
}
|
|
45430
45670
|
|
|
45671
|
+
if (!validFieldNames) {
|
|
45672
|
+
output[key] = true;
|
|
45673
|
+
} else if (output[key] !== true) {
|
|
45431
45674
|
if (key in output) {
|
|
45432
45675
|
output[key] = output[key].concat(headers);
|
|
45433
45676
|
} else {
|
|
@@ -45435,13 +45678,17 @@ function requireCache$2 () {
|
|
|
45435
45678
|
}
|
|
45436
45679
|
}
|
|
45437
45680
|
} else {
|
|
45438
|
-
// Something like `no-cache=
|
|
45439
|
-
const fieldName = value
|
|
45681
|
+
// Something like `no-cache=some-header`
|
|
45682
|
+
const fieldName = trimOWS(value);
|
|
45440
45683
|
|
|
45441
|
-
if (
|
|
45442
|
-
output[key] =
|
|
45443
|
-
} else {
|
|
45444
|
-
|
|
45684
|
+
if (!isValidHTTPToken(fieldName)) {
|
|
45685
|
+
output[key] = true;
|
|
45686
|
+
} else if (output[key] !== true) {
|
|
45687
|
+
if (key in output) {
|
|
45688
|
+
output[key] = output[key].concat(fieldName);
|
|
45689
|
+
} else {
|
|
45690
|
+
output[key] = [fieldName];
|
|
45691
|
+
}
|
|
45445
45692
|
}
|
|
45446
45693
|
}
|
|
45447
45694
|
|
|
@@ -45450,19 +45697,27 @@ function requireCache$2 () {
|
|
|
45450
45697
|
}
|
|
45451
45698
|
// eslint-disable-next-line no-fallthrough
|
|
45452
45699
|
case 'public':
|
|
45453
|
-
case 'no-store':
|
|
45454
45700
|
case 'must-revalidate':
|
|
45455
45701
|
case 'proxy-revalidate':
|
|
45456
45702
|
case 'immutable':
|
|
45457
45703
|
case 'no-transform':
|
|
45458
45704
|
case 'must-understand':
|
|
45459
45705
|
case 'only-if-cached':
|
|
45460
|
-
if (
|
|
45706
|
+
if (fromMalformedQuote || invalidNoArgumentDirectives.has(key)) {
|
|
45707
|
+
continue
|
|
45708
|
+
}
|
|
45709
|
+
|
|
45710
|
+
if (value !== undefined) {
|
|
45461
45711
|
// These are qualified (something like `public=...`) when they aren't
|
|
45462
|
-
// allowed to be, skip
|
|
45712
|
+
// allowed to be, skip all instances of the malformed directive.
|
|
45713
|
+
delete output[key];
|
|
45714
|
+
invalidNoArgumentDirectives.add(key);
|
|
45463
45715
|
continue
|
|
45464
45716
|
}
|
|
45465
45717
|
|
|
45718
|
+
output[key] = true;
|
|
45719
|
+
break
|
|
45720
|
+
case 'no-store':
|
|
45466
45721
|
output[key] = true;
|
|
45467
45722
|
break
|
|
45468
45723
|
default:
|
|
@@ -45474,31 +45729,79 @@ function requireCache$2 () {
|
|
|
45474
45729
|
return output
|
|
45475
45730
|
}
|
|
45476
45731
|
|
|
45732
|
+
/**
|
|
45733
|
+
* @param {string | string[]} varyHeader Vary header from the server
|
|
45734
|
+
* @returns {string[]}
|
|
45735
|
+
*/
|
|
45736
|
+
function splitVaryHeader (varyHeader) {
|
|
45737
|
+
const values = Array.isArray(varyHeader) ? varyHeader : [varyHeader];
|
|
45738
|
+
const output = [];
|
|
45739
|
+
|
|
45740
|
+
for (let i = 0; i < values.length; i++) {
|
|
45741
|
+
const parts = values[i].split(',');
|
|
45742
|
+
for (let j = 0; j < parts.length; j++) {
|
|
45743
|
+
output.push(parts[j]);
|
|
45744
|
+
}
|
|
45745
|
+
}
|
|
45746
|
+
|
|
45747
|
+
return output
|
|
45748
|
+
}
|
|
45749
|
+
|
|
45750
|
+
/**
|
|
45751
|
+
* @param {string | string[]} varyHeader Vary header from the server
|
|
45752
|
+
* @returns {boolean}
|
|
45753
|
+
*/
|
|
45754
|
+
function hasVaryStar (varyHeader) {
|
|
45755
|
+
const values = splitVaryHeader(varyHeader);
|
|
45756
|
+
for (let i = 0; i < values.length; i++) {
|
|
45757
|
+
if (trimOWS(values[i]).indexOf('*') !== -1) {
|
|
45758
|
+
return true
|
|
45759
|
+
}
|
|
45760
|
+
}
|
|
45761
|
+
|
|
45762
|
+
return false
|
|
45763
|
+
}
|
|
45764
|
+
|
|
45477
45765
|
/**
|
|
45478
45766
|
* @param {string | string[]} varyHeader Vary header from the server
|
|
45479
45767
|
* @param {Record<string, string | string[]>} headers Request headers
|
|
45480
|
-
* @returns {Record<string, string | string[]>}
|
|
45768
|
+
* @returns {Record<string, string | string[] | null> | undefined}
|
|
45481
45769
|
*/
|
|
45482
45770
|
function parseVaryHeader (varyHeader, headers) {
|
|
45483
|
-
if (
|
|
45771
|
+
if (hasVaryStar(varyHeader)) {
|
|
45484
45772
|
return headers
|
|
45485
45773
|
}
|
|
45486
45774
|
|
|
45487
45775
|
const output = /** @type {Record<string, string | string[] | null>} */ ({});
|
|
45488
45776
|
|
|
45489
|
-
const varyingHeaders =
|
|
45490
|
-
? varyHeader.split(',')
|
|
45491
|
-
: varyHeader;
|
|
45777
|
+
const varyingHeaders = splitVaryHeader(varyHeader);
|
|
45492
45778
|
|
|
45493
45779
|
for (const header of varyingHeaders) {
|
|
45494
|
-
const trimmedHeader = header
|
|
45780
|
+
const trimmedHeader = trimOWS(header).toLowerCase();
|
|
45781
|
+
|
|
45782
|
+
if (trimmedHeader.length === 0) {
|
|
45783
|
+
continue
|
|
45784
|
+
}
|
|
45785
|
+
|
|
45786
|
+
if (!isValidHTTPToken(trimmedHeader)) {
|
|
45787
|
+
return undefined
|
|
45788
|
+
}
|
|
45495
45789
|
|
|
45496
|
-
|
|
45790
|
+
const headerValue = headers[trimmedHeader];
|
|
45791
|
+
output[trimmedHeader] = Array.isArray(headerValue) ? headerValue.slice() : headerValue ?? null;
|
|
45497
45792
|
}
|
|
45498
45793
|
|
|
45499
45794
|
return output
|
|
45500
45795
|
}
|
|
45501
45796
|
|
|
45797
|
+
/**
|
|
45798
|
+
* @param {string | string[]} varyHeader Vary header from the server
|
|
45799
|
+
* @returns {boolean}
|
|
45800
|
+
*/
|
|
45801
|
+
function isInvalidOrWildcardVaryHeader (varyHeader) {
|
|
45802
|
+
return hasVaryStar(varyHeader) || parseVaryHeader(varyHeader, {}) === undefined
|
|
45803
|
+
}
|
|
45804
|
+
|
|
45502
45805
|
/**
|
|
45503
45806
|
* Note: this deviates from the spec a little. Empty etags ("", W/"") are valid,
|
|
45504
45807
|
* however, including them in cached resposnes serves little to no purpose.
|
|
@@ -45562,7 +45865,7 @@ function requireCache$2 () {
|
|
|
45562
45865
|
}
|
|
45563
45866
|
|
|
45564
45867
|
for (const method of methods) {
|
|
45565
|
-
if (!safeHTTPMethods
|
|
45868
|
+
if (!arrayIncludes(safeHTTPMethods, method)) {
|
|
45566
45869
|
throw new TypeError(`element of ${name}-array needs to be one of following values: ${safeHTTPMethods.join(', ')}, got ${method}`)
|
|
45567
45870
|
}
|
|
45568
45871
|
}
|
|
@@ -45602,7 +45905,10 @@ function requireCache$2 () {
|
|
|
45602
45905
|
assertCacheKey,
|
|
45603
45906
|
assertCacheValue,
|
|
45604
45907
|
parseCacheControlHeader,
|
|
45908
|
+
hasInvalidCacheControlDirective,
|
|
45605
45909
|
parseVaryHeader,
|
|
45910
|
+
hasVaryStar,
|
|
45911
|
+
isInvalidOrWildcardVaryHeader,
|
|
45606
45912
|
isEtagUsable,
|
|
45607
45913
|
assertCacheMethods,
|
|
45608
45914
|
assertCacheStore,
|
|
@@ -45636,6 +45942,26 @@ function requireDate () {
|
|
|
45636
45942
|
}
|
|
45637
45943
|
}
|
|
45638
45944
|
|
|
45945
|
+
function makeDate (year, monthIdx, day, hour, minute, second, weekday) {
|
|
45946
|
+
const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second));
|
|
45947
|
+
|
|
45948
|
+
// Date.UTC treats years 0-99 as 1900-1999. Reset the full year so component
|
|
45949
|
+
// checks below validate the HTTP date as written.
|
|
45950
|
+
if (year >= 0 && year <= 99) {
|
|
45951
|
+
result.setUTCFullYear(year);
|
|
45952
|
+
}
|
|
45953
|
+
|
|
45954
|
+
return result.getUTCFullYear() === year &&
|
|
45955
|
+
result.getUTCMonth() === monthIdx &&
|
|
45956
|
+
result.getUTCDate() === day &&
|
|
45957
|
+
result.getUTCHours() === hour &&
|
|
45958
|
+
result.getUTCMinutes() === minute &&
|
|
45959
|
+
result.getUTCSeconds() === second &&
|
|
45960
|
+
result.getUTCDay() === weekday
|
|
45961
|
+
? result
|
|
45962
|
+
: undefined
|
|
45963
|
+
}
|
|
45964
|
+
|
|
45639
45965
|
/**
|
|
45640
45966
|
* @see https://httpwg.org/specs/rfc9110.html#preferred.date.format
|
|
45641
45967
|
*
|
|
@@ -45842,8 +46168,7 @@ function requireDate () {
|
|
|
45842
46168
|
second = (code1 - 48) * 10 + (code2 - 48); // Convert ASCII codes to number
|
|
45843
46169
|
}
|
|
45844
46170
|
|
|
45845
|
-
|
|
45846
|
-
return result.getUTCDay() === weekday ? result : undefined
|
|
46171
|
+
return makeDate(year, monthIdx, day, hour, minute, second, weekday)
|
|
45847
46172
|
}
|
|
45848
46173
|
|
|
45849
46174
|
/**
|
|
@@ -46047,8 +46372,7 @@ function requireDate () {
|
|
|
46047
46372
|
}
|
|
46048
46373
|
const year = (yearDigit1 - 48) * 1000 + (yearDigit2 - 48) * 100 + (yearDigit3 - 48) * 10 + (yearDigit4 - 48);
|
|
46049
46374
|
|
|
46050
|
-
|
|
46051
|
-
return result.getUTCDay() === weekday ? result : undefined
|
|
46375
|
+
return makeDate(year, monthIdx, day, hour, minute, second, weekday)
|
|
46052
46376
|
}
|
|
46053
46377
|
|
|
46054
46378
|
/**
|
|
@@ -46262,8 +46586,7 @@ function requireDate () {
|
|
|
46262
46586
|
second = (code1 - 48) * 10 + (code2 - 48); // Convert ASCII codes to number
|
|
46263
46587
|
}
|
|
46264
46588
|
|
|
46265
|
-
|
|
46266
|
-
return result.getUTCDay() === weekday ? result : undefined
|
|
46589
|
+
return makeDate(year, monthIdx, day, hour, minute, second, weekday)
|
|
46267
46590
|
}
|
|
46268
46591
|
|
|
46269
46592
|
date = {
|
|
@@ -46282,7 +46605,10 @@ function requireCacheHandler () {
|
|
|
46282
46605
|
const util = requireUtil$7();
|
|
46283
46606
|
const {
|
|
46284
46607
|
parseCacheControlHeader,
|
|
46608
|
+
hasInvalidCacheControlDirective,
|
|
46285
46609
|
parseVaryHeader,
|
|
46610
|
+
hasVaryStar,
|
|
46611
|
+
isInvalidOrWildcardVaryHeader,
|
|
46286
46612
|
isEtagUsable
|
|
46287
46613
|
} = requireCache$2();
|
|
46288
46614
|
const { parseHttpDate } = requireDate();
|
|
@@ -46305,6 +46631,92 @@ function requireCacheHandler () {
|
|
|
46305
46631
|
|
|
46306
46632
|
const MAX_RESPONSE_AGE = 2147483647000;
|
|
46307
46633
|
|
|
46634
|
+
function trimOWS (value) {
|
|
46635
|
+
return value.replace(/^[\t ]+|[\t ]+$/g, '')
|
|
46636
|
+
}
|
|
46637
|
+
|
|
46638
|
+
function arrayIncludes (array, value) {
|
|
46639
|
+
for (let i = 0; i < array.length; i++) {
|
|
46640
|
+
if (array[i] === value) {
|
|
46641
|
+
return true
|
|
46642
|
+
}
|
|
46643
|
+
}
|
|
46644
|
+
|
|
46645
|
+
return false
|
|
46646
|
+
}
|
|
46647
|
+
|
|
46648
|
+
function appendConnectionHeaderTokens (headersToRemove, connectionHeader) {
|
|
46649
|
+
const values = Array.isArray(connectionHeader) ? connectionHeader : [connectionHeader];
|
|
46650
|
+
|
|
46651
|
+
for (let i = 0; i < values.length; i++) {
|
|
46652
|
+
const tokens = values[i].split(',');
|
|
46653
|
+
for (let j = 0; j < tokens.length; j++) {
|
|
46654
|
+
headersToRemove.push(trimOWS(tokens[j]).toLowerCase());
|
|
46655
|
+
}
|
|
46656
|
+
}
|
|
46657
|
+
}
|
|
46658
|
+
|
|
46659
|
+
function getSameOriginPath (cacheKey, location) {
|
|
46660
|
+
if (typeof location !== 'string') {
|
|
46661
|
+
return undefined
|
|
46662
|
+
}
|
|
46663
|
+
|
|
46664
|
+
let originUrl;
|
|
46665
|
+
let requestUrl;
|
|
46666
|
+
let locationUrl;
|
|
46667
|
+
try {
|
|
46668
|
+
originUrl = new URL(cacheKey.origin);
|
|
46669
|
+
requestUrl = new URL(cacheKey.path, originUrl);
|
|
46670
|
+
locationUrl = new URL(location, requestUrl);
|
|
46671
|
+
} catch {
|
|
46672
|
+
return undefined
|
|
46673
|
+
}
|
|
46674
|
+
|
|
46675
|
+
if (locationUrl.origin !== originUrl.origin) {
|
|
46676
|
+
return undefined
|
|
46677
|
+
}
|
|
46678
|
+
|
|
46679
|
+
return locationUrl.pathname + locationUrl.search
|
|
46680
|
+
}
|
|
46681
|
+
|
|
46682
|
+
function deleteCachedUri (store, cacheKey, path) {
|
|
46683
|
+
deleteCachedValue(store, {
|
|
46684
|
+
...cacheKey,
|
|
46685
|
+
path
|
|
46686
|
+
});
|
|
46687
|
+
|
|
46688
|
+
for (let i = 0; i < util.safeHTTPMethods.length; i++) {
|
|
46689
|
+
const method = util.safeHTTPMethods[i];
|
|
46690
|
+
if (method !== cacheKey.method) {
|
|
46691
|
+
deleteCachedValue(store, {
|
|
46692
|
+
...cacheKey,
|
|
46693
|
+
method,
|
|
46694
|
+
path
|
|
46695
|
+
});
|
|
46696
|
+
}
|
|
46697
|
+
}
|
|
46698
|
+
}
|
|
46699
|
+
|
|
46700
|
+
function deleteLocationTargets (store, cacheKey, headerValue) {
|
|
46701
|
+
if (headerValue === undefined) {
|
|
46702
|
+
return
|
|
46703
|
+
}
|
|
46704
|
+
|
|
46705
|
+
const values = Array.isArray(headerValue) ? headerValue : [headerValue];
|
|
46706
|
+
for (let i = 0; i < values.length; i++) {
|
|
46707
|
+
const path = getSameOriginPath(cacheKey, values[i]);
|
|
46708
|
+
if (path !== undefined) {
|
|
46709
|
+
deleteCachedUri(store, cacheKey, path);
|
|
46710
|
+
}
|
|
46711
|
+
}
|
|
46712
|
+
}
|
|
46713
|
+
|
|
46714
|
+
function invalidateUnsafeRequest (store, cacheKey, resHeaders) {
|
|
46715
|
+
deleteCachedUri(store, cacheKey, cacheKey.path);
|
|
46716
|
+
deleteLocationTargets(store, cacheKey, resHeaders.location);
|
|
46717
|
+
deleteLocationTargets(store, cacheKey, resHeaders['content-location']);
|
|
46718
|
+
}
|
|
46719
|
+
|
|
46308
46720
|
/**
|
|
46309
46721
|
* @typedef {import('../../types/dispatcher.d.ts').default.DispatchHandler} DispatchHandler
|
|
46310
46722
|
*
|
|
@@ -46386,28 +46798,28 @@ function requireCacheHandler () {
|
|
|
46386
46798
|
const handler = this;
|
|
46387
46799
|
|
|
46388
46800
|
if (
|
|
46389
|
-
!util.safeHTTPMethods
|
|
46801
|
+
!arrayIncludes(util.safeHTTPMethods, this.#cacheKey.method) &&
|
|
46390
46802
|
statusCode >= 200 &&
|
|
46391
46803
|
statusCode <= 399
|
|
46392
46804
|
) {
|
|
46393
46805
|
// Successful response to an unsafe method, delete it from cache
|
|
46394
46806
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-invalidating-stored-response
|
|
46395
|
-
|
|
46396
|
-
this.#store.delete(this.#cacheKey)?.catch?.(noop);
|
|
46397
|
-
} catch {
|
|
46398
|
-
// Fail silently
|
|
46399
|
-
}
|
|
46807
|
+
invalidateUnsafeRequest(this.#store, this.#cacheKey, resHeaders);
|
|
46400
46808
|
return downstreamOnHeaders()
|
|
46401
46809
|
}
|
|
46402
46810
|
|
|
46403
46811
|
const cacheControlHeader = resHeaders['cache-control'];
|
|
46404
|
-
const heuristicallyCacheable = resHeaders['last-modified'] && HEURISTICALLY_CACHEABLE_STATUS_CODES
|
|
46812
|
+
const heuristicallyCacheable = resHeaders['last-modified'] && arrayIncludes(HEURISTICALLY_CACHEABLE_STATUS_CODES, statusCode);
|
|
46405
46813
|
if (
|
|
46406
46814
|
!cacheControlHeader &&
|
|
46407
46815
|
!resHeaders['expires'] &&
|
|
46408
46816
|
!heuristicallyCacheable &&
|
|
46409
46817
|
!this.#cacheByDefault
|
|
46410
46818
|
) {
|
|
46819
|
+
if (statusCode === 304 && resHeaders.vary && isInvalidOrWildcardVaryHeader(resHeaders.vary)) {
|
|
46820
|
+
deleteCachedValue(this.#store, this.#cacheKey);
|
|
46821
|
+
}
|
|
46822
|
+
|
|
46411
46823
|
// Don't have anything to tell us this response is cachable and we're not
|
|
46412
46824
|
// caching by default
|
|
46413
46825
|
return downstreamOnHeaders()
|
|
@@ -46415,31 +46827,46 @@ function requireCacheHandler () {
|
|
|
46415
46827
|
|
|
46416
46828
|
const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {};
|
|
46417
46829
|
if (!canCacheResponse(this.#cacheType, statusCode, resHeaders, cacheControlDirectives, this.#cacheKey.headers)) {
|
|
46830
|
+
if (statusCode === 304 && (cacheControlHeader || revalidationResponseDisallowsCachedReuse(this.#cacheType, resHeaders, cacheControlDirectives))) {
|
|
46831
|
+
deleteCachedValue(this.#store, this.#cacheKey);
|
|
46832
|
+
}
|
|
46833
|
+
|
|
46418
46834
|
return downstreamOnHeaders()
|
|
46419
46835
|
}
|
|
46420
46836
|
|
|
46421
46837
|
const now = Date.now();
|
|
46422
|
-
const resAge = resHeaders
|
|
46423
|
-
if (resAge && resAge >= MAX_RESPONSE_AGE) {
|
|
46838
|
+
const resAge = Object.hasOwn(resHeaders, 'age') ? getAge(resHeaders.age) : undefined;
|
|
46839
|
+
if (resAge !== undefined && resAge >= MAX_RESPONSE_AGE) {
|
|
46424
46840
|
// Response considered stale
|
|
46841
|
+
deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey);
|
|
46425
46842
|
return downstreamOnHeaders()
|
|
46426
46843
|
}
|
|
46427
46844
|
|
|
46428
|
-
const resDate =
|
|
46429
|
-
|
|
46430
|
-
|
|
46845
|
+
const resDate = Object.hasOwn(resHeaders, 'date') ? getDate(resHeaders.date) : undefined;
|
|
46846
|
+
if (resDate === null) {
|
|
46847
|
+
deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey);
|
|
46848
|
+
return downstreamOnHeaders()
|
|
46849
|
+
}
|
|
46850
|
+
|
|
46851
|
+
const apparentAge = resDate ? Math.max(0, now - resDate.getTime()) : 0;
|
|
46852
|
+
const currentAge = Math.max(apparentAge, resAge ?? 0);
|
|
46431
46853
|
|
|
46432
46854
|
const staleAt =
|
|
46433
46855
|
determineStaleAt(this.#cacheType, now, resAge, resHeaders, resDate, cacheControlDirectives) ??
|
|
46434
46856
|
this.#cacheByDefault;
|
|
46435
|
-
if (staleAt === undefined ||
|
|
46857
|
+
if (staleAt === undefined || currentAge >= staleAt) {
|
|
46858
|
+
if (cacheControlHeader || staleAt !== undefined) {
|
|
46859
|
+
deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey);
|
|
46860
|
+
}
|
|
46861
|
+
|
|
46436
46862
|
return downstreamOnHeaders()
|
|
46437
46863
|
}
|
|
46438
46864
|
|
|
46439
|
-
const baseTime =
|
|
46865
|
+
const baseTime = now - currentAge;
|
|
46440
46866
|
const absoluteStaleAt = staleAt + baseTime;
|
|
46441
46867
|
if (now >= absoluteStaleAt) {
|
|
46442
46868
|
// Response is already stale
|
|
46869
|
+
deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey);
|
|
46443
46870
|
return downstreamOnHeaders()
|
|
46444
46871
|
}
|
|
46445
46872
|
|
|
@@ -46452,7 +46879,8 @@ function requireCacheHandler () {
|
|
|
46452
46879
|
}
|
|
46453
46880
|
}
|
|
46454
46881
|
|
|
46455
|
-
const
|
|
46882
|
+
const cachedAt = baseTime;
|
|
46883
|
+
const deleteAt = determineDeleteAt(baseTime, now, cacheControlDirectives, absoluteStaleAt);
|
|
46456
46884
|
const strippedHeaders = stripNecessaryHeaders(resHeaders, cacheControlDirectives);
|
|
46457
46885
|
|
|
46458
46886
|
/**
|
|
@@ -46464,7 +46892,7 @@ function requireCacheHandler () {
|
|
|
46464
46892
|
headers: strippedHeaders,
|
|
46465
46893
|
vary: varyDirectives,
|
|
46466
46894
|
cacheControlDirectives,
|
|
46467
|
-
cachedAt
|
|
46895
|
+
cachedAt,
|
|
46468
46896
|
staleAt: absoluteStaleAt,
|
|
46469
46897
|
deleteAt
|
|
46470
46898
|
};
|
|
@@ -46482,6 +46910,7 @@ function requireCacheHandler () {
|
|
|
46482
46910
|
value.statusCode = cachedValue.statusCode;
|
|
46483
46911
|
value.statusMessage = cachedValue.statusMessage;
|
|
46484
46912
|
value.etag = cachedValue.etag;
|
|
46913
|
+
value.vary = varyDirectives ?? cachedValue.vary;
|
|
46485
46914
|
value.headers = { ...cachedValue.headers, ...strippedHeaders };
|
|
46486
46915
|
|
|
46487
46916
|
downstreamOnHeaders();
|
|
@@ -46612,6 +47041,36 @@ function requireCacheHandler () {
|
|
|
46612
47041
|
}
|
|
46613
47042
|
}
|
|
46614
47043
|
|
|
47044
|
+
/**
|
|
47045
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheStore} store
|
|
47046
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey
|
|
47047
|
+
*/
|
|
47048
|
+
function deleteCachedValue (store, cacheKey) {
|
|
47049
|
+
try {
|
|
47050
|
+
store.delete(cacheKey)?.catch?.(noop);
|
|
47051
|
+
} catch {
|
|
47052
|
+
// Fail silently
|
|
47053
|
+
}
|
|
47054
|
+
}
|
|
47055
|
+
|
|
47056
|
+
function deleteCachedValueIfNotModified (statusCode, store, cacheKey) {
|
|
47057
|
+
if (statusCode === 304) {
|
|
47058
|
+
deleteCachedValue(store, cacheKey);
|
|
47059
|
+
}
|
|
47060
|
+
}
|
|
47061
|
+
|
|
47062
|
+
/**
|
|
47063
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47064
|
+
* @param {import('../../types/header.d.ts').IncomingHttpHeaders} resHeaders
|
|
47065
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives
|
|
47066
|
+
* @returns {boolean}
|
|
47067
|
+
*/
|
|
47068
|
+
function revalidationResponseDisallowsCachedReuse (cacheType, resHeaders, cacheControlDirectives) {
|
|
47069
|
+
return cacheControlDirectives['no-store'] === true ||
|
|
47070
|
+
(cacheType === 'shared' && cacheControlDirectives.private === true) ||
|
|
47071
|
+
(resHeaders.vary ? isInvalidOrWildcardVaryHeader(resHeaders.vary) : false)
|
|
47072
|
+
}
|
|
47073
|
+
|
|
46615
47074
|
/**
|
|
46616
47075
|
* @see https://www.rfc-editor.org/rfc/rfc9111.html#name-storing-responses-to-authen
|
|
46617
47076
|
*
|
|
@@ -46623,12 +47082,12 @@ function requireCacheHandler () {
|
|
|
46623
47082
|
*/
|
|
46624
47083
|
function canCacheResponse (cacheType, statusCode, resHeaders, cacheControlDirectives, reqHeaders) {
|
|
46625
47084
|
// Status code must be final and understood.
|
|
46626
|
-
if (statusCode < 200 || NOT_UNDERSTOOD_STATUS_CODES
|
|
47085
|
+
if (statusCode < 200 || arrayIncludes(NOT_UNDERSTOOD_STATUS_CODES, statusCode)) {
|
|
46627
47086
|
return false
|
|
46628
47087
|
}
|
|
46629
47088
|
// Responses with neither status codes that are heuristically cacheable, nor "explicit enough" caching
|
|
46630
47089
|
// directives, are not cacheable. "Explicit enough": see https://www.rfc-editor.org/rfc/rfc9111.html#section-3
|
|
46631
|
-
if (!HEURISTICALLY_CACHEABLE_STATUS_CODES
|
|
47090
|
+
if (!arrayIncludes(HEURISTICALLY_CACHEABLE_STATUS_CODES, statusCode) && !resHeaders['expires'] &&
|
|
46632
47091
|
!cacheControlDirectives.public &&
|
|
46633
47092
|
cacheControlDirectives['max-age'] === undefined &&
|
|
46634
47093
|
// RFC 9111: a private response directive, if the cache is not shared
|
|
@@ -46647,12 +47106,12 @@ function requireCacheHandler () {
|
|
|
46647
47106
|
}
|
|
46648
47107
|
|
|
46649
47108
|
// https://www.rfc-editor.org/rfc/rfc9111.html#section-4.1-5
|
|
46650
|
-
if (resHeaders.vary
|
|
47109
|
+
if (resHeaders.vary && hasVaryStar(resHeaders.vary)) {
|
|
46651
47110
|
return false
|
|
46652
47111
|
}
|
|
46653
47112
|
|
|
46654
47113
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-storing-responses-to-authen
|
|
46655
|
-
if (reqHeaders
|
|
47114
|
+
if (reqHeaders != null && Object.hasOwn(reqHeaders, 'authorization')) {
|
|
46656
47115
|
if (
|
|
46657
47116
|
!cacheControlDirectives.public &&
|
|
46658
47117
|
!cacheControlDirectives['s-maxage'] &&
|
|
@@ -46667,14 +47126,14 @@ function requireCacheHandler () {
|
|
|
46667
47126
|
|
|
46668
47127
|
if (
|
|
46669
47128
|
Array.isArray(cacheControlDirectives['no-cache']) &&
|
|
46670
|
-
cacheControlDirectives['no-cache']
|
|
47129
|
+
arrayIncludes(cacheControlDirectives['no-cache'], 'authorization')
|
|
46671
47130
|
) {
|
|
46672
47131
|
return false
|
|
46673
47132
|
}
|
|
46674
47133
|
|
|
46675
47134
|
if (
|
|
46676
47135
|
Array.isArray(cacheControlDirectives['private']) &&
|
|
46677
|
-
cacheControlDirectives['private']
|
|
47136
|
+
arrayIncludes(cacheControlDirectives['private'], 'authorization')
|
|
46678
47137
|
) {
|
|
46679
47138
|
return false
|
|
46680
47139
|
}
|
|
@@ -46683,14 +47142,51 @@ function requireCacheHandler () {
|
|
|
46683
47142
|
return true
|
|
46684
47143
|
}
|
|
46685
47144
|
|
|
47145
|
+
/**
|
|
47146
|
+
* @param {string | string[]} dateHeader
|
|
47147
|
+
* @returns {Date | null | undefined}
|
|
47148
|
+
*/
|
|
47149
|
+
function getDate (dateHeader) {
|
|
47150
|
+
let dateValue = dateHeader;
|
|
47151
|
+
if (Array.isArray(dateValue)) {
|
|
47152
|
+
if (dateValue.length !== 1) {
|
|
47153
|
+
return null
|
|
47154
|
+
}
|
|
47155
|
+
|
|
47156
|
+
dateValue = dateValue[0];
|
|
47157
|
+
}
|
|
47158
|
+
|
|
47159
|
+
if (typeof dateValue !== 'string') {
|
|
47160
|
+
return null
|
|
47161
|
+
}
|
|
47162
|
+
|
|
47163
|
+
return parseHttpDate(dateValue)
|
|
47164
|
+
}
|
|
47165
|
+
|
|
46686
47166
|
/**
|
|
46687
47167
|
* @param {string | string[]} ageHeader
|
|
46688
47168
|
* @returns {number | undefined}
|
|
46689
47169
|
*/
|
|
46690
47170
|
function getAge (ageHeader) {
|
|
46691
|
-
|
|
47171
|
+
let ageValue = ageHeader;
|
|
47172
|
+
if (Array.isArray(ageValue)) {
|
|
47173
|
+
if (ageValue.length !== 1) {
|
|
47174
|
+
return MAX_RESPONSE_AGE
|
|
47175
|
+
}
|
|
47176
|
+
|
|
47177
|
+
ageValue = ageValue[0];
|
|
47178
|
+
}
|
|
47179
|
+
|
|
47180
|
+
if (typeof ageValue !== 'string' || !/^[\t ]*[0-9]+[\t ]*$/.test(ageValue)) {
|
|
47181
|
+
return MAX_RESPONSE_AGE
|
|
47182
|
+
}
|
|
47183
|
+
|
|
47184
|
+
const age = BigInt(ageValue.replace(/^[\t ]+|[\t ]+$/g, ''));
|
|
47185
|
+
if (age >= BigInt(MAX_RESPONSE_AGE / 1000)) {
|
|
47186
|
+
return MAX_RESPONSE_AGE
|
|
47187
|
+
}
|
|
46692
47188
|
|
|
46693
|
-
return
|
|
47189
|
+
return Number(age) * 1000
|
|
46694
47190
|
}
|
|
46695
47191
|
|
|
46696
47192
|
/**
|
|
@@ -46708,43 +47204,60 @@ function requireCacheHandler () {
|
|
|
46708
47204
|
// Prioritize s-maxage since we're a shared cache
|
|
46709
47205
|
// s-maxage > max-age > Expire
|
|
46710
47206
|
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.10-3
|
|
47207
|
+
if (hasInvalidCacheControlDirective(cacheControlDirectives, 's-maxage')) {
|
|
47208
|
+
return 0
|
|
47209
|
+
}
|
|
47210
|
+
|
|
46711
47211
|
const sMaxAge = cacheControlDirectives['s-maxage'];
|
|
46712
47212
|
if (sMaxAge !== undefined) {
|
|
46713
|
-
return sMaxAge
|
|
47213
|
+
return sMaxAge * 1000
|
|
46714
47214
|
}
|
|
46715
47215
|
}
|
|
46716
47216
|
|
|
47217
|
+
if (hasInvalidCacheControlDirective(cacheControlDirectives, 'max-age')) {
|
|
47218
|
+
return 0
|
|
47219
|
+
}
|
|
47220
|
+
|
|
46717
47221
|
const maxAge = cacheControlDirectives['max-age'];
|
|
46718
47222
|
if (maxAge !== undefined) {
|
|
46719
|
-
return maxAge
|
|
47223
|
+
return maxAge * 1000
|
|
46720
47224
|
}
|
|
46721
47225
|
|
|
46722
|
-
if (
|
|
47226
|
+
if (Object.hasOwn(resHeaders, 'expires')) {
|
|
46723
47227
|
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.3
|
|
47228
|
+
if (typeof resHeaders.expires !== 'string') {
|
|
47229
|
+
return 0
|
|
47230
|
+
}
|
|
47231
|
+
|
|
46724
47232
|
const expiresDate = parseHttpDate(resHeaders.expires);
|
|
46725
|
-
if (expiresDate) {
|
|
46726
|
-
|
|
46727
|
-
|
|
46728
|
-
}
|
|
47233
|
+
if (!expiresDate) {
|
|
47234
|
+
return 0
|
|
47235
|
+
}
|
|
46729
47236
|
|
|
46730
|
-
|
|
46731
|
-
|
|
46732
|
-
|
|
46733
|
-
}
|
|
47237
|
+
if (now >= expiresDate.getTime()) {
|
|
47238
|
+
return 0
|
|
47239
|
+
}
|
|
46734
47240
|
|
|
46735
|
-
|
|
46736
|
-
|
|
46737
|
-
|
|
47241
|
+
if (responseDate) {
|
|
47242
|
+
if (responseDate >= expiresDate) {
|
|
47243
|
+
return 0
|
|
47244
|
+
}
|
|
47245
|
+
|
|
47246
|
+
const freshnessLifetime = expiresDate.getTime() - responseDate.getTime();
|
|
47247
|
+
if (age !== undefined && age >= freshnessLifetime) {
|
|
47248
|
+
return 0
|
|
46738
47249
|
}
|
|
46739
47250
|
|
|
46740
|
-
return
|
|
47251
|
+
return freshnessLifetime
|
|
46741
47252
|
}
|
|
47253
|
+
|
|
47254
|
+
return expiresDate.getTime() - now
|
|
46742
47255
|
}
|
|
46743
47256
|
|
|
46744
47257
|
if (typeof resHeaders['last-modified'] === 'string') {
|
|
46745
47258
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-calculating-heuristic-fresh
|
|
46746
|
-
const lastModified =
|
|
46747
|
-
if (
|
|
47259
|
+
const lastModified = parseHttpDate(resHeaders['last-modified']);
|
|
47260
|
+
if (lastModified) {
|
|
46748
47261
|
if (lastModified.getTime() >= now) {
|
|
46749
47262
|
return undefined
|
|
46750
47263
|
}
|
|
@@ -46757,18 +47270,19 @@ function requireCacheHandler () {
|
|
|
46757
47270
|
|
|
46758
47271
|
if (cacheControlDirectives.immutable) {
|
|
46759
47272
|
// https://www.rfc-editor.org/rfc/rfc8246.html#section-2.2
|
|
46760
|
-
return
|
|
47273
|
+
return 31536000000
|
|
46761
47274
|
}
|
|
46762
47275
|
|
|
46763
47276
|
return undefined
|
|
46764
47277
|
}
|
|
46765
47278
|
|
|
46766
47279
|
/**
|
|
46767
|
-
* @param {number}
|
|
47280
|
+
* @param {number} baseTime
|
|
47281
|
+
* @param {number} cachedAt
|
|
46768
47282
|
* @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives
|
|
46769
47283
|
* @param {number} staleAt
|
|
46770
47284
|
*/
|
|
46771
|
-
function determineDeleteAt (
|
|
47285
|
+
function determineDeleteAt (baseTime, cachedAt, cacheControlDirectives, staleAt) {
|
|
46772
47286
|
let staleWhileRevalidate = -Infinity;
|
|
46773
47287
|
let staleIfError = -Infinity;
|
|
46774
47288
|
let immutable = -Infinity;
|
|
@@ -46782,15 +47296,21 @@ function requireCacheHandler () {
|
|
|
46782
47296
|
}
|
|
46783
47297
|
|
|
46784
47298
|
if (cacheControlDirectives.immutable && staleWhileRevalidate === -Infinity && staleIfError === -Infinity) {
|
|
46785
|
-
immutable =
|
|
47299
|
+
immutable = cachedAt + 31536000000;
|
|
46786
47300
|
}
|
|
46787
47301
|
|
|
46788
47302
|
// When no stale directives or immutable flag, add a revalidation buffer
|
|
46789
47303
|
// equal to the freshness lifetime so the entry survives past staleAt long
|
|
46790
47304
|
// enough to be revalidated instead of silently disappearing.
|
|
47305
|
+
//
|
|
47306
|
+
// Response Date headers only have second precision, so baseTime can trail the
|
|
47307
|
+
// actual cache insertion time by up to ~1s. Pad the buffer by that bounded
|
|
47308
|
+
// skew so short-lived entries do not disappear exactly when they should be
|
|
47309
|
+
// revalidated.
|
|
46791
47310
|
if (staleWhileRevalidate === -Infinity && staleIfError === -Infinity && immutable === -Infinity) {
|
|
46792
|
-
const freshnessLifetime = staleAt -
|
|
46793
|
-
|
|
47311
|
+
const freshnessLifetime = staleAt - baseTime;
|
|
47312
|
+
const datePrecisionPadding = Math.min(Math.max(cachedAt - baseTime, 0), 1000);
|
|
47313
|
+
return staleAt + freshnessLifetime + datePrecisionPadding
|
|
46794
47314
|
}
|
|
46795
47315
|
|
|
46796
47316
|
return Math.max(staleAt, staleWhileRevalidate, staleIfError, immutable)
|
|
@@ -46817,14 +47337,7 @@ function requireCacheHandler () {
|
|
|
46817
47337
|
];
|
|
46818
47338
|
|
|
46819
47339
|
if (resHeaders['connection']) {
|
|
46820
|
-
|
|
46821
|
-
// connection: a
|
|
46822
|
-
// connection: b
|
|
46823
|
-
headersToRemove.push(...resHeaders['connection'].map(header => header.trim()));
|
|
46824
|
-
} else {
|
|
46825
|
-
// connection: a, b
|
|
46826
|
-
headersToRemove.push(...resHeaders['connection'].split(',').map(header => header.trim()));
|
|
46827
|
-
}
|
|
47340
|
+
appendConnectionHeaderTokens(headersToRemove, resHeaders['connection']);
|
|
46828
47341
|
}
|
|
46829
47342
|
|
|
46830
47343
|
if (Array.isArray(cacheControlDirectives['no-cache'])) {
|
|
@@ -46837,7 +47350,7 @@ function requireCacheHandler () {
|
|
|
46837
47350
|
|
|
46838
47351
|
let strippedHeaders;
|
|
46839
47352
|
for (const headerName of headersToRemove) {
|
|
46840
|
-
if (resHeaders
|
|
47353
|
+
if (Object.hasOwn(resHeaders, headerName)) {
|
|
46841
47354
|
strippedHeaders ??= { ...resHeaders };
|
|
46842
47355
|
delete strippedHeaders[headerName];
|
|
46843
47356
|
}
|
|
@@ -46846,14 +47359,6 @@ function requireCacheHandler () {
|
|
|
46846
47359
|
return strippedHeaders ?? resHeaders
|
|
46847
47360
|
}
|
|
46848
47361
|
|
|
46849
|
-
/**
|
|
46850
|
-
* @param {Date} date
|
|
46851
|
-
* @returns {boolean}
|
|
46852
|
-
*/
|
|
46853
|
-
function isValidDate (date) {
|
|
46854
|
-
return date instanceof Date && Number.isFinite(date.valueOf())
|
|
46855
|
-
}
|
|
46856
|
-
|
|
46857
47362
|
cacheHandler = CacheHandler;
|
|
46858
47363
|
return cacheHandler;
|
|
46859
47364
|
}
|
|
@@ -47083,17 +47588,62 @@ function requireMemoryCacheStore () {
|
|
|
47083
47588
|
}
|
|
47084
47589
|
|
|
47085
47590
|
function findEntry (key, entries, now) {
|
|
47086
|
-
|
|
47087
|
-
entry
|
|
47088
|
-
|
|
47089
|
-
|
|
47090
|
-
|
|
47091
|
-
|
|
47591
|
+
for (let i = 0; i < entries.length; i++) {
|
|
47592
|
+
const entry = entries[i];
|
|
47593
|
+
if (
|
|
47594
|
+
entry.deleteAt > now &&
|
|
47595
|
+
entry.method === key.method &&
|
|
47596
|
+
varyMatches(key, entry)
|
|
47597
|
+
) {
|
|
47598
|
+
return entry
|
|
47599
|
+
}
|
|
47600
|
+
}
|
|
47601
|
+
}
|
|
47602
|
+
|
|
47603
|
+
function varyMatches (key, entry) {
|
|
47604
|
+
if (entry.vary == null) {
|
|
47605
|
+
return true
|
|
47606
|
+
}
|
|
47607
|
+
|
|
47608
|
+
for (const headerName in entry.vary) {
|
|
47609
|
+
if (Object.hasOwn(entry.vary, headerName) && !headerValueEquals(key.headers?.[headerName], entry.vary[headerName])) {
|
|
47610
|
+
return false
|
|
47611
|
+
}
|
|
47612
|
+
}
|
|
47613
|
+
|
|
47614
|
+
return true
|
|
47615
|
+
}
|
|
47616
|
+
|
|
47617
|
+
/**
|
|
47618
|
+
* @param {string|string[]|null|undefined} lhs
|
|
47619
|
+
* @param {string|string[]|null|undefined} rhs
|
|
47620
|
+
* @returns {boolean}
|
|
47621
|
+
*/
|
|
47622
|
+
function headerValueEquals (lhs, rhs) {
|
|
47623
|
+
if (lhs == null && rhs == null) {
|
|
47624
|
+
return true
|
|
47625
|
+
}
|
|
47626
|
+
|
|
47627
|
+
if ((lhs == null && rhs != null) ||
|
|
47628
|
+
(lhs != null && rhs == null)) {
|
|
47629
|
+
return false
|
|
47630
|
+
}
|
|
47631
|
+
|
|
47632
|
+
if (Array.isArray(lhs) && Array.isArray(rhs)) {
|
|
47633
|
+
if (lhs.length !== rhs.length) {
|
|
47634
|
+
return false
|
|
47635
|
+
}
|
|
47636
|
+
|
|
47637
|
+
for (let i = 0; i < lhs.length; i++) {
|
|
47638
|
+
if (lhs[i] !== rhs[i]) {
|
|
47639
|
+
return false
|
|
47092
47640
|
}
|
|
47641
|
+
}
|
|
47093
47642
|
|
|
47094
|
-
|
|
47095
|
-
|
|
47096
|
-
|
|
47643
|
+
return true
|
|
47644
|
+
}
|
|
47645
|
+
|
|
47646
|
+
return lhs === rhs
|
|
47097
47647
|
}
|
|
47098
47648
|
|
|
47099
47649
|
memoryCacheStore = MemoryCacheStore;
|
|
@@ -47126,7 +47676,7 @@ function requireCacheRevalidationHandler () {
|
|
|
47126
47676
|
#successful = false
|
|
47127
47677
|
|
|
47128
47678
|
/**
|
|
47129
|
-
* @type {((boolean, any) => void) | null}
|
|
47679
|
+
* @type {((success: boolean, context?: any, statusCode?: number, headers?: import('../../types/header.d.ts').IncomingHttpHeaders) => void) | null}
|
|
47130
47680
|
*/
|
|
47131
47681
|
#callback
|
|
47132
47682
|
|
|
@@ -47143,7 +47693,7 @@ function requireCacheRevalidationHandler () {
|
|
|
47143
47693
|
#allowErrorStatusCodes
|
|
47144
47694
|
|
|
47145
47695
|
/**
|
|
47146
|
-
* @param {(boolean) => void} callback Function to call if the cached value is valid
|
|
47696
|
+
* @param {(success: boolean, context?: any, statusCode?: number, headers?: import('../../types/header.d.ts').IncomingHttpHeaders) => void} callback Function to call if the cached value is valid
|
|
47147
47697
|
* @param {import('../../types/dispatcher.d.ts').default.DispatchHandlers} handler
|
|
47148
47698
|
* @param {boolean} allowErrorStatusCodes
|
|
47149
47699
|
*/
|
|
@@ -47178,7 +47728,7 @@ function requireCacheRevalidationHandler () {
|
|
|
47178
47728
|
// https://datatracker.ietf.org/doc/html/rfc5861#section-4
|
|
47179
47729
|
this.#successful = statusCode === 304 ||
|
|
47180
47730
|
(this.#allowErrorStatusCodes && statusCode >= 500 && statusCode <= 504);
|
|
47181
|
-
this.#callback(this.#successful, this.#context);
|
|
47731
|
+
this.#callback(this.#successful, this.#context, statusCode, headers);
|
|
47182
47732
|
this.#callback = null;
|
|
47183
47733
|
|
|
47184
47734
|
if (this.#successful) {
|
|
@@ -47245,8 +47795,9 @@ function requireCache$1 () {
|
|
|
47245
47795
|
const CacheHandler = requireCacheHandler();
|
|
47246
47796
|
const MemoryCacheStore = requireMemoryCacheStore();
|
|
47247
47797
|
const CacheRevalidationHandler = requireCacheRevalidationHandler();
|
|
47248
|
-
const { assertCacheStore, assertCacheMethods, makeCacheKey, normalizeHeaders, parseCacheControlHeader } = requireCache$2();
|
|
47798
|
+
const { assertCacheStore, assertCacheMethods, makeCacheKey, normalizeHeaders, parseCacheControlHeader, isInvalidOrWildcardVaryHeader } = requireCache$2();
|
|
47249
47799
|
const { AbortError } = requireErrors$1();
|
|
47800
|
+
const { parseHttpDate } = requireDate();
|
|
47250
47801
|
|
|
47251
47802
|
/**
|
|
47252
47803
|
* @param {(string | RegExp)[] | undefined} origins
|
|
@@ -47267,6 +47818,44 @@ function requireCache$1 () {
|
|
|
47267
47818
|
|
|
47268
47819
|
const nop = () => {};
|
|
47269
47820
|
|
|
47821
|
+
function trimOWS (value) {
|
|
47822
|
+
return value.replace(/^[\t ]+|[\t ]+$/g, '')
|
|
47823
|
+
}
|
|
47824
|
+
|
|
47825
|
+
function arrayIncludes (array, value) {
|
|
47826
|
+
for (let i = 0; i < array.length; i++) {
|
|
47827
|
+
if (array[i] === value) {
|
|
47828
|
+
return true
|
|
47829
|
+
}
|
|
47830
|
+
}
|
|
47831
|
+
|
|
47832
|
+
return false
|
|
47833
|
+
}
|
|
47834
|
+
|
|
47835
|
+
function hasPragmaNoCache (headers) {
|
|
47836
|
+
const pragma = headers?.pragma;
|
|
47837
|
+
if (!pragma) {
|
|
47838
|
+
return false
|
|
47839
|
+
}
|
|
47840
|
+
|
|
47841
|
+
const values = Array.isArray(pragma) ? pragma : [pragma];
|
|
47842
|
+
for (let i = 0; i < values.length; i++) {
|
|
47843
|
+
const value = values[i];
|
|
47844
|
+
if (typeof value !== 'string') {
|
|
47845
|
+
continue
|
|
47846
|
+
}
|
|
47847
|
+
|
|
47848
|
+
const directives = value.split(',');
|
|
47849
|
+
for (let j = 0; j < directives.length; j++) {
|
|
47850
|
+
if (trimOWS(directives[j]).toLowerCase() === 'no-cache') {
|
|
47851
|
+
return true
|
|
47852
|
+
}
|
|
47853
|
+
}
|
|
47854
|
+
}
|
|
47855
|
+
|
|
47856
|
+
return false
|
|
47857
|
+
}
|
|
47858
|
+
|
|
47270
47859
|
/**
|
|
47271
47860
|
* @typedef {(options: import('../../types/dispatcher.d.ts').default.DispatchOptions, handler: import('../../types/dispatcher.d.ts').default.DispatchHandler) => void} DispatchFn
|
|
47272
47861
|
*/
|
|
@@ -47296,16 +47885,92 @@ function requireCache$1 () {
|
|
|
47296
47885
|
return false
|
|
47297
47886
|
}
|
|
47298
47887
|
|
|
47888
|
+
/**
|
|
47889
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result
|
|
47890
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47891
|
+
* @returns {boolean}
|
|
47892
|
+
*/
|
|
47893
|
+
function staleResponseRequiresRevalidation (result, cacheType) {
|
|
47894
|
+
return result.cacheControlDirectives?.['must-revalidate'] === true ||
|
|
47895
|
+
(cacheType === 'shared' && (
|
|
47896
|
+
result.cacheControlDirectives?.['proxy-revalidate'] === true ||
|
|
47897
|
+
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.10
|
|
47898
|
+
// s-maxage implies proxy-revalidate for shared caches.
|
|
47899
|
+
result.cacheControlDirectives?.['s-maxage'] !== undefined
|
|
47900
|
+
))
|
|
47901
|
+
}
|
|
47902
|
+
|
|
47903
|
+
/**
|
|
47904
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47905
|
+
* @param {import('../../types/header.d.ts').IncomingHttpHeaders} headers
|
|
47906
|
+
* @returns {boolean}
|
|
47907
|
+
*/
|
|
47908
|
+
function revalidationResponseDisallowsCachedReuse (cacheType, headers) {
|
|
47909
|
+
if (headers.vary && isInvalidOrWildcardVaryHeader(headers.vary)) {
|
|
47910
|
+
return true
|
|
47911
|
+
}
|
|
47912
|
+
|
|
47913
|
+
const cacheControl = headers['cache-control'];
|
|
47914
|
+
if (!cacheControl) {
|
|
47915
|
+
return false
|
|
47916
|
+
}
|
|
47917
|
+
|
|
47918
|
+
const cacheControlDirectives = parseCacheControlHeader(cacheControl);
|
|
47919
|
+
return cacheControlDirectives['no-store'] === true ||
|
|
47920
|
+
(cacheType === 'shared' && cacheControlDirectives.private === true)
|
|
47921
|
+
}
|
|
47922
|
+
|
|
47923
|
+
function revalidationResponseUpdatesCacheControl (headers) {
|
|
47924
|
+
return headers['cache-control'] !== undefined
|
|
47925
|
+
}
|
|
47926
|
+
|
|
47927
|
+
function deleteCachedValue (store, cacheKey) {
|
|
47928
|
+
try {
|
|
47929
|
+
store.delete(cacheKey)?.catch?.(nop);
|
|
47930
|
+
} catch {
|
|
47931
|
+
// Fail silently
|
|
47932
|
+
}
|
|
47933
|
+
}
|
|
47934
|
+
|
|
47935
|
+
function getUsableLastModified (headers) {
|
|
47936
|
+
const lastModified = headers?.['last-modified'];
|
|
47937
|
+
if (typeof lastModified === 'string' && parseHttpDate(lastModified)) {
|
|
47938
|
+
return lastModified
|
|
47939
|
+
}
|
|
47940
|
+
}
|
|
47941
|
+
|
|
47942
|
+
function makeRevalidationHeaders (opts, result) {
|
|
47943
|
+
const headers = {
|
|
47944
|
+
...opts.headers,
|
|
47945
|
+
'if-modified-since': getUsableLastModified(result.headers) ?? new Date(result.cachedAt).toUTCString()
|
|
47946
|
+
};
|
|
47947
|
+
|
|
47948
|
+
if (result.etag) {
|
|
47949
|
+
headers['if-none-match'] = result.etag;
|
|
47950
|
+
}
|
|
47951
|
+
|
|
47952
|
+
if (result.vary) {
|
|
47953
|
+
for (const key in result.vary) {
|
|
47954
|
+
if (result.vary[key] != null) {
|
|
47955
|
+
headers[key] = result.vary[key];
|
|
47956
|
+
}
|
|
47957
|
+
}
|
|
47958
|
+
}
|
|
47959
|
+
|
|
47960
|
+
return headers
|
|
47961
|
+
}
|
|
47962
|
+
|
|
47299
47963
|
/**
|
|
47300
47964
|
* @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result
|
|
47301
47965
|
* @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives | undefined} cacheControlDirectives
|
|
47966
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47302
47967
|
* @returns {boolean}
|
|
47303
47968
|
*/
|
|
47304
|
-
function isStale (result, cacheControlDirectives) {
|
|
47969
|
+
function isStale (result, cacheControlDirectives, cacheType) {
|
|
47305
47970
|
const now = Date.now();
|
|
47306
47971
|
if (now > result.staleAt) {
|
|
47307
47972
|
// Response is stale
|
|
47308
|
-
if (cacheControlDirectives?.['max-stale']) {
|
|
47973
|
+
if (!staleResponseRequiresRevalidation(result, cacheType) && cacheControlDirectives?.['max-stale']) {
|
|
47309
47974
|
// There's a threshold where we can serve stale responses, let's see if
|
|
47310
47975
|
// we're in it
|
|
47311
47976
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-max-stale
|
|
@@ -47332,11 +47997,12 @@ function requireCache$1 () {
|
|
|
47332
47997
|
/**
|
|
47333
47998
|
* Check if we're within the stale-while-revalidate window for a stale response
|
|
47334
47999
|
* @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result
|
|
48000
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47335
48001
|
* @returns {boolean}
|
|
47336
48002
|
*/
|
|
47337
|
-
function withinStaleWhileRevalidateWindow (result) {
|
|
48003
|
+
function withinStaleWhileRevalidateWindow (result, cacheType) {
|
|
47338
48004
|
const staleWhileRevalidate = result.cacheControlDirectives?.['stale-while-revalidate'];
|
|
47339
|
-
if (!staleWhileRevalidate) {
|
|
48005
|
+
if (!staleWhileRevalidate || staleResponseRequiresRevalidation(result, cacheType)) {
|
|
47340
48006
|
return false
|
|
47341
48007
|
}
|
|
47342
48008
|
|
|
@@ -47506,14 +48172,10 @@ function requireCache$1 () {
|
|
|
47506
48172
|
}
|
|
47507
48173
|
|
|
47508
48174
|
const age = Math.round((now - result.cachedAt) / 1000);
|
|
47509
|
-
|
|
47510
|
-
// Response is considered expired for this specific request
|
|
47511
|
-
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.1.1
|
|
47512
|
-
return dispatch(opts, handler)
|
|
47513
|
-
}
|
|
48175
|
+
const requestMaxAgeExpired = reqCacheControl?.['max-age'] !== undefined && age >= reqCacheControl['max-age'];
|
|
47514
48176
|
|
|
47515
|
-
const stale = isStale(result, reqCacheControl);
|
|
47516
|
-
const revalidate = needsRevalidation(result, reqCacheControl, opts);
|
|
48177
|
+
const stale = requestMaxAgeExpired || isStale(result, reqCacheControl, globalOpts.type);
|
|
48178
|
+
const revalidate = requestMaxAgeExpired || needsRevalidation(result, reqCacheControl, opts);
|
|
47517
48179
|
|
|
47518
48180
|
// Check if the response is stale
|
|
47519
48181
|
if (stale || revalidate) {
|
|
@@ -47525,28 +48187,13 @@ function requireCache$1 () {
|
|
|
47525
48187
|
|
|
47526
48188
|
// RFC 5861: If we're within stale-while-revalidate window, serve stale immediately
|
|
47527
48189
|
// and revalidate in background, unless immediate revalidation is necessary
|
|
47528
|
-
if (!revalidate && withinStaleWhileRevalidateWindow(result)) {
|
|
48190
|
+
if (!revalidate && withinStaleWhileRevalidateWindow(result, globalOpts.type)) {
|
|
47529
48191
|
// Serve stale response immediately
|
|
47530
48192
|
sendCachedValue(handler, opts, result, age, null, true);
|
|
47531
48193
|
|
|
47532
48194
|
// Start background revalidation (fire-and-forget)
|
|
47533
48195
|
queueMicrotask(() => {
|
|
47534
|
-
const headers =
|
|
47535
|
-
...opts.headers,
|
|
47536
|
-
'if-modified-since': new Date(result.cachedAt).toUTCString()
|
|
47537
|
-
};
|
|
47538
|
-
|
|
47539
|
-
if (result.etag) {
|
|
47540
|
-
headers['if-none-match'] = result.etag;
|
|
47541
|
-
}
|
|
47542
|
-
|
|
47543
|
-
if (result.vary) {
|
|
47544
|
-
for (const key in result.vary) {
|
|
47545
|
-
if (result.vary[key] != null) {
|
|
47546
|
-
headers[key] = result.vary[key];
|
|
47547
|
-
}
|
|
47548
|
-
}
|
|
47549
|
-
}
|
|
48196
|
+
const headers = makeRevalidationHeaders(opts, result);
|
|
47550
48197
|
|
|
47551
48198
|
// Background revalidation - update cache if we get new data
|
|
47552
48199
|
dispatch(
|
|
@@ -47570,28 +48217,15 @@ function requireCache$1 () {
|
|
|
47570
48217
|
}
|
|
47571
48218
|
|
|
47572
48219
|
let withinStaleIfErrorThreshold = false;
|
|
47573
|
-
|
|
47574
|
-
|
|
47575
|
-
|
|
47576
|
-
|
|
47577
|
-
|
|
47578
|
-
const headers = {
|
|
47579
|
-
...opts.headers,
|
|
47580
|
-
'if-modified-since': new Date(result.cachedAt).toUTCString()
|
|
47581
|
-
};
|
|
47582
|
-
|
|
47583
|
-
if (result.etag) {
|
|
47584
|
-
headers['if-none-match'] = result.etag;
|
|
47585
|
-
}
|
|
47586
|
-
|
|
47587
|
-
if (result.vary) {
|
|
47588
|
-
for (const key in result.vary) {
|
|
47589
|
-
if (result.vary[key] != null) {
|
|
47590
|
-
headers[key] = result.vary[key];
|
|
47591
|
-
}
|
|
48220
|
+
if (!staleResponseRequiresRevalidation(result, globalOpts.type)) {
|
|
48221
|
+
const staleIfErrorExpiry = result.cacheControlDirectives['stale-if-error'] ?? reqCacheControl?.['stale-if-error'];
|
|
48222
|
+
if (staleIfErrorExpiry) {
|
|
48223
|
+
withinStaleIfErrorThreshold = now < (result.staleAt + (staleIfErrorExpiry * 1000));
|
|
47592
48224
|
}
|
|
47593
48225
|
}
|
|
47594
48226
|
|
|
48227
|
+
const headers = makeRevalidationHeaders(opts, result);
|
|
48228
|
+
|
|
47595
48229
|
// We need to revalidate the response
|
|
47596
48230
|
return dispatch(
|
|
47597
48231
|
{
|
|
@@ -47599,8 +48233,23 @@ function requireCache$1 () {
|
|
|
47599
48233
|
headers
|
|
47600
48234
|
},
|
|
47601
48235
|
new CacheRevalidationHandler(
|
|
47602
|
-
(success, context) => {
|
|
48236
|
+
(success, context, statusCode, headers) => {
|
|
47603
48237
|
if (success) {
|
|
48238
|
+
if (statusCode === 304) {
|
|
48239
|
+
if (revalidationResponseDisallowsCachedReuse(globalOpts.type, headers)) {
|
|
48240
|
+
if (util.isStream(result.body)) {
|
|
48241
|
+
result.body.on('error', nop).destroy();
|
|
48242
|
+
}
|
|
48243
|
+
|
|
48244
|
+
deleteCachedValue(globalOpts.store, cacheKey);
|
|
48245
|
+
return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler))
|
|
48246
|
+
}
|
|
48247
|
+
|
|
48248
|
+
if (revalidationResponseUpdatesCacheControl(headers)) {
|
|
48249
|
+
deleteCachedValue(globalOpts.store, cacheKey);
|
|
48250
|
+
}
|
|
48251
|
+
}
|
|
48252
|
+
|
|
47604
48253
|
// TODO: successful revalidation should be considered fresh (not give stale warning).
|
|
47605
48254
|
sendCachedValue(handler, opts, result, age, context, stale);
|
|
47606
48255
|
} else if (util.isStream(result.body)) {
|
|
@@ -47657,11 +48306,17 @@ function requireCache$1 () {
|
|
|
47657
48306
|
type
|
|
47658
48307
|
};
|
|
47659
48308
|
|
|
47660
|
-
const safeMethodsToNotCache =
|
|
48309
|
+
const safeMethodsToNotCache = [];
|
|
48310
|
+
for (let i = 0; i < util.safeHTTPMethods.length; i++) {
|
|
48311
|
+
const method = util.safeHTTPMethods[i];
|
|
48312
|
+
if (!arrayIncludes(methods, method)) {
|
|
48313
|
+
safeMethodsToNotCache.push(method);
|
|
48314
|
+
}
|
|
48315
|
+
}
|
|
47661
48316
|
|
|
47662
48317
|
return dispatch => {
|
|
47663
48318
|
return (opts, handler) => {
|
|
47664
|
-
if (!opts.origin || safeMethodsToNotCache
|
|
48319
|
+
if (!opts.origin || arrayIncludes(safeMethodsToNotCache, opts.method)) {
|
|
47665
48320
|
// Not a method we want to cache or we don't have the origin, skip
|
|
47666
48321
|
return dispatch(opts, handler)
|
|
47667
48322
|
}
|
|
@@ -47696,7 +48351,9 @@ function requireCache$1 () {
|
|
|
47696
48351
|
|
|
47697
48352
|
const reqCacheControl = opts.headers?.['cache-control']
|
|
47698
48353
|
? parseCacheControlHeader(opts.headers['cache-control'])
|
|
47699
|
-
:
|
|
48354
|
+
: hasPragmaNoCache(opts.headers)
|
|
48355
|
+
? { 'no-cache': true }
|
|
48356
|
+
: undefined;
|
|
47700
48357
|
|
|
47701
48358
|
if (reqCacheControl?.['no-store']) {
|
|
47702
48359
|
return dispatch(opts, handler)
|
|
@@ -49056,7 +49713,13 @@ function requireSqliteCacheStore () {
|
|
|
49056
49713
|
return false
|
|
49057
49714
|
}
|
|
49058
49715
|
|
|
49059
|
-
|
|
49716
|
+
for (let i = 0; i < lhs.length; i++) {
|
|
49717
|
+
if (lhs[i] !== rhs[i]) {
|
|
49718
|
+
return false
|
|
49719
|
+
}
|
|
49720
|
+
}
|
|
49721
|
+
|
|
49722
|
+
return true
|
|
49060
49723
|
}
|
|
49061
49724
|
|
|
49062
49725
|
return lhs === rhs
|
|
@@ -55456,7 +56119,7 @@ function requireUtil$4 () {
|
|
|
55456
56119
|
|
|
55457
56120
|
if (
|
|
55458
56121
|
code < 0x20 || // exclude CTLs (0-31)
|
|
55459
|
-
code
|
|
56122
|
+
code > 0x7E || // exclude DEL and non-ascii
|
|
55460
56123
|
code === 0x3B // ;
|
|
55461
56124
|
) {
|
|
55462
56125
|
throw new Error('Invalid cookie path')
|
|
@@ -55465,16 +56128,80 @@ function requireUtil$4 () {
|
|
|
55465
56128
|
}
|
|
55466
56129
|
|
|
55467
56130
|
/**
|
|
55468
|
-
*
|
|
55469
|
-
*
|
|
56131
|
+
* <let-dig> ::= <letter> | <digit>
|
|
56132
|
+
*
|
|
56133
|
+
* <letter> ::= any one of the 52 alphabetic characters A through Z in
|
|
56134
|
+
* upper case and a through z in lower case
|
|
56135
|
+
*
|
|
56136
|
+
* <digit> ::= any one of the ten digits 0 through 9r
|
|
56137
|
+
*
|
|
56138
|
+
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
|
|
56139
|
+
* @param {number} code
|
|
56140
|
+
*/
|
|
56141
|
+
function isLetterOrDigit (code) {
|
|
56142
|
+
return (
|
|
56143
|
+
(code >= 0x30 && code <= 0x39) || // 0-9
|
|
56144
|
+
(code >= 0x41 && code <= 0x5A) || // A-Z
|
|
56145
|
+
(code >= 0x61 && code <= 0x7A) // a-z
|
|
56146
|
+
)
|
|
56147
|
+
}
|
|
56148
|
+
|
|
56149
|
+
/**
|
|
56150
|
+
* Validates a cookie domain against the "preferred name syntax".
|
|
56151
|
+
*
|
|
56152
|
+
* <domain> ::= <subdomain> | " "
|
|
56153
|
+
* <subdomain> ::= <label> | <subdomain> "." <label>
|
|
56154
|
+
* <label> ::= <let-dig> [ [ <ldh-str> ] <let-dig> ]
|
|
56155
|
+
* <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
|
|
56156
|
+
* <let-dig-hyp> ::= <let-dig> | "-"
|
|
56157
|
+
*
|
|
56158
|
+
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
|
|
56159
|
+
* @see https://www.rfc-editor.org/rfc/rfc1123#section-2.1
|
|
56160
|
+
* @see https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4
|
|
55470
56161
|
* @param {string} domain
|
|
55471
56162
|
*/
|
|
55472
56163
|
function validateCookieDomain (domain) {
|
|
55473
|
-
|
|
55474
|
-
|
|
55475
|
-
|
|
55476
|
-
|
|
55477
|
-
|
|
56164
|
+
// <domain> ::= <subdomain> | " "
|
|
56165
|
+
if (domain === ' ') {
|
|
56166
|
+
return
|
|
56167
|
+
}
|
|
56168
|
+
|
|
56169
|
+
if (domain.length > 255) {
|
|
56170
|
+
throw new Error('Invalid cookie domain')
|
|
56171
|
+
}
|
|
56172
|
+
|
|
56173
|
+
let labelLength = 0;
|
|
56174
|
+
|
|
56175
|
+
for (let i = 0; i < domain.length; ++i) {
|
|
56176
|
+
const code = domain.charCodeAt(i);
|
|
56177
|
+
|
|
56178
|
+
if (code === 0x2E) {
|
|
56179
|
+
if (labelLength === 0) {
|
|
56180
|
+
throw new Error('Invalid cookie domain')
|
|
56181
|
+
}
|
|
56182
|
+
|
|
56183
|
+
if (domain.charCodeAt(i - 1) === 0x2D) { // "-"
|
|
56184
|
+
throw new Error('Invalid cookie domain')
|
|
56185
|
+
}
|
|
56186
|
+
|
|
56187
|
+
labelLength = 0;
|
|
56188
|
+
continue
|
|
56189
|
+
}
|
|
56190
|
+
|
|
56191
|
+
if (labelLength === 0 && !isLetterOrDigit(code)) {
|
|
56192
|
+
throw new Error('Invalid cookie domain')
|
|
56193
|
+
}
|
|
56194
|
+
|
|
56195
|
+
if (!isLetterOrDigit(code) && code !== 0x2D) { // "-"
|
|
56196
|
+
throw new Error('Invalid cookie domain')
|
|
56197
|
+
}
|
|
56198
|
+
|
|
56199
|
+
if (++labelLength > 63) {
|
|
56200
|
+
throw new Error('Invalid cookie domain')
|
|
56201
|
+
}
|
|
56202
|
+
}
|
|
56203
|
+
|
|
56204
|
+
if (labelLength === 0 || domain.charCodeAt(domain.length - 1) === 0x2D) { // "-"
|
|
55478
56205
|
throw new Error('Invalid cookie domain')
|
|
55479
56206
|
}
|
|
55480
56207
|
}
|
|
@@ -55617,7 +56344,13 @@ function requireUtil$4 () {
|
|
|
55617
56344
|
|
|
55618
56345
|
const [key, ...value] = part.split('=');
|
|
55619
56346
|
|
|
55620
|
-
|
|
56347
|
+
const trimmedKey = key.trim();
|
|
56348
|
+
const joinedValue = value.join('=');
|
|
56349
|
+
|
|
56350
|
+
validateCookieName(trimmedKey);
|
|
56351
|
+
validateCookieValue(joinedValue);
|
|
56352
|
+
|
|
56353
|
+
out.push(`${trimmedKey}=${joinedValue}`);
|
|
55621
56354
|
}
|
|
55622
56355
|
|
|
55623
56356
|
return out.join('; ')
|
|
@@ -87707,15 +88440,19 @@ function requireJson () {
|
|
|
87707
88440
|
function json (options) {
|
|
87708
88441
|
var opts = options || {};
|
|
87709
88442
|
|
|
87710
|
-
var limit = typeof opts.limit
|
|
87711
|
-
?
|
|
87712
|
-
: opts.limit;
|
|
88443
|
+
var limit = typeof opts.limit === 'undefined' || opts.limit === null
|
|
88444
|
+
? 102400 // 100kb default
|
|
88445
|
+
: bytes.parse(opts.limit);
|
|
87713
88446
|
var inflate = opts.inflate !== false;
|
|
87714
88447
|
var reviver = opts.reviver;
|
|
87715
88448
|
var strict = opts.strict !== false;
|
|
87716
88449
|
var type = opts.type || 'application/json';
|
|
87717
88450
|
var verify = opts.verify || false;
|
|
87718
88451
|
|
|
88452
|
+
if (limit === null) {
|
|
88453
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid')
|
|
88454
|
+
}
|
|
88455
|
+
|
|
87719
88456
|
if (verify !== false && typeof verify !== 'function') {
|
|
87720
88457
|
throw new TypeError('option verify must be function')
|
|
87721
88458
|
}
|
|
@@ -87938,12 +88675,16 @@ function requireRaw () {
|
|
|
87938
88675
|
var opts = options || {};
|
|
87939
88676
|
|
|
87940
88677
|
var inflate = opts.inflate !== false;
|
|
87941
|
-
var limit = typeof opts.limit
|
|
87942
|
-
?
|
|
87943
|
-
: opts.limit;
|
|
88678
|
+
var limit = typeof opts.limit === 'undefined' || opts.limit === null
|
|
88679
|
+
? 102400 // 100kb default
|
|
88680
|
+
: bytes.parse(opts.limit);
|
|
87944
88681
|
var type = opts.type || 'application/octet-stream';
|
|
87945
88682
|
var verify = opts.verify || false;
|
|
87946
88683
|
|
|
88684
|
+
if (limit === null) {
|
|
88685
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid')
|
|
88686
|
+
}
|
|
88687
|
+
|
|
87947
88688
|
if (verify !== false && typeof verify !== 'function') {
|
|
87948
88689
|
throw new TypeError('option verify must be function')
|
|
87949
88690
|
}
|
|
@@ -88049,12 +88790,16 @@ function requireText () {
|
|
|
88049
88790
|
|
|
88050
88791
|
var defaultCharset = opts.defaultCharset || 'utf-8';
|
|
88051
88792
|
var inflate = opts.inflate !== false;
|
|
88052
|
-
var limit = typeof opts.limit
|
|
88053
|
-
?
|
|
88054
|
-
: opts.limit;
|
|
88793
|
+
var limit = typeof opts.limit === 'undefined' || opts.limit === null
|
|
88794
|
+
? 102400 // 100kb default
|
|
88795
|
+
: bytes.parse(opts.limit);
|
|
88055
88796
|
var type = opts.type || 'text/plain';
|
|
88056
88797
|
var verify = opts.verify || false;
|
|
88057
88798
|
|
|
88799
|
+
if (limit === null) {
|
|
88800
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid')
|
|
88801
|
+
}
|
|
88802
|
+
|
|
88058
88803
|
if (verify !== false && typeof verify !== 'function') {
|
|
88059
88804
|
throw new TypeError('option verify must be function')
|
|
88060
88805
|
}
|
|
@@ -91321,12 +92066,16 @@ function requireUrlencoded () {
|
|
|
91321
92066
|
|
|
91322
92067
|
var extended = opts.extended !== false;
|
|
91323
92068
|
var inflate = opts.inflate !== false;
|
|
91324
|
-
var limit = typeof opts.limit
|
|
91325
|
-
?
|
|
91326
|
-
: opts.limit;
|
|
92069
|
+
var limit = typeof opts.limit === 'undefined' || opts.limit === null
|
|
92070
|
+
? 102400 // 100kb default
|
|
92071
|
+
: bytes.parse(opts.limit);
|
|
91327
92072
|
var type = opts.type || 'application/x-www-form-urlencoded';
|
|
91328
92073
|
var verify = opts.verify || false;
|
|
91329
92074
|
|
|
92075
|
+
if (limit === null) {
|
|
92076
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid')
|
|
92077
|
+
}
|
|
92078
|
+
|
|
91330
92079
|
if (verify !== false && typeof verify !== 'function') {
|
|
91331
92080
|
throw new TypeError('option verify must be function')
|
|
91332
92081
|
}
|
|
@@ -112042,6 +112791,17 @@ const closePattern = /\\}/g;
|
|
|
112042
112791
|
const commaPattern = /\\,/g;
|
|
112043
112792
|
const periodPattern = /\\\./g;
|
|
112044
112793
|
const EXPANSION_MAX = 100_000;
|
|
112794
|
+
// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An
|
|
112795
|
+
// input like `'{a,b}'.repeat(1500)` stays under that count - its output is
|
|
112796
|
+
// truncated to 100k results - while making every result ~1500 characters
|
|
112797
|
+
// long. The result set, and the intermediate arrays built while combining
|
|
112798
|
+
// brace sets, then grow large enough to exhaust memory and crash the process
|
|
112799
|
+
// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of
|
|
112800
|
+
// characters the accumulator may hold at any point, so memory stays flat no
|
|
112801
|
+
// matter how many brace groups are chained. The limit sits well above any
|
|
112802
|
+
// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
|
|
112803
|
+
// characters) so legitimate input is unaffected.
|
|
112804
|
+
const EXPANSION_MAX_LENGTH = 4_000_000;
|
|
112045
112805
|
function numeric(str) {
|
|
112046
112806
|
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
|
112047
112807
|
}
|
|
@@ -112090,7 +112850,7 @@ function expand(str, options = {}) {
|
|
|
112090
112850
|
if (!str) {
|
|
112091
112851
|
return [];
|
|
112092
112852
|
}
|
|
112093
|
-
const { max = EXPANSION_MAX } = options;
|
|
112853
|
+
const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options;
|
|
112094
112854
|
// I don't know why Bash 4.3 does this, but it does.
|
|
112095
112855
|
// Anything starting with {} will have the first two bytes preserved
|
|
112096
112856
|
// but *only* at the top level, so {},a}b will not expand to anything,
|
|
@@ -112100,7 +112860,7 @@ function expand(str, options = {}) {
|
|
|
112100
112860
|
if (str.slice(0, 2) === '{}') {
|
|
112101
112861
|
str = '\\{\\}' + str.slice(2);
|
|
112102
112862
|
}
|
|
112103
|
-
return expand_(escapeBraces(str), max, true).map(unescapeBraces);
|
|
112863
|
+
return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
|
|
112104
112864
|
}
|
|
112105
112865
|
function embrace(str) {
|
|
112106
112866
|
return '{' + str + '}';
|
|
@@ -112114,22 +112874,117 @@ function lte(i, y) {
|
|
|
112114
112874
|
function gte(i, y) {
|
|
112115
112875
|
return i >= y;
|
|
112116
112876
|
}
|
|
112117
|
-
|
|
112118
|
-
|
|
112119
|
-
|
|
112120
|
-
|
|
112121
|
-
|
|
112122
|
-
|
|
112123
|
-
|
|
112124
|
-
|
|
112125
|
-
|
|
112126
|
-
|
|
112127
|
-
|
|
112128
|
-
|
|
112129
|
-
|
|
112877
|
+
// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
|
|
112878
|
+
// number of results at `max` and the total number of characters at `maxLength`.
|
|
112879
|
+
// This is the one place output grows, so bounding it here keeps the single
|
|
112880
|
+
// accumulator - and therefore memory - flat regardless of how many brace groups
|
|
112881
|
+
// are combined (CVE-2026-14257).
|
|
112882
|
+
function combine(acc, pre, values, max, maxLength, dropEmpties) {
|
|
112883
|
+
const out = [];
|
|
112884
|
+
let length = 0;
|
|
112885
|
+
for (let a = 0; a < acc.length; a++) {
|
|
112886
|
+
for (let v = 0; v < values.length; v++) {
|
|
112887
|
+
if (out.length >= max)
|
|
112888
|
+
return out;
|
|
112889
|
+
const expansion = acc[a] + pre + values[v];
|
|
112890
|
+
// Bash drops empty results at the top level. Skip them before they count
|
|
112891
|
+
// against `max`, so `max` bounds the number of *kept* results.
|
|
112892
|
+
if (dropEmpties && !expansion)
|
|
112893
|
+
continue;
|
|
112894
|
+
if (length + expansion.length > maxLength)
|
|
112895
|
+
return out;
|
|
112896
|
+
out.push(expansion);
|
|
112897
|
+
length += expansion.length;
|
|
112130
112898
|
}
|
|
112131
112899
|
}
|
|
112132
|
-
|
|
112900
|
+
return out;
|
|
112901
|
+
}
|
|
112902
|
+
// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
|
|
112903
|
+
// sequence body.
|
|
112904
|
+
function expandSequence(body, isAlphaSequence, max, maxLength) {
|
|
112905
|
+
const n = body.split(/\.\./);
|
|
112906
|
+
const N = [];
|
|
112907
|
+
// A sequence body always splits into two or three parts, but the compiler
|
|
112908
|
+
// can't know that.
|
|
112909
|
+
/* c8 ignore start */
|
|
112910
|
+
if (n[0] === undefined || n[1] === undefined) {
|
|
112911
|
+
return N;
|
|
112912
|
+
}
|
|
112913
|
+
/* c8 ignore stop */
|
|
112914
|
+
const x = numeric(n[0]);
|
|
112915
|
+
const y = numeric(n[1]);
|
|
112916
|
+
const width = Math.max(n[0].length, n[1].length);
|
|
112917
|
+
let incr = n.length === 3 && n[2] !== undefined ?
|
|
112918
|
+
Math.max(Math.abs(numeric(n[2])), 1)
|
|
112919
|
+
: 1;
|
|
112920
|
+
let test = lte;
|
|
112921
|
+
const reverse = y < x;
|
|
112922
|
+
if (reverse) {
|
|
112923
|
+
incr *= -1;
|
|
112924
|
+
test = gte;
|
|
112925
|
+
}
|
|
112926
|
+
const pad = n.some(isPadded);
|
|
112927
|
+
let length = 0;
|
|
112928
|
+
for (let i = x; test(i, y) && N.length < max; i += incr) {
|
|
112929
|
+
let c;
|
|
112930
|
+
if (isAlphaSequence) {
|
|
112931
|
+
c = String.fromCharCode(i);
|
|
112932
|
+
if (c === '\\') {
|
|
112933
|
+
c = '';
|
|
112934
|
+
}
|
|
112935
|
+
}
|
|
112936
|
+
else {
|
|
112937
|
+
c = String(i);
|
|
112938
|
+
if (pad) {
|
|
112939
|
+
const need = width - c.length;
|
|
112940
|
+
if (need > 0) {
|
|
112941
|
+
const z = new Array(need + 1).join('0');
|
|
112942
|
+
if (i < 0) {
|
|
112943
|
+
c = '-' + z + c.slice(1);
|
|
112944
|
+
}
|
|
112945
|
+
else {
|
|
112946
|
+
c = z + c;
|
|
112947
|
+
}
|
|
112948
|
+
}
|
|
112949
|
+
}
|
|
112950
|
+
}
|
|
112951
|
+
if (length + c.length > maxLength)
|
|
112952
|
+
break;
|
|
112953
|
+
N.push(c);
|
|
112954
|
+
length += c.length;
|
|
112955
|
+
}
|
|
112956
|
+
return N;
|
|
112957
|
+
}
|
|
112958
|
+
function expand_(str, max, maxLength, isTop) {
|
|
112959
|
+
// Consume the string's top-level brace groups left to right, threading a
|
|
112960
|
+
// running set of combined prefixes (`acc`). Expanding the tail iteratively -
|
|
112961
|
+
// rather than recursing on `m.post` once per group - keeps the native stack
|
|
112962
|
+
// depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no
|
|
112963
|
+
// longer overflow the stack, and leaves a single accumulator whose size
|
|
112964
|
+
// `maxLength` bounds directly (CVE-2026-14257).
|
|
112965
|
+
let acc = [''];
|
|
112966
|
+
// Bash drops empty results, but only when the *first* top-level group is a
|
|
112967
|
+
// comma set - a sequence like `{a..\}` may legitimately yield ''. The drop
|
|
112968
|
+
// is on the final strings, so it is applied to whichever `combine` produces
|
|
112969
|
+
// them (the one with no brace set left in the tail).
|
|
112970
|
+
let dropEmpties = false;
|
|
112971
|
+
let firstGroup = true;
|
|
112972
|
+
for (;;) {
|
|
112973
|
+
const m = balanced('{', '}', str);
|
|
112974
|
+
// No brace set left: the rest of the string is literal.
|
|
112975
|
+
if (!m) {
|
|
112976
|
+
return combine(acc, str, [''], max, maxLength, dropEmpties);
|
|
112977
|
+
}
|
|
112978
|
+
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|
112979
|
+
const pre = m.pre;
|
|
112980
|
+
if (/\$$/.test(pre)) {
|
|
112981
|
+
acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length);
|
|
112982
|
+
firstGroup = false;
|
|
112983
|
+
if (!m.post.length)
|
|
112984
|
+
break;
|
|
112985
|
+
str = m.post;
|
|
112986
|
+
continue;
|
|
112987
|
+
}
|
|
112133
112988
|
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
112134
112989
|
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
112135
112990
|
const isSequence = isNumericSequence || isAlphaSequence;
|
|
@@ -112138,87 +112993,69 @@ function expand_(str, max, isTop) {
|
|
|
112138
112993
|
// {a},b}
|
|
112139
112994
|
if (m.post.match(/,(?!,).*\}/)) {
|
|
112140
112995
|
str = m.pre + '{' + m.body + escClose + m.post;
|
|
112141
|
-
|
|
112996
|
+
isTop = true;
|
|
112997
|
+
continue;
|
|
112142
112998
|
}
|
|
112143
|
-
|
|
112999
|
+
// Nothing here expands, so the whole remaining string is literal.
|
|
113000
|
+
return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties);
|
|
112144
113001
|
}
|
|
112145
|
-
|
|
113002
|
+
if (firstGroup) {
|
|
113003
|
+
dropEmpties = isTop && !isSequence;
|
|
113004
|
+
firstGroup = false;
|
|
113005
|
+
}
|
|
113006
|
+
let values;
|
|
112146
113007
|
if (isSequence) {
|
|
112147
|
-
|
|
113008
|
+
values = expandSequence(m.body, isAlphaSequence, max, maxLength);
|
|
112148
113009
|
}
|
|
112149
113010
|
else {
|
|
112150
|
-
n = parseCommaParts(m.body);
|
|
113011
|
+
let n = parseCommaParts(m.body);
|
|
112151
113012
|
if (n.length === 1 && n[0] !== undefined) {
|
|
112152
113013
|
// x{{a,b}}y ==> x{a}y x{b}y
|
|
112153
|
-
n = expand_(n[0], max, false).map(embrace);
|
|
113014
|
+
n = expand_(n[0], max, maxLength, false).map(embrace);
|
|
112154
113015
|
//XXX is this necessary? Can't seem to hit it in tests.
|
|
112155
113016
|
/* c8 ignore start */
|
|
112156
113017
|
if (n.length === 1) {
|
|
112157
|
-
|
|
113018
|
+
acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length);
|
|
113019
|
+
if (!m.post.length)
|
|
113020
|
+
break;
|
|
113021
|
+
str = m.post;
|
|
113022
|
+
continue;
|
|
112158
113023
|
}
|
|
112159
113024
|
/* c8 ignore stop */
|
|
112160
113025
|
}
|
|
112161
|
-
|
|
112162
|
-
|
|
112163
|
-
|
|
112164
|
-
|
|
112165
|
-
|
|
112166
|
-
|
|
112167
|
-
|
|
112168
|
-
|
|
112169
|
-
|
|
112170
|
-
|
|
112171
|
-
|
|
112172
|
-
|
|
112173
|
-
|
|
112174
|
-
|
|
112175
|
-
|
|
112176
|
-
|
|
112177
|
-
|
|
112178
|
-
|
|
112179
|
-
|
|
112180
|
-
|
|
112181
|
-
|
|
112182
|
-
if (isAlphaSequence) {
|
|
112183
|
-
c = String.fromCharCode(i);
|
|
112184
|
-
if (c === '\\') {
|
|
112185
|
-
c = '';
|
|
112186
|
-
}
|
|
112187
|
-
}
|
|
112188
|
-
else {
|
|
112189
|
-
c = String(i);
|
|
112190
|
-
if (pad) {
|
|
112191
|
-
const need = width - c.length;
|
|
112192
|
-
if (need > 0) {
|
|
112193
|
-
const z = new Array(need + 1).join('0');
|
|
112194
|
-
if (i < 0) {
|
|
112195
|
-
c = '-' + z + c.slice(1);
|
|
112196
|
-
}
|
|
112197
|
-
else {
|
|
112198
|
-
c = z + c;
|
|
112199
|
-
}
|
|
112200
|
-
}
|
|
113026
|
+
// Values that `combine` is going to drop as empty produce no result, so
|
|
113027
|
+
// they must not count against `max` - otherwise `{a,,b}` with `max: 2`
|
|
113028
|
+
// would stop at `['a', '']` and yield one result instead of two. Skipping
|
|
113029
|
+
// them outright keeps `values` bounded while leaving `max` a bound on
|
|
113030
|
+
// *kept* results.
|
|
113031
|
+
let dropsEmpties = dropEmpties && !m.post.length && !pre;
|
|
113032
|
+
for (let d = 0; dropsEmpties && d < acc.length; d++) {
|
|
113033
|
+
if (acc[d]) {
|
|
113034
|
+
dropsEmpties = false;
|
|
113035
|
+
}
|
|
113036
|
+
}
|
|
113037
|
+
values = [];
|
|
113038
|
+
let valuesLength = 0;
|
|
113039
|
+
outer: for (let j = 0; j < n.length; j++) {
|
|
113040
|
+
const expanded = expand_(n[j], max, maxLength, false);
|
|
113041
|
+
for (let k = 0; k < expanded.length; k++) {
|
|
113042
|
+
const v = expanded[k];
|
|
113043
|
+
if (dropsEmpties && !v)
|
|
113044
|
+
continue;
|
|
113045
|
+
if (values.length >= max || valuesLength + v.length > maxLength) {
|
|
113046
|
+
break outer;
|
|
112201
113047
|
}
|
|
112202
|
-
|
|
112203
|
-
|
|
112204
|
-
}
|
|
112205
|
-
}
|
|
112206
|
-
else {
|
|
112207
|
-
N = [];
|
|
112208
|
-
for (let j = 0; j < n.length; j++) {
|
|
112209
|
-
N.push.apply(N, expand_(n[j], max, false));
|
|
112210
|
-
}
|
|
112211
|
-
}
|
|
112212
|
-
for (let j = 0; j < N.length; j++) {
|
|
112213
|
-
for (let k = 0; k < post.length && expansions.length < max; k++) {
|
|
112214
|
-
const expansion = pre + N[j] + post[k];
|
|
112215
|
-
if (!isTop || isSequence || expansion) {
|
|
112216
|
-
expansions.push(expansion);
|
|
113048
|
+
values.push(v);
|
|
113049
|
+
valuesLength += v.length;
|
|
112217
113050
|
}
|
|
112218
113051
|
}
|
|
112219
113052
|
}
|
|
113053
|
+
acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
|
|
113054
|
+
if (!m.post.length)
|
|
113055
|
+
break;
|
|
113056
|
+
str = m.post;
|
|
112220
113057
|
}
|
|
112221
|
-
return
|
|
113058
|
+
return acc;
|
|
112222
113059
|
}
|
|
112223
113060
|
|
|
112224
113061
|
const MAX_PATTERN_LENGTH = 1024 * 64;
|
|
@@ -190418,7 +191255,12 @@ function requireFastUri () {
|
|
|
190418
191255
|
*/
|
|
190419
191256
|
function resolve (baseURI, relativeURI, options) {
|
|
190420
191257
|
const schemelessOptions = options ? Object.assign({ scheme: 'null' }, options) : { scheme: 'null' };
|
|
190421
|
-
const
|
|
191258
|
+
const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
|
|
191259
|
+
const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
|
|
191260
|
+
if (baseMalformed || relativeMalformed) {
|
|
191261
|
+
throw new Error(baseParsed.error || relativeParsed.error || 'URI is malformed.')
|
|
191262
|
+
}
|
|
191263
|
+
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
190422
191264
|
schemelessOptions.skipEscape = true;
|
|
190423
191265
|
return serialize(resolved, schemelessOptions)
|
|
190424
191266
|
}
|
|
@@ -190594,6 +191436,19 @@ function requireFastUri () {
|
|
|
190594
191436
|
|
|
190595
191437
|
const URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
190596
191438
|
|
|
191439
|
+
// Captures the authority component (between "//" and the next "/", "?" or "#"),
|
|
191440
|
+
// with or without a scheme prefix, for the literal-backslash rejection below.
|
|
191441
|
+
const AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
|
|
191442
|
+
|
|
191443
|
+
// Captures the leading authority-introducer region after an optional scheme: a
|
|
191444
|
+
// run of forward slashes, backslashes, and the characters the WHATWG URL parser
|
|
191445
|
+
// removes before parsing (TAB U+0009, LF U+000A, CR U+000D). A valid introducer
|
|
191446
|
+
// is exactly "//". Node treats "\" as "/" on special schemes and strips those
|
|
191447
|
+
// characters first, so forms like "\\", "/\", "\/", "/<TAB>/", or a leading
|
|
191448
|
+
// "<TAB>//" reach an authority in Node while fast-uri's URI_PARSE folds them into
|
|
191449
|
+
// the path group (host confusion / SSRF / redirect bypass).
|
|
191450
|
+
const AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
|
|
191451
|
+
|
|
190597
191452
|
/**
|
|
190598
191453
|
* @param {import('./types/index').URIComponent} parsed
|
|
190599
191454
|
* @param {RegExpMatchArray} matches
|
|
@@ -190640,6 +191495,41 @@ function requireFastUri () {
|
|
|
190640
191495
|
}
|
|
190641
191496
|
}
|
|
190642
191497
|
|
|
191498
|
+
// A literal backslash (U+005C) is not a valid RFC 3986 URI character and is
|
|
191499
|
+
// not an authority delimiter. Reject it in the authority rather than
|
|
191500
|
+
// rewriting it: normalizing "\" -> "/" (WHATWG error recovery) could silently
|
|
191501
|
+
// change the resource identified by an otherwise-invalid input, and lets "\"
|
|
191502
|
+
// act as a host delimiter here while Node's native URL parses a different
|
|
191503
|
+
// host (SSRF / redirect / origin-allowlist bypass). Percent-encoded %5C is
|
|
191504
|
+
// untouched and remains valid encoded data.
|
|
191505
|
+
const authorityMatch = uri.match(AUTHORITY_PREFIX);
|
|
191506
|
+
if (authorityMatch !== null && authorityMatch[1].indexOf('\\') !== -1) {
|
|
191507
|
+
parsed.error = 'URI authority must not contain a literal backslash.';
|
|
191508
|
+
malformedAuthorityOrPort = true;
|
|
191509
|
+
}
|
|
191510
|
+
|
|
191511
|
+
// Reject a malformed or whitespace-smuggled authority introducer. fast-uri
|
|
191512
|
+
// only recognizes a literal "//"; anything else in the leading separator run
|
|
191513
|
+
// (a backslash, or a "//" that appears only after removing the TAB/LF/CR that
|
|
191514
|
+
// Node strips) means the authority fast-uri parses differs from the one Node's
|
|
191515
|
+
// URL resolves. Reject rather than rewrite, mirroring the literal-backslash
|
|
191516
|
+
// guard above. Percent-encoded forms (%5C, %09) are untouched, valid data.
|
|
191517
|
+
const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION);
|
|
191518
|
+
if (introducerMatch !== null) {
|
|
191519
|
+
const region = introducerMatch[1];
|
|
191520
|
+
const normalizedRegion = region.replace(/[\t\n\r]/g, '');
|
|
191521
|
+
// Two or more leading separators introduce an authority.
|
|
191522
|
+
if (normalizedRegion.length >= 2) {
|
|
191523
|
+
if (normalizedRegion.slice(0, 2) !== '//') {
|
|
191524
|
+
parsed.error = parsed.error || 'URI authority must not contain a literal backslash.';
|
|
191525
|
+
malformedAuthorityOrPort = true;
|
|
191526
|
+
} else if (region.length !== normalizedRegion.length) {
|
|
191527
|
+
parsed.error = parsed.error || 'URI authority introducer must not contain whitespace.';
|
|
191528
|
+
malformedAuthorityOrPort = true;
|
|
191529
|
+
}
|
|
191530
|
+
}
|
|
191531
|
+
}
|
|
191532
|
+
|
|
190643
191533
|
const matches = uri.match(URI_PARSE);
|
|
190644
191534
|
|
|
190645
191535
|
if (matches) {
|
|
@@ -190697,7 +191587,7 @@ function requireFastUri () {
|
|
|
190697
191587
|
if (parsed.host && (options.domainHost || (schemeHandler && schemeHandler.domainHost)) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
190698
191588
|
// convert Unicode IDN -> ASCII IDN
|
|
190699
191589
|
try {
|
|
190700
|
-
parsed.host = URL
|
|
191590
|
+
parsed.host = new URL('http://' + parsed.host).hostname;
|
|
190701
191591
|
} catch (e) {
|
|
190702
191592
|
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
190703
191593
|
}
|