@infersec/conduit 1.85.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.js
CHANGED
|
@@ -26916,7 +26916,13 @@ function requireRequest$2 () {
|
|
|
26916
26916
|
} else if (typeof val[i] === 'object') {
|
|
26917
26917
|
throw new InvalidArgumentError(`invalid ${key} header`)
|
|
26918
26918
|
} else {
|
|
26919
|
-
|
|
26919
|
+
// Coerce primitives (and reject unsafe coercions such as functions
|
|
26920
|
+
// with a crafted toString/Symbol.toPrimitive).
|
|
26921
|
+
const str = `${val[i]}`;
|
|
26922
|
+
if (!isValidHeaderValue(str)) {
|
|
26923
|
+
throw new InvalidArgumentError(`invalid ${key} header`)
|
|
26924
|
+
}
|
|
26925
|
+
arr.push(str);
|
|
26920
26926
|
}
|
|
26921
26927
|
}
|
|
26922
26928
|
val = arr;
|
|
@@ -26927,7 +26933,12 @@ function requireRequest$2 () {
|
|
|
26927
26933
|
} else if (val === null) {
|
|
26928
26934
|
val = '';
|
|
26929
26935
|
} else {
|
|
26936
|
+
// Coerce primitives (and reject unsafe coercions such as functions
|
|
26937
|
+
// with a crafted toString/Symbol.toPrimitive).
|
|
26930
26938
|
val = `${val}`;
|
|
26939
|
+
if (!isValidHeaderValue(val)) {
|
|
26940
|
+
throw new InvalidArgumentError(`invalid ${key} header`)
|
|
26941
|
+
}
|
|
26931
26942
|
}
|
|
26932
26943
|
|
|
26933
26944
|
if (headerName === 'host') {
|
|
@@ -33409,6 +33420,7 @@ function requireClientH1 () {
|
|
|
33409
33420
|
RequestContentLengthMismatchError,
|
|
33410
33421
|
ResponseContentLengthMismatchError,
|
|
33411
33422
|
RequestAbortedError,
|
|
33423
|
+
InvalidArgumentError,
|
|
33412
33424
|
HeadersTimeoutError,
|
|
33413
33425
|
HeadersOverflowError,
|
|
33414
33426
|
SocketError,
|
|
@@ -34533,8 +34545,16 @@ function requireClientH1 () {
|
|
|
34533
34545
|
}
|
|
34534
34546
|
body = bodyStream.stream;
|
|
34535
34547
|
contentLength = bodyStream.length;
|
|
34536
|
-
} else if (util.isBlobLike(body) && request.contentType == null
|
|
34537
|
-
|
|
34548
|
+
} else if (util.isBlobLike(body) && request.contentType == null) {
|
|
34549
|
+
const contentType = body.type;
|
|
34550
|
+
if (contentType) {
|
|
34551
|
+
const contentTypeValue = `${contentType}`;
|
|
34552
|
+
if (!util.isValidHeaderValue(contentTypeValue)) {
|
|
34553
|
+
util.errorRequest(client, request, new InvalidArgumentError('invalid content-type header'));
|
|
34554
|
+
return false
|
|
34555
|
+
}
|
|
34556
|
+
headers.push('content-type', contentTypeValue);
|
|
34557
|
+
}
|
|
34538
34558
|
}
|
|
34539
34559
|
|
|
34540
34560
|
if (body && typeof body.read === 'function') {
|
|
@@ -39245,6 +39265,26 @@ function requireRetryHandler () {
|
|
|
39245
39265
|
return isNaN(retryTime) ? 0 : retryTime - Date.now()
|
|
39246
39266
|
}
|
|
39247
39267
|
|
|
39268
|
+
function validatePartialResponseContentLength (headers, range, statusCode, retryCount) {
|
|
39269
|
+
const contentLength = headers['content-length'];
|
|
39270
|
+
if (contentLength == null) {
|
|
39271
|
+
return
|
|
39272
|
+
}
|
|
39273
|
+
|
|
39274
|
+
if (!Number.isFinite(range.start) || !Number.isFinite(range.end)) {
|
|
39275
|
+
return
|
|
39276
|
+
}
|
|
39277
|
+
|
|
39278
|
+
const length = Number(contentLength);
|
|
39279
|
+
const expectedLength = range.end - range.start + 1;
|
|
39280
|
+
if (!Number.isFinite(length) || length !== expectedLength) {
|
|
39281
|
+
throw new RequestRetryError('Content-Length mismatch', statusCode, {
|
|
39282
|
+
headers,
|
|
39283
|
+
data: { count: retryCount }
|
|
39284
|
+
})
|
|
39285
|
+
}
|
|
39286
|
+
}
|
|
39287
|
+
|
|
39248
39288
|
class RetryHandler {
|
|
39249
39289
|
constructor (opts, { dispatch, handler }) {
|
|
39250
39290
|
const { retryOptions, ...dispatchOpts } = opts;
|
|
@@ -39459,6 +39499,8 @@ function requireRetryHandler () {
|
|
|
39459
39499
|
})
|
|
39460
39500
|
}
|
|
39461
39501
|
|
|
39502
|
+
validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount);
|
|
39503
|
+
|
|
39462
39504
|
const { start, size, end = size ? size - 1 : null } = contentRange;
|
|
39463
39505
|
|
|
39464
39506
|
assert(this.start === start, 'content-range mismatch');
|
|
@@ -39483,6 +39525,8 @@ function requireRetryHandler () {
|
|
|
39483
39525
|
return
|
|
39484
39526
|
}
|
|
39485
39527
|
|
|
39528
|
+
validatePartialResponseContentLength(headers, range, statusCode, this.retryCount);
|
|
39529
|
+
|
|
39486
39530
|
const { start, size, end = size ? size - 1 : null } = range;
|
|
39487
39531
|
assert(
|
|
39488
39532
|
start != null && Number.isFinite(start),
|
|
@@ -45185,11 +45229,147 @@ function requireCache$2 () {
|
|
|
45185
45229
|
const {
|
|
45186
45230
|
safeHTTPMethods,
|
|
45187
45231
|
pathHasQueryOrFragment,
|
|
45188
|
-
hasSafeIterator
|
|
45232
|
+
hasSafeIterator,
|
|
45233
|
+
isValidHTTPToken
|
|
45189
45234
|
} = requireUtil$6();
|
|
45190
45235
|
|
|
45191
45236
|
const { serializePathWithQuery } = requireUtil$6();
|
|
45192
45237
|
|
|
45238
|
+
const MAX_DELTA_SECONDS = 2147483647;
|
|
45239
|
+
const RESTRICTIVE_DIRECTIVE_NAMES = ['no-store', 'private', 'no-cache'];
|
|
45240
|
+
const kInvalidCacheControlDirectives = Symbol('invalid cache-control directives');
|
|
45241
|
+
|
|
45242
|
+
function trimOWS (value) {
|
|
45243
|
+
return value.replace(/^[\t ]+|[\t ]+$/g, '')
|
|
45244
|
+
}
|
|
45245
|
+
|
|
45246
|
+
function arrayIncludes (array, value) {
|
|
45247
|
+
for (let i = 0; i < array.length; i++) {
|
|
45248
|
+
if (array[i] === value) {
|
|
45249
|
+
return true
|
|
45250
|
+
}
|
|
45251
|
+
}
|
|
45252
|
+
|
|
45253
|
+
return false
|
|
45254
|
+
}
|
|
45255
|
+
|
|
45256
|
+
function trimOWSStart (value) {
|
|
45257
|
+
return value.replace(/^[\t ]+/, '')
|
|
45258
|
+
}
|
|
45259
|
+
|
|
45260
|
+
function trimOWSEnd (value) {
|
|
45261
|
+
return value.replace(/[\t ]+$/, '')
|
|
45262
|
+
}
|
|
45263
|
+
|
|
45264
|
+
function findUnescapedQuote (value, start) {
|
|
45265
|
+
let escaped = false;
|
|
45266
|
+
for (let i = start; i < value.length; i++) {
|
|
45267
|
+
if (escaped) {
|
|
45268
|
+
escaped = false;
|
|
45269
|
+
} else if (value[i] === '\\') {
|
|
45270
|
+
escaped = true;
|
|
45271
|
+
} else if (value[i] === '"') {
|
|
45272
|
+
return i
|
|
45273
|
+
}
|
|
45274
|
+
}
|
|
45275
|
+
|
|
45276
|
+
return -1
|
|
45277
|
+
}
|
|
45278
|
+
|
|
45279
|
+
function splitCacheControlHeaderValue (value) {
|
|
45280
|
+
const directives = [];
|
|
45281
|
+
let start = 0;
|
|
45282
|
+
let quoteStart = -1;
|
|
45283
|
+
let inQuote = false;
|
|
45284
|
+
let escaped = false;
|
|
45285
|
+
|
|
45286
|
+
for (let i = 0; i < value.length; i++) {
|
|
45287
|
+
if (inQuote) {
|
|
45288
|
+
if (escaped) {
|
|
45289
|
+
escaped = false;
|
|
45290
|
+
} else if (value[i] === '\\') {
|
|
45291
|
+
escaped = true;
|
|
45292
|
+
} else if (value[i] === '"') {
|
|
45293
|
+
inQuote = false;
|
|
45294
|
+
quoteStart = -1;
|
|
45295
|
+
}
|
|
45296
|
+
} else if (value[i] === '"') {
|
|
45297
|
+
inQuote = true;
|
|
45298
|
+
quoteStart = i;
|
|
45299
|
+
} else if (value[i] === ',') {
|
|
45300
|
+
directives.push({ value: value.substring(start, i), fromMalformedQuote: false });
|
|
45301
|
+
start = i + 1;
|
|
45302
|
+
}
|
|
45303
|
+
}
|
|
45304
|
+
|
|
45305
|
+
if (!inQuote) {
|
|
45306
|
+
directives.push({ value: value.substring(start), fromMalformedQuote: false });
|
|
45307
|
+
return directives
|
|
45308
|
+
}
|
|
45309
|
+
|
|
45310
|
+
const tail = value.substring(start);
|
|
45311
|
+
const quoteOffset = quoteStart - start;
|
|
45312
|
+
let tailStart = 0;
|
|
45313
|
+
for (let i = 0; i < tail.length; i++) {
|
|
45314
|
+
if (tail[i] === ',') {
|
|
45315
|
+
directives.push({
|
|
45316
|
+
value: tail.substring(tailStart, i),
|
|
45317
|
+
fromMalformedQuote: tailStart > quoteOffset
|
|
45318
|
+
});
|
|
45319
|
+
tailStart = i + 1;
|
|
45320
|
+
}
|
|
45321
|
+
}
|
|
45322
|
+
|
|
45323
|
+
directives.push({
|
|
45324
|
+
value: tail.substring(tailStart),
|
|
45325
|
+
fromMalformedQuote: tailStart > quoteOffset
|
|
45326
|
+
});
|
|
45327
|
+
return directives
|
|
45328
|
+
}
|
|
45329
|
+
|
|
45330
|
+
function markInvalidCacheControlDirective (directives, key) {
|
|
45331
|
+
let invalidDirectives = directives[kInvalidCacheControlDirectives];
|
|
45332
|
+
|
|
45333
|
+
if (invalidDirectives === undefined) {
|
|
45334
|
+
invalidDirectives = new Set();
|
|
45335
|
+
Object.defineProperty(directives, kInvalidCacheControlDirectives, {
|
|
45336
|
+
value: invalidDirectives
|
|
45337
|
+
});
|
|
45338
|
+
}
|
|
45339
|
+
|
|
45340
|
+
invalidDirectives.add(key);
|
|
45341
|
+
}
|
|
45342
|
+
|
|
45343
|
+
function hasInvalidCacheControlDirective (directives, key) {
|
|
45344
|
+
return directives[kInvalidCacheControlDirectives]?.has(key) === true
|
|
45345
|
+
}
|
|
45346
|
+
|
|
45347
|
+
function getMalformedRestrictiveDirectiveName (key) {
|
|
45348
|
+
for (const directiveName of RESTRICTIVE_DIRECTIVE_NAMES) {
|
|
45349
|
+
if (
|
|
45350
|
+
key.startsWith(directiveName) &&
|
|
45351
|
+
key.length > directiveName.length &&
|
|
45352
|
+
!isValidHTTPToken(key[directiveName.length])
|
|
45353
|
+
) {
|
|
45354
|
+
return directiveName
|
|
45355
|
+
}
|
|
45356
|
+
}
|
|
45357
|
+
|
|
45358
|
+
let tokenOnlyKey = '';
|
|
45359
|
+
let hasInvalidTokenChar = false;
|
|
45360
|
+
for (let i = 0; i < key.length; i++) {
|
|
45361
|
+
if (isValidHTTPToken(key[i])) {
|
|
45362
|
+
tokenOnlyKey += key[i];
|
|
45363
|
+
} else {
|
|
45364
|
+
hasInvalidTokenChar = true;
|
|
45365
|
+
}
|
|
45366
|
+
}
|
|
45367
|
+
|
|
45368
|
+
if (hasInvalidTokenChar && arrayIncludes(RESTRICTIVE_DIRECTIVE_NAMES, tokenOnlyKey)) {
|
|
45369
|
+
return tokenOnlyKey
|
|
45370
|
+
}
|
|
45371
|
+
}
|
|
45372
|
+
|
|
45193
45373
|
/**
|
|
45194
45374
|
* @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts
|
|
45195
45375
|
*/
|
|
@@ -45212,6 +45392,20 @@ function requireCache$2 () {
|
|
|
45212
45392
|
}
|
|
45213
45393
|
}
|
|
45214
45394
|
|
|
45395
|
+
function appendHeader (headers, key, val) {
|
|
45396
|
+
const headerName = key.toLowerCase();
|
|
45397
|
+
const current = headers[headerName];
|
|
45398
|
+
const values = Array.isArray(val) ? val : [val];
|
|
45399
|
+
|
|
45400
|
+
if (current === undefined) {
|
|
45401
|
+
headers[headerName] = Array.isArray(val) ? val.slice() : val;
|
|
45402
|
+
} else if (Array.isArray(current)) {
|
|
45403
|
+
current.push(...values);
|
|
45404
|
+
} else {
|
|
45405
|
+
headers[headerName] = [current, ...values];
|
|
45406
|
+
}
|
|
45407
|
+
}
|
|
45408
|
+
|
|
45215
45409
|
/**
|
|
45216
45410
|
* @param {Record<string, string[] | string>}
|
|
45217
45411
|
* @returns {Record<string, string[] | string>}
|
|
@@ -45232,11 +45426,11 @@ function requireCache$2 () {
|
|
|
45232
45426
|
if (typeof key !== 'string' || typeof val !== 'string') {
|
|
45233
45427
|
throw new Error('opts.headers is not a valid header map')
|
|
45234
45428
|
}
|
|
45235
|
-
headers
|
|
45429
|
+
appendHeader(headers, key, val);
|
|
45236
45430
|
}
|
|
45237
45431
|
} else {
|
|
45238
45432
|
for (const key of Object.keys(opts.headers)) {
|
|
45239
|
-
headers
|
|
45433
|
+
appendHeader(headers, key, opts.headers[key]);
|
|
45240
45434
|
}
|
|
45241
45435
|
}
|
|
45242
45436
|
} else {
|
|
@@ -45308,29 +45502,37 @@ function requireCache$2 () {
|
|
|
45308
45502
|
* @type {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives}
|
|
45309
45503
|
*/
|
|
45310
45504
|
const output = {};
|
|
45505
|
+
const invalidNumericDirectives = new Set();
|
|
45506
|
+
const invalidNoArgumentDirectives = new Set();
|
|
45311
45507
|
|
|
45312
|
-
|
|
45313
|
-
if (Array.isArray(header)) {
|
|
45314
|
-
directives = [];
|
|
45315
|
-
|
|
45316
|
-
for (const directive of header) {
|
|
45317
|
-
directives.push(...directive.split(','));
|
|
45318
|
-
}
|
|
45319
|
-
} else {
|
|
45320
|
-
directives = header.split(',');
|
|
45321
|
-
}
|
|
45508
|
+
const directives = splitCacheControlHeaderValue(Array.isArray(header) ? header.join(',') : header);
|
|
45322
45509
|
|
|
45323
45510
|
for (let i = 0; i < directives.length; i++) {
|
|
45324
|
-
const
|
|
45511
|
+
const directiveRecord = directives[i];
|
|
45512
|
+
const directive = directiveRecord.value.toLowerCase();
|
|
45513
|
+
const fromMalformedQuote = directiveRecord.fromMalformedQuote;
|
|
45325
45514
|
const keyValueDelimiter = directive.indexOf('=');
|
|
45326
45515
|
|
|
45327
45516
|
let key;
|
|
45328
45517
|
let value;
|
|
45518
|
+
let keyHasTrailingWhitespace = false;
|
|
45519
|
+
let valueHasLeadingWhitespace = false;
|
|
45329
45520
|
if (keyValueDelimiter !== -1) {
|
|
45330
|
-
|
|
45331
|
-
|
|
45521
|
+
const rawKey = directive.substring(0, keyValueDelimiter);
|
|
45522
|
+
const rawValue = directive.substring(keyValueDelimiter + 1);
|
|
45523
|
+
|
|
45524
|
+
keyHasTrailingWhitespace = trimOWSEnd(rawKey) !== rawKey;
|
|
45525
|
+
valueHasLeadingWhitespace = trimOWSStart(rawValue) !== rawValue;
|
|
45526
|
+
key = trimOWS(rawKey);
|
|
45527
|
+
value = trimOWSStart(rawValue);
|
|
45332
45528
|
} else {
|
|
45333
|
-
key = directive
|
|
45529
|
+
key = trimOWS(directive);
|
|
45530
|
+
}
|
|
45531
|
+
|
|
45532
|
+
const malformedRestrictiveDirectiveName = getMalformedRestrictiveDirectiveName(key);
|
|
45533
|
+
if (malformedRestrictiveDirectiveName !== undefined) {
|
|
45534
|
+
output[malformedRestrictiveDirectiveName] = true;
|
|
45535
|
+
continue
|
|
45334
45536
|
}
|
|
45335
45537
|
|
|
45336
45538
|
switch (key) {
|
|
@@ -45340,7 +45542,14 @@ function requireCache$2 () {
|
|
|
45340
45542
|
case 's-maxage':
|
|
45341
45543
|
case 'stale-while-revalidate':
|
|
45342
45544
|
case 'stale-if-error': {
|
|
45343
|
-
if (
|
|
45545
|
+
if (fromMalformedQuote || invalidNumericDirectives.has(key)) {
|
|
45546
|
+
continue
|
|
45547
|
+
}
|
|
45548
|
+
|
|
45549
|
+
if (value === undefined || keyHasTrailingWhitespace || valueHasLeadingWhitespace) {
|
|
45550
|
+
delete output[key];
|
|
45551
|
+
invalidNumericDirectives.add(key);
|
|
45552
|
+
markInvalidCacheControlDirective(output, key);
|
|
45344
45553
|
continue
|
|
45345
45554
|
}
|
|
45346
45555
|
|
|
@@ -45352,22 +45561,37 @@ function requireCache$2 () {
|
|
|
45352
45561
|
value = value.substring(1, value.length - 1);
|
|
45353
45562
|
}
|
|
45354
45563
|
|
|
45355
|
-
|
|
45356
|
-
|
|
45357
|
-
|
|
45564
|
+
if (!/^[0-9]+$/.test(value)) {
|
|
45565
|
+
delete output[key];
|
|
45566
|
+
invalidNumericDirectives.add(key);
|
|
45567
|
+
markInvalidCacheControlDirective(output, key);
|
|
45358
45568
|
continue
|
|
45359
45569
|
}
|
|
45360
45570
|
|
|
45361
|
-
|
|
45362
|
-
continue
|
|
45363
|
-
}
|
|
45571
|
+
const parsedValue = Math.min(parseInt(value, 10), MAX_DELTA_SECONDS);
|
|
45364
45572
|
|
|
45365
|
-
|
|
45573
|
+
if (key === 'min-fresh') {
|
|
45574
|
+
if (!(key in output) || output[key] < parsedValue) {
|
|
45575
|
+
output[key] = parsedValue;
|
|
45576
|
+
}
|
|
45577
|
+
} else if (!(key in output) || output[key] > parsedValue) {
|
|
45578
|
+
output[key] = parsedValue;
|
|
45579
|
+
}
|
|
45366
45580
|
|
|
45367
45581
|
break
|
|
45368
45582
|
}
|
|
45369
45583
|
case 'private':
|
|
45370
45584
|
case 'no-cache': {
|
|
45585
|
+
if (fromMalformedQuote) {
|
|
45586
|
+
output[key] = true;
|
|
45587
|
+
break
|
|
45588
|
+
}
|
|
45589
|
+
|
|
45590
|
+
if (value !== undefined && value.length === 0) {
|
|
45591
|
+
output[key] = true;
|
|
45592
|
+
break
|
|
45593
|
+
}
|
|
45594
|
+
|
|
45371
45595
|
if (value) {
|
|
45372
45596
|
// The private and no-cache directives can be unqualified (aka just
|
|
45373
45597
|
// `private` or `no-cache`) or qualified (w/ a value). When they're
|
|
@@ -45375,45 +45599,64 @@ function requireCache$2 () {
|
|
|
45375
45599
|
// `no-cache="header1"`, or `no-cache="header1, header2"`
|
|
45376
45600
|
// If we're given multiple headers, the comma messes us up since
|
|
45377
45601
|
// we split the full header by commas. So, let's loop through the
|
|
45378
|
-
// remaining parts in front of us until we find one that
|
|
45379
|
-
// quote. We can then
|
|
45380
|
-
//
|
|
45381
|
-
// and continue parsing like normal.
|
|
45602
|
+
// remaining parts in front of us until we find one that contains a
|
|
45603
|
+
// closing quote. We can then skip the consumed quoted-list fragments and
|
|
45604
|
+
// continue parsing like normal.
|
|
45382
45605
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-no-cache-2
|
|
45383
45606
|
if (value[0] === '"') {
|
|
45384
45607
|
// Something like `no-cache="some-header"` OR `no-cache="some-header, another-header"`.
|
|
45608
|
+
value = trimOWSEnd(value);
|
|
45385
45609
|
|
|
45386
|
-
|
|
45387
|
-
|
|
45610
|
+
let fieldList = '';
|
|
45611
|
+
let lastQuotedPart = i;
|
|
45612
|
+
let foundEndingQuote = false;
|
|
45613
|
+
const closingQuote = findUnescapedQuote(value, 1);
|
|
45388
45614
|
|
|
45389
|
-
|
|
45390
|
-
|
|
45615
|
+
if (closingQuote !== -1) {
|
|
45616
|
+
fieldList = value.substring(1, closingQuote);
|
|
45617
|
+
foundEndingQuote = true;
|
|
45618
|
+
} else {
|
|
45391
45619
|
// Something like `no-cache="some-header, another-header"`
|
|
45392
45620
|
// This can still be something invalid, e.g. `no-cache="some-header, ...`
|
|
45621
|
+
const fieldListParts = [value.substring(1)];
|
|
45622
|
+
|
|
45393
45623
|
for (let j = i + 1; j < directives.length; j++) {
|
|
45394
|
-
const nextPart = directives[j];
|
|
45395
|
-
const
|
|
45624
|
+
const nextPart = trimOWS(directives[j].value);
|
|
45625
|
+
const closingQuote = findUnescapedQuote(nextPart, 0);
|
|
45396
45626
|
|
|
45397
|
-
|
|
45627
|
+
lastQuotedPart = j;
|
|
45398
45628
|
|
|
45399
|
-
if (
|
|
45629
|
+
if (closingQuote !== -1) {
|
|
45630
|
+
fieldListParts.push(nextPart.substring(0, closingQuote));
|
|
45400
45631
|
foundEndingQuote = true;
|
|
45401
45632
|
break
|
|
45402
45633
|
}
|
|
45634
|
+
|
|
45635
|
+
fieldListParts.push(nextPart);
|
|
45403
45636
|
}
|
|
45637
|
+
|
|
45638
|
+
fieldList = fieldListParts.join(',');
|
|
45404
45639
|
}
|
|
45405
45640
|
|
|
45406
|
-
if (foundEndingQuote) {
|
|
45407
|
-
|
|
45408
|
-
|
|
45409
|
-
|
|
45410
|
-
headers[headers.length - 1] = lastHeader;
|
|
45411
|
-
}
|
|
45641
|
+
if (!foundEndingQuote) {
|
|
45642
|
+
output[key] = true;
|
|
45643
|
+
break
|
|
45644
|
+
}
|
|
45412
45645
|
|
|
45413
|
-
|
|
45414
|
-
|
|
45646
|
+
i = lastQuotedPart;
|
|
45647
|
+
|
|
45648
|
+
const headers = fieldList.split(',');
|
|
45649
|
+
let validFieldNames = true;
|
|
45650
|
+
for (let j = 0; j < headers.length; j++) {
|
|
45651
|
+
headers[j] = trimOWS(headers[j]);
|
|
45652
|
+
if (!isValidHTTPToken(headers[j])) {
|
|
45653
|
+
validFieldNames = false;
|
|
45415
45654
|
}
|
|
45655
|
+
}
|
|
45416
45656
|
|
|
45657
|
+
if (!validFieldNames) {
|
|
45658
|
+
output[key] = true;
|
|
45659
|
+
} else if (output[key] !== true) {
|
|
45417
45660
|
if (key in output) {
|
|
45418
45661
|
output[key] = output[key].concat(headers);
|
|
45419
45662
|
} else {
|
|
@@ -45421,13 +45664,17 @@ function requireCache$2 () {
|
|
|
45421
45664
|
}
|
|
45422
45665
|
}
|
|
45423
45666
|
} else {
|
|
45424
|
-
// Something like `no-cache=
|
|
45425
|
-
const fieldName = value
|
|
45667
|
+
// Something like `no-cache=some-header`
|
|
45668
|
+
const fieldName = trimOWS(value);
|
|
45426
45669
|
|
|
45427
|
-
if (
|
|
45428
|
-
output[key] =
|
|
45429
|
-
} else {
|
|
45430
|
-
|
|
45670
|
+
if (!isValidHTTPToken(fieldName)) {
|
|
45671
|
+
output[key] = true;
|
|
45672
|
+
} else if (output[key] !== true) {
|
|
45673
|
+
if (key in output) {
|
|
45674
|
+
output[key] = output[key].concat(fieldName);
|
|
45675
|
+
} else {
|
|
45676
|
+
output[key] = [fieldName];
|
|
45677
|
+
}
|
|
45431
45678
|
}
|
|
45432
45679
|
}
|
|
45433
45680
|
|
|
@@ -45436,19 +45683,27 @@ function requireCache$2 () {
|
|
|
45436
45683
|
}
|
|
45437
45684
|
// eslint-disable-next-line no-fallthrough
|
|
45438
45685
|
case 'public':
|
|
45439
|
-
case 'no-store':
|
|
45440
45686
|
case 'must-revalidate':
|
|
45441
45687
|
case 'proxy-revalidate':
|
|
45442
45688
|
case 'immutable':
|
|
45443
45689
|
case 'no-transform':
|
|
45444
45690
|
case 'must-understand':
|
|
45445
45691
|
case 'only-if-cached':
|
|
45446
|
-
if (
|
|
45692
|
+
if (fromMalformedQuote || invalidNoArgumentDirectives.has(key)) {
|
|
45693
|
+
continue
|
|
45694
|
+
}
|
|
45695
|
+
|
|
45696
|
+
if (value !== undefined) {
|
|
45447
45697
|
// These are qualified (something like `public=...`) when they aren't
|
|
45448
|
-
// allowed to be, skip
|
|
45698
|
+
// allowed to be, skip all instances of the malformed directive.
|
|
45699
|
+
delete output[key];
|
|
45700
|
+
invalidNoArgumentDirectives.add(key);
|
|
45449
45701
|
continue
|
|
45450
45702
|
}
|
|
45451
45703
|
|
|
45704
|
+
output[key] = true;
|
|
45705
|
+
break
|
|
45706
|
+
case 'no-store':
|
|
45452
45707
|
output[key] = true;
|
|
45453
45708
|
break
|
|
45454
45709
|
default:
|
|
@@ -45460,31 +45715,79 @@ function requireCache$2 () {
|
|
|
45460
45715
|
return output
|
|
45461
45716
|
}
|
|
45462
45717
|
|
|
45718
|
+
/**
|
|
45719
|
+
* @param {string | string[]} varyHeader Vary header from the server
|
|
45720
|
+
* @returns {string[]}
|
|
45721
|
+
*/
|
|
45722
|
+
function splitVaryHeader (varyHeader) {
|
|
45723
|
+
const values = Array.isArray(varyHeader) ? varyHeader : [varyHeader];
|
|
45724
|
+
const output = [];
|
|
45725
|
+
|
|
45726
|
+
for (let i = 0; i < values.length; i++) {
|
|
45727
|
+
const parts = values[i].split(',');
|
|
45728
|
+
for (let j = 0; j < parts.length; j++) {
|
|
45729
|
+
output.push(parts[j]);
|
|
45730
|
+
}
|
|
45731
|
+
}
|
|
45732
|
+
|
|
45733
|
+
return output
|
|
45734
|
+
}
|
|
45735
|
+
|
|
45736
|
+
/**
|
|
45737
|
+
* @param {string | string[]} varyHeader Vary header from the server
|
|
45738
|
+
* @returns {boolean}
|
|
45739
|
+
*/
|
|
45740
|
+
function hasVaryStar (varyHeader) {
|
|
45741
|
+
const values = splitVaryHeader(varyHeader);
|
|
45742
|
+
for (let i = 0; i < values.length; i++) {
|
|
45743
|
+
if (trimOWS(values[i]).indexOf('*') !== -1) {
|
|
45744
|
+
return true
|
|
45745
|
+
}
|
|
45746
|
+
}
|
|
45747
|
+
|
|
45748
|
+
return false
|
|
45749
|
+
}
|
|
45750
|
+
|
|
45463
45751
|
/**
|
|
45464
45752
|
* @param {string | string[]} varyHeader Vary header from the server
|
|
45465
45753
|
* @param {Record<string, string | string[]>} headers Request headers
|
|
45466
|
-
* @returns {Record<string, string | string[]>}
|
|
45754
|
+
* @returns {Record<string, string | string[] | null> | undefined}
|
|
45467
45755
|
*/
|
|
45468
45756
|
function parseVaryHeader (varyHeader, headers) {
|
|
45469
|
-
if (
|
|
45757
|
+
if (hasVaryStar(varyHeader)) {
|
|
45470
45758
|
return headers
|
|
45471
45759
|
}
|
|
45472
45760
|
|
|
45473
45761
|
const output = /** @type {Record<string, string | string[] | null>} */ ({});
|
|
45474
45762
|
|
|
45475
|
-
const varyingHeaders =
|
|
45476
|
-
? varyHeader.split(',')
|
|
45477
|
-
: varyHeader;
|
|
45763
|
+
const varyingHeaders = splitVaryHeader(varyHeader);
|
|
45478
45764
|
|
|
45479
45765
|
for (const header of varyingHeaders) {
|
|
45480
|
-
const trimmedHeader = header
|
|
45766
|
+
const trimmedHeader = trimOWS(header).toLowerCase();
|
|
45767
|
+
|
|
45768
|
+
if (trimmedHeader.length === 0) {
|
|
45769
|
+
continue
|
|
45770
|
+
}
|
|
45481
45771
|
|
|
45482
|
-
|
|
45772
|
+
if (!isValidHTTPToken(trimmedHeader)) {
|
|
45773
|
+
return undefined
|
|
45774
|
+
}
|
|
45775
|
+
|
|
45776
|
+
const headerValue = headers[trimmedHeader];
|
|
45777
|
+
output[trimmedHeader] = Array.isArray(headerValue) ? headerValue.slice() : headerValue ?? null;
|
|
45483
45778
|
}
|
|
45484
45779
|
|
|
45485
45780
|
return output
|
|
45486
45781
|
}
|
|
45487
45782
|
|
|
45783
|
+
/**
|
|
45784
|
+
* @param {string | string[]} varyHeader Vary header from the server
|
|
45785
|
+
* @returns {boolean}
|
|
45786
|
+
*/
|
|
45787
|
+
function isInvalidOrWildcardVaryHeader (varyHeader) {
|
|
45788
|
+
return hasVaryStar(varyHeader) || parseVaryHeader(varyHeader, {}) === undefined
|
|
45789
|
+
}
|
|
45790
|
+
|
|
45488
45791
|
/**
|
|
45489
45792
|
* Note: this deviates from the spec a little. Empty etags ("", W/"") are valid,
|
|
45490
45793
|
* however, including them in cached resposnes serves little to no purpose.
|
|
@@ -45548,7 +45851,7 @@ function requireCache$2 () {
|
|
|
45548
45851
|
}
|
|
45549
45852
|
|
|
45550
45853
|
for (const method of methods) {
|
|
45551
|
-
if (!safeHTTPMethods
|
|
45854
|
+
if (!arrayIncludes(safeHTTPMethods, method)) {
|
|
45552
45855
|
throw new TypeError(`element of ${name}-array needs to be one of following values: ${safeHTTPMethods.join(', ')}, got ${method}`)
|
|
45553
45856
|
}
|
|
45554
45857
|
}
|
|
@@ -45588,7 +45891,10 @@ function requireCache$2 () {
|
|
|
45588
45891
|
assertCacheKey,
|
|
45589
45892
|
assertCacheValue,
|
|
45590
45893
|
parseCacheControlHeader,
|
|
45894
|
+
hasInvalidCacheControlDirective,
|
|
45591
45895
|
parseVaryHeader,
|
|
45896
|
+
hasVaryStar,
|
|
45897
|
+
isInvalidOrWildcardVaryHeader,
|
|
45592
45898
|
isEtagUsable,
|
|
45593
45899
|
assertCacheMethods,
|
|
45594
45900
|
assertCacheStore,
|
|
@@ -45622,6 +45928,26 @@ function requireDate () {
|
|
|
45622
45928
|
}
|
|
45623
45929
|
}
|
|
45624
45930
|
|
|
45931
|
+
function makeDate (year, monthIdx, day, hour, minute, second, weekday) {
|
|
45932
|
+
const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second));
|
|
45933
|
+
|
|
45934
|
+
// Date.UTC treats years 0-99 as 1900-1999. Reset the full year so component
|
|
45935
|
+
// checks below validate the HTTP date as written.
|
|
45936
|
+
if (year >= 0 && year <= 99) {
|
|
45937
|
+
result.setUTCFullYear(year);
|
|
45938
|
+
}
|
|
45939
|
+
|
|
45940
|
+
return result.getUTCFullYear() === year &&
|
|
45941
|
+
result.getUTCMonth() === monthIdx &&
|
|
45942
|
+
result.getUTCDate() === day &&
|
|
45943
|
+
result.getUTCHours() === hour &&
|
|
45944
|
+
result.getUTCMinutes() === minute &&
|
|
45945
|
+
result.getUTCSeconds() === second &&
|
|
45946
|
+
result.getUTCDay() === weekday
|
|
45947
|
+
? result
|
|
45948
|
+
: undefined
|
|
45949
|
+
}
|
|
45950
|
+
|
|
45625
45951
|
/**
|
|
45626
45952
|
* @see https://httpwg.org/specs/rfc9110.html#preferred.date.format
|
|
45627
45953
|
*
|
|
@@ -45828,8 +46154,7 @@ function requireDate () {
|
|
|
45828
46154
|
second = (code1 - 48) * 10 + (code2 - 48); // Convert ASCII codes to number
|
|
45829
46155
|
}
|
|
45830
46156
|
|
|
45831
|
-
|
|
45832
|
-
return result.getUTCDay() === weekday ? result : undefined
|
|
46157
|
+
return makeDate(year, monthIdx, day, hour, minute, second, weekday)
|
|
45833
46158
|
}
|
|
45834
46159
|
|
|
45835
46160
|
/**
|
|
@@ -46033,8 +46358,7 @@ function requireDate () {
|
|
|
46033
46358
|
}
|
|
46034
46359
|
const year = (yearDigit1 - 48) * 1000 + (yearDigit2 - 48) * 100 + (yearDigit3 - 48) * 10 + (yearDigit4 - 48);
|
|
46035
46360
|
|
|
46036
|
-
|
|
46037
|
-
return result.getUTCDay() === weekday ? result : undefined
|
|
46361
|
+
return makeDate(year, monthIdx, day, hour, minute, second, weekday)
|
|
46038
46362
|
}
|
|
46039
46363
|
|
|
46040
46364
|
/**
|
|
@@ -46248,8 +46572,7 @@ function requireDate () {
|
|
|
46248
46572
|
second = (code1 - 48) * 10 + (code2 - 48); // Convert ASCII codes to number
|
|
46249
46573
|
}
|
|
46250
46574
|
|
|
46251
|
-
|
|
46252
|
-
return result.getUTCDay() === weekday ? result : undefined
|
|
46575
|
+
return makeDate(year, monthIdx, day, hour, minute, second, weekday)
|
|
46253
46576
|
}
|
|
46254
46577
|
|
|
46255
46578
|
date = {
|
|
@@ -46268,7 +46591,10 @@ function requireCacheHandler () {
|
|
|
46268
46591
|
const util = requireUtil$6();
|
|
46269
46592
|
const {
|
|
46270
46593
|
parseCacheControlHeader,
|
|
46594
|
+
hasInvalidCacheControlDirective,
|
|
46271
46595
|
parseVaryHeader,
|
|
46596
|
+
hasVaryStar,
|
|
46597
|
+
isInvalidOrWildcardVaryHeader,
|
|
46272
46598
|
isEtagUsable
|
|
46273
46599
|
} = requireCache$2();
|
|
46274
46600
|
const { parseHttpDate } = requireDate();
|
|
@@ -46291,6 +46617,92 @@ function requireCacheHandler () {
|
|
|
46291
46617
|
|
|
46292
46618
|
const MAX_RESPONSE_AGE = 2147483647000;
|
|
46293
46619
|
|
|
46620
|
+
function trimOWS (value) {
|
|
46621
|
+
return value.replace(/^[\t ]+|[\t ]+$/g, '')
|
|
46622
|
+
}
|
|
46623
|
+
|
|
46624
|
+
function arrayIncludes (array, value) {
|
|
46625
|
+
for (let i = 0; i < array.length; i++) {
|
|
46626
|
+
if (array[i] === value) {
|
|
46627
|
+
return true
|
|
46628
|
+
}
|
|
46629
|
+
}
|
|
46630
|
+
|
|
46631
|
+
return false
|
|
46632
|
+
}
|
|
46633
|
+
|
|
46634
|
+
function appendConnectionHeaderTokens (headersToRemove, connectionHeader) {
|
|
46635
|
+
const values = Array.isArray(connectionHeader) ? connectionHeader : [connectionHeader];
|
|
46636
|
+
|
|
46637
|
+
for (let i = 0; i < values.length; i++) {
|
|
46638
|
+
const tokens = values[i].split(',');
|
|
46639
|
+
for (let j = 0; j < tokens.length; j++) {
|
|
46640
|
+
headersToRemove.push(trimOWS(tokens[j]).toLowerCase());
|
|
46641
|
+
}
|
|
46642
|
+
}
|
|
46643
|
+
}
|
|
46644
|
+
|
|
46645
|
+
function getSameOriginPath (cacheKey, location) {
|
|
46646
|
+
if (typeof location !== 'string') {
|
|
46647
|
+
return undefined
|
|
46648
|
+
}
|
|
46649
|
+
|
|
46650
|
+
let originUrl;
|
|
46651
|
+
let requestUrl;
|
|
46652
|
+
let locationUrl;
|
|
46653
|
+
try {
|
|
46654
|
+
originUrl = new URL(cacheKey.origin);
|
|
46655
|
+
requestUrl = new URL(cacheKey.path, originUrl);
|
|
46656
|
+
locationUrl = new URL(location, requestUrl);
|
|
46657
|
+
} catch {
|
|
46658
|
+
return undefined
|
|
46659
|
+
}
|
|
46660
|
+
|
|
46661
|
+
if (locationUrl.origin !== originUrl.origin) {
|
|
46662
|
+
return undefined
|
|
46663
|
+
}
|
|
46664
|
+
|
|
46665
|
+
return locationUrl.pathname + locationUrl.search
|
|
46666
|
+
}
|
|
46667
|
+
|
|
46668
|
+
function deleteCachedUri (store, cacheKey, path) {
|
|
46669
|
+
deleteCachedValue(store, {
|
|
46670
|
+
...cacheKey,
|
|
46671
|
+
path
|
|
46672
|
+
});
|
|
46673
|
+
|
|
46674
|
+
for (let i = 0; i < util.safeHTTPMethods.length; i++) {
|
|
46675
|
+
const method = util.safeHTTPMethods[i];
|
|
46676
|
+
if (method !== cacheKey.method) {
|
|
46677
|
+
deleteCachedValue(store, {
|
|
46678
|
+
...cacheKey,
|
|
46679
|
+
method,
|
|
46680
|
+
path
|
|
46681
|
+
});
|
|
46682
|
+
}
|
|
46683
|
+
}
|
|
46684
|
+
}
|
|
46685
|
+
|
|
46686
|
+
function deleteLocationTargets (store, cacheKey, headerValue) {
|
|
46687
|
+
if (headerValue === undefined) {
|
|
46688
|
+
return
|
|
46689
|
+
}
|
|
46690
|
+
|
|
46691
|
+
const values = Array.isArray(headerValue) ? headerValue : [headerValue];
|
|
46692
|
+
for (let i = 0; i < values.length; i++) {
|
|
46693
|
+
const path = getSameOriginPath(cacheKey, values[i]);
|
|
46694
|
+
if (path !== undefined) {
|
|
46695
|
+
deleteCachedUri(store, cacheKey, path);
|
|
46696
|
+
}
|
|
46697
|
+
}
|
|
46698
|
+
}
|
|
46699
|
+
|
|
46700
|
+
function invalidateUnsafeRequest (store, cacheKey, resHeaders) {
|
|
46701
|
+
deleteCachedUri(store, cacheKey, cacheKey.path);
|
|
46702
|
+
deleteLocationTargets(store, cacheKey, resHeaders.location);
|
|
46703
|
+
deleteLocationTargets(store, cacheKey, resHeaders['content-location']);
|
|
46704
|
+
}
|
|
46705
|
+
|
|
46294
46706
|
/**
|
|
46295
46707
|
* @typedef {import('../../types/dispatcher.d.ts').default.DispatchHandler} DispatchHandler
|
|
46296
46708
|
*
|
|
@@ -46372,28 +46784,28 @@ function requireCacheHandler () {
|
|
|
46372
46784
|
const handler = this;
|
|
46373
46785
|
|
|
46374
46786
|
if (
|
|
46375
|
-
!util.safeHTTPMethods
|
|
46787
|
+
!arrayIncludes(util.safeHTTPMethods, this.#cacheKey.method) &&
|
|
46376
46788
|
statusCode >= 200 &&
|
|
46377
46789
|
statusCode <= 399
|
|
46378
46790
|
) {
|
|
46379
46791
|
// Successful response to an unsafe method, delete it from cache
|
|
46380
46792
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-invalidating-stored-response
|
|
46381
|
-
|
|
46382
|
-
this.#store.delete(this.#cacheKey)?.catch?.(noop);
|
|
46383
|
-
} catch {
|
|
46384
|
-
// Fail silently
|
|
46385
|
-
}
|
|
46793
|
+
invalidateUnsafeRequest(this.#store, this.#cacheKey, resHeaders);
|
|
46386
46794
|
return downstreamOnHeaders()
|
|
46387
46795
|
}
|
|
46388
46796
|
|
|
46389
46797
|
const cacheControlHeader = resHeaders['cache-control'];
|
|
46390
|
-
const heuristicallyCacheable = resHeaders['last-modified'] && HEURISTICALLY_CACHEABLE_STATUS_CODES
|
|
46798
|
+
const heuristicallyCacheable = resHeaders['last-modified'] && arrayIncludes(HEURISTICALLY_CACHEABLE_STATUS_CODES, statusCode);
|
|
46391
46799
|
if (
|
|
46392
46800
|
!cacheControlHeader &&
|
|
46393
46801
|
!resHeaders['expires'] &&
|
|
46394
46802
|
!heuristicallyCacheable &&
|
|
46395
46803
|
!this.#cacheByDefault
|
|
46396
46804
|
) {
|
|
46805
|
+
if (statusCode === 304 && resHeaders.vary && isInvalidOrWildcardVaryHeader(resHeaders.vary)) {
|
|
46806
|
+
deleteCachedValue(this.#store, this.#cacheKey);
|
|
46807
|
+
}
|
|
46808
|
+
|
|
46397
46809
|
// Don't have anything to tell us this response is cachable and we're not
|
|
46398
46810
|
// caching by default
|
|
46399
46811
|
return downstreamOnHeaders()
|
|
@@ -46401,31 +46813,46 @@ function requireCacheHandler () {
|
|
|
46401
46813
|
|
|
46402
46814
|
const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {};
|
|
46403
46815
|
if (!canCacheResponse(this.#cacheType, statusCode, resHeaders, cacheControlDirectives, this.#cacheKey.headers)) {
|
|
46816
|
+
if (statusCode === 304 && (cacheControlHeader || revalidationResponseDisallowsCachedReuse(this.#cacheType, resHeaders, cacheControlDirectives))) {
|
|
46817
|
+
deleteCachedValue(this.#store, this.#cacheKey);
|
|
46818
|
+
}
|
|
46819
|
+
|
|
46404
46820
|
return downstreamOnHeaders()
|
|
46405
46821
|
}
|
|
46406
46822
|
|
|
46407
46823
|
const now = Date.now();
|
|
46408
|
-
const resAge = resHeaders
|
|
46409
|
-
if (resAge && resAge >= MAX_RESPONSE_AGE) {
|
|
46824
|
+
const resAge = Object.hasOwn(resHeaders, 'age') ? getAge(resHeaders.age) : undefined;
|
|
46825
|
+
if (resAge !== undefined && resAge >= MAX_RESPONSE_AGE) {
|
|
46410
46826
|
// Response considered stale
|
|
46827
|
+
deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey);
|
|
46411
46828
|
return downstreamOnHeaders()
|
|
46412
46829
|
}
|
|
46413
46830
|
|
|
46414
|
-
const resDate =
|
|
46415
|
-
|
|
46416
|
-
|
|
46831
|
+
const resDate = Object.hasOwn(resHeaders, 'date') ? getDate(resHeaders.date) : undefined;
|
|
46832
|
+
if (resDate === null) {
|
|
46833
|
+
deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey);
|
|
46834
|
+
return downstreamOnHeaders()
|
|
46835
|
+
}
|
|
46836
|
+
|
|
46837
|
+
const apparentAge = resDate ? Math.max(0, now - resDate.getTime()) : 0;
|
|
46838
|
+
const currentAge = Math.max(apparentAge, resAge ?? 0);
|
|
46417
46839
|
|
|
46418
46840
|
const staleAt =
|
|
46419
46841
|
determineStaleAt(this.#cacheType, now, resAge, resHeaders, resDate, cacheControlDirectives) ??
|
|
46420
46842
|
this.#cacheByDefault;
|
|
46421
|
-
if (staleAt === undefined ||
|
|
46843
|
+
if (staleAt === undefined || currentAge >= staleAt) {
|
|
46844
|
+
if (cacheControlHeader || staleAt !== undefined) {
|
|
46845
|
+
deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey);
|
|
46846
|
+
}
|
|
46847
|
+
|
|
46422
46848
|
return downstreamOnHeaders()
|
|
46423
46849
|
}
|
|
46424
46850
|
|
|
46425
|
-
const baseTime =
|
|
46851
|
+
const baseTime = now - currentAge;
|
|
46426
46852
|
const absoluteStaleAt = staleAt + baseTime;
|
|
46427
46853
|
if (now >= absoluteStaleAt) {
|
|
46428
46854
|
// Response is already stale
|
|
46855
|
+
deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey);
|
|
46429
46856
|
return downstreamOnHeaders()
|
|
46430
46857
|
}
|
|
46431
46858
|
|
|
@@ -46438,7 +46865,8 @@ function requireCacheHandler () {
|
|
|
46438
46865
|
}
|
|
46439
46866
|
}
|
|
46440
46867
|
|
|
46441
|
-
const
|
|
46868
|
+
const cachedAt = baseTime;
|
|
46869
|
+
const deleteAt = determineDeleteAt(baseTime, now, cacheControlDirectives, absoluteStaleAt);
|
|
46442
46870
|
const strippedHeaders = stripNecessaryHeaders(resHeaders, cacheControlDirectives);
|
|
46443
46871
|
|
|
46444
46872
|
/**
|
|
@@ -46450,7 +46878,7 @@ function requireCacheHandler () {
|
|
|
46450
46878
|
headers: strippedHeaders,
|
|
46451
46879
|
vary: varyDirectives,
|
|
46452
46880
|
cacheControlDirectives,
|
|
46453
|
-
cachedAt
|
|
46881
|
+
cachedAt,
|
|
46454
46882
|
staleAt: absoluteStaleAt,
|
|
46455
46883
|
deleteAt
|
|
46456
46884
|
};
|
|
@@ -46468,6 +46896,7 @@ function requireCacheHandler () {
|
|
|
46468
46896
|
value.statusCode = cachedValue.statusCode;
|
|
46469
46897
|
value.statusMessage = cachedValue.statusMessage;
|
|
46470
46898
|
value.etag = cachedValue.etag;
|
|
46899
|
+
value.vary = varyDirectives ?? cachedValue.vary;
|
|
46471
46900
|
value.headers = { ...cachedValue.headers, ...strippedHeaders };
|
|
46472
46901
|
|
|
46473
46902
|
downstreamOnHeaders();
|
|
@@ -46598,6 +47027,36 @@ function requireCacheHandler () {
|
|
|
46598
47027
|
}
|
|
46599
47028
|
}
|
|
46600
47029
|
|
|
47030
|
+
/**
|
|
47031
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheStore} store
|
|
47032
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey
|
|
47033
|
+
*/
|
|
47034
|
+
function deleteCachedValue (store, cacheKey) {
|
|
47035
|
+
try {
|
|
47036
|
+
store.delete(cacheKey)?.catch?.(noop);
|
|
47037
|
+
} catch {
|
|
47038
|
+
// Fail silently
|
|
47039
|
+
}
|
|
47040
|
+
}
|
|
47041
|
+
|
|
47042
|
+
function deleteCachedValueIfNotModified (statusCode, store, cacheKey) {
|
|
47043
|
+
if (statusCode === 304) {
|
|
47044
|
+
deleteCachedValue(store, cacheKey);
|
|
47045
|
+
}
|
|
47046
|
+
}
|
|
47047
|
+
|
|
47048
|
+
/**
|
|
47049
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47050
|
+
* @param {import('../../types/header.d.ts').IncomingHttpHeaders} resHeaders
|
|
47051
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives
|
|
47052
|
+
* @returns {boolean}
|
|
47053
|
+
*/
|
|
47054
|
+
function revalidationResponseDisallowsCachedReuse (cacheType, resHeaders, cacheControlDirectives) {
|
|
47055
|
+
return cacheControlDirectives['no-store'] === true ||
|
|
47056
|
+
(cacheType === 'shared' && cacheControlDirectives.private === true) ||
|
|
47057
|
+
(resHeaders.vary ? isInvalidOrWildcardVaryHeader(resHeaders.vary) : false)
|
|
47058
|
+
}
|
|
47059
|
+
|
|
46601
47060
|
/**
|
|
46602
47061
|
* @see https://www.rfc-editor.org/rfc/rfc9111.html#name-storing-responses-to-authen
|
|
46603
47062
|
*
|
|
@@ -46609,12 +47068,12 @@ function requireCacheHandler () {
|
|
|
46609
47068
|
*/
|
|
46610
47069
|
function canCacheResponse (cacheType, statusCode, resHeaders, cacheControlDirectives, reqHeaders) {
|
|
46611
47070
|
// Status code must be final and understood.
|
|
46612
|
-
if (statusCode < 200 || NOT_UNDERSTOOD_STATUS_CODES
|
|
47071
|
+
if (statusCode < 200 || arrayIncludes(NOT_UNDERSTOOD_STATUS_CODES, statusCode)) {
|
|
46613
47072
|
return false
|
|
46614
47073
|
}
|
|
46615
47074
|
// Responses with neither status codes that are heuristically cacheable, nor "explicit enough" caching
|
|
46616
47075
|
// directives, are not cacheable. "Explicit enough": see https://www.rfc-editor.org/rfc/rfc9111.html#section-3
|
|
46617
|
-
if (!HEURISTICALLY_CACHEABLE_STATUS_CODES
|
|
47076
|
+
if (!arrayIncludes(HEURISTICALLY_CACHEABLE_STATUS_CODES, statusCode) && !resHeaders['expires'] &&
|
|
46618
47077
|
!cacheControlDirectives.public &&
|
|
46619
47078
|
cacheControlDirectives['max-age'] === undefined &&
|
|
46620
47079
|
// RFC 9111: a private response directive, if the cache is not shared
|
|
@@ -46633,12 +47092,12 @@ function requireCacheHandler () {
|
|
|
46633
47092
|
}
|
|
46634
47093
|
|
|
46635
47094
|
// https://www.rfc-editor.org/rfc/rfc9111.html#section-4.1-5
|
|
46636
|
-
if (resHeaders.vary
|
|
47095
|
+
if (resHeaders.vary && hasVaryStar(resHeaders.vary)) {
|
|
46637
47096
|
return false
|
|
46638
47097
|
}
|
|
46639
47098
|
|
|
46640
47099
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-storing-responses-to-authen
|
|
46641
|
-
if (reqHeaders
|
|
47100
|
+
if (reqHeaders != null && Object.hasOwn(reqHeaders, 'authorization')) {
|
|
46642
47101
|
if (
|
|
46643
47102
|
!cacheControlDirectives.public &&
|
|
46644
47103
|
!cacheControlDirectives['s-maxage'] &&
|
|
@@ -46653,14 +47112,14 @@ function requireCacheHandler () {
|
|
|
46653
47112
|
|
|
46654
47113
|
if (
|
|
46655
47114
|
Array.isArray(cacheControlDirectives['no-cache']) &&
|
|
46656
|
-
cacheControlDirectives['no-cache']
|
|
47115
|
+
arrayIncludes(cacheControlDirectives['no-cache'], 'authorization')
|
|
46657
47116
|
) {
|
|
46658
47117
|
return false
|
|
46659
47118
|
}
|
|
46660
47119
|
|
|
46661
47120
|
if (
|
|
46662
47121
|
Array.isArray(cacheControlDirectives['private']) &&
|
|
46663
|
-
cacheControlDirectives['private']
|
|
47122
|
+
arrayIncludes(cacheControlDirectives['private'], 'authorization')
|
|
46664
47123
|
) {
|
|
46665
47124
|
return false
|
|
46666
47125
|
}
|
|
@@ -46669,14 +47128,51 @@ function requireCacheHandler () {
|
|
|
46669
47128
|
return true
|
|
46670
47129
|
}
|
|
46671
47130
|
|
|
47131
|
+
/**
|
|
47132
|
+
* @param {string | string[]} dateHeader
|
|
47133
|
+
* @returns {Date | null | undefined}
|
|
47134
|
+
*/
|
|
47135
|
+
function getDate (dateHeader) {
|
|
47136
|
+
let dateValue = dateHeader;
|
|
47137
|
+
if (Array.isArray(dateValue)) {
|
|
47138
|
+
if (dateValue.length !== 1) {
|
|
47139
|
+
return null
|
|
47140
|
+
}
|
|
47141
|
+
|
|
47142
|
+
dateValue = dateValue[0];
|
|
47143
|
+
}
|
|
47144
|
+
|
|
47145
|
+
if (typeof dateValue !== 'string') {
|
|
47146
|
+
return null
|
|
47147
|
+
}
|
|
47148
|
+
|
|
47149
|
+
return parseHttpDate(dateValue)
|
|
47150
|
+
}
|
|
47151
|
+
|
|
46672
47152
|
/**
|
|
46673
47153
|
* @param {string | string[]} ageHeader
|
|
46674
47154
|
* @returns {number | undefined}
|
|
46675
47155
|
*/
|
|
46676
47156
|
function getAge (ageHeader) {
|
|
46677
|
-
|
|
47157
|
+
let ageValue = ageHeader;
|
|
47158
|
+
if (Array.isArray(ageValue)) {
|
|
47159
|
+
if (ageValue.length !== 1) {
|
|
47160
|
+
return MAX_RESPONSE_AGE
|
|
47161
|
+
}
|
|
47162
|
+
|
|
47163
|
+
ageValue = ageValue[0];
|
|
47164
|
+
}
|
|
47165
|
+
|
|
47166
|
+
if (typeof ageValue !== 'string' || !/^[\t ]*[0-9]+[\t ]*$/.test(ageValue)) {
|
|
47167
|
+
return MAX_RESPONSE_AGE
|
|
47168
|
+
}
|
|
47169
|
+
|
|
47170
|
+
const age = BigInt(ageValue.replace(/^[\t ]+|[\t ]+$/g, ''));
|
|
47171
|
+
if (age >= BigInt(MAX_RESPONSE_AGE / 1000)) {
|
|
47172
|
+
return MAX_RESPONSE_AGE
|
|
47173
|
+
}
|
|
46678
47174
|
|
|
46679
|
-
return
|
|
47175
|
+
return Number(age) * 1000
|
|
46680
47176
|
}
|
|
46681
47177
|
|
|
46682
47178
|
/**
|
|
@@ -46694,43 +47190,60 @@ function requireCacheHandler () {
|
|
|
46694
47190
|
// Prioritize s-maxage since we're a shared cache
|
|
46695
47191
|
// s-maxage > max-age > Expire
|
|
46696
47192
|
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.10-3
|
|
47193
|
+
if (hasInvalidCacheControlDirective(cacheControlDirectives, 's-maxage')) {
|
|
47194
|
+
return 0
|
|
47195
|
+
}
|
|
47196
|
+
|
|
46697
47197
|
const sMaxAge = cacheControlDirectives['s-maxage'];
|
|
46698
47198
|
if (sMaxAge !== undefined) {
|
|
46699
|
-
return sMaxAge
|
|
47199
|
+
return sMaxAge * 1000
|
|
46700
47200
|
}
|
|
46701
47201
|
}
|
|
46702
47202
|
|
|
47203
|
+
if (hasInvalidCacheControlDirective(cacheControlDirectives, 'max-age')) {
|
|
47204
|
+
return 0
|
|
47205
|
+
}
|
|
47206
|
+
|
|
46703
47207
|
const maxAge = cacheControlDirectives['max-age'];
|
|
46704
47208
|
if (maxAge !== undefined) {
|
|
46705
|
-
return maxAge
|
|
47209
|
+
return maxAge * 1000
|
|
46706
47210
|
}
|
|
46707
47211
|
|
|
46708
|
-
if (
|
|
47212
|
+
if (Object.hasOwn(resHeaders, 'expires')) {
|
|
46709
47213
|
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.3
|
|
47214
|
+
if (typeof resHeaders.expires !== 'string') {
|
|
47215
|
+
return 0
|
|
47216
|
+
}
|
|
47217
|
+
|
|
46710
47218
|
const expiresDate = parseHttpDate(resHeaders.expires);
|
|
46711
|
-
if (expiresDate) {
|
|
46712
|
-
|
|
46713
|
-
|
|
46714
|
-
}
|
|
47219
|
+
if (!expiresDate) {
|
|
47220
|
+
return 0
|
|
47221
|
+
}
|
|
46715
47222
|
|
|
46716
|
-
|
|
46717
|
-
|
|
46718
|
-
|
|
46719
|
-
}
|
|
47223
|
+
if (now >= expiresDate.getTime()) {
|
|
47224
|
+
return 0
|
|
47225
|
+
}
|
|
46720
47226
|
|
|
46721
|
-
|
|
46722
|
-
|
|
46723
|
-
|
|
47227
|
+
if (responseDate) {
|
|
47228
|
+
if (responseDate >= expiresDate) {
|
|
47229
|
+
return 0
|
|
47230
|
+
}
|
|
47231
|
+
|
|
47232
|
+
const freshnessLifetime = expiresDate.getTime() - responseDate.getTime();
|
|
47233
|
+
if (age !== undefined && age >= freshnessLifetime) {
|
|
47234
|
+
return 0
|
|
46724
47235
|
}
|
|
46725
47236
|
|
|
46726
|
-
return
|
|
47237
|
+
return freshnessLifetime
|
|
46727
47238
|
}
|
|
47239
|
+
|
|
47240
|
+
return expiresDate.getTime() - now
|
|
46728
47241
|
}
|
|
46729
47242
|
|
|
46730
47243
|
if (typeof resHeaders['last-modified'] === 'string') {
|
|
46731
47244
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-calculating-heuristic-fresh
|
|
46732
|
-
const lastModified =
|
|
46733
|
-
if (
|
|
47245
|
+
const lastModified = parseHttpDate(resHeaders['last-modified']);
|
|
47246
|
+
if (lastModified) {
|
|
46734
47247
|
if (lastModified.getTime() >= now) {
|
|
46735
47248
|
return undefined
|
|
46736
47249
|
}
|
|
@@ -46743,18 +47256,19 @@ function requireCacheHandler () {
|
|
|
46743
47256
|
|
|
46744
47257
|
if (cacheControlDirectives.immutable) {
|
|
46745
47258
|
// https://www.rfc-editor.org/rfc/rfc8246.html#section-2.2
|
|
46746
|
-
return
|
|
47259
|
+
return 31536000000
|
|
46747
47260
|
}
|
|
46748
47261
|
|
|
46749
47262
|
return undefined
|
|
46750
47263
|
}
|
|
46751
47264
|
|
|
46752
47265
|
/**
|
|
46753
|
-
* @param {number}
|
|
47266
|
+
* @param {number} baseTime
|
|
47267
|
+
* @param {number} cachedAt
|
|
46754
47268
|
* @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives
|
|
46755
47269
|
* @param {number} staleAt
|
|
46756
47270
|
*/
|
|
46757
|
-
function determineDeleteAt (
|
|
47271
|
+
function determineDeleteAt (baseTime, cachedAt, cacheControlDirectives, staleAt) {
|
|
46758
47272
|
let staleWhileRevalidate = -Infinity;
|
|
46759
47273
|
let staleIfError = -Infinity;
|
|
46760
47274
|
let immutable = -Infinity;
|
|
@@ -46768,15 +47282,21 @@ function requireCacheHandler () {
|
|
|
46768
47282
|
}
|
|
46769
47283
|
|
|
46770
47284
|
if (cacheControlDirectives.immutable && staleWhileRevalidate === -Infinity && staleIfError === -Infinity) {
|
|
46771
|
-
immutable =
|
|
47285
|
+
immutable = cachedAt + 31536000000;
|
|
46772
47286
|
}
|
|
46773
47287
|
|
|
46774
47288
|
// When no stale directives or immutable flag, add a revalidation buffer
|
|
46775
47289
|
// equal to the freshness lifetime so the entry survives past staleAt long
|
|
46776
47290
|
// enough to be revalidated instead of silently disappearing.
|
|
47291
|
+
//
|
|
47292
|
+
// Response Date headers only have second precision, so baseTime can trail the
|
|
47293
|
+
// actual cache insertion time by up to ~1s. Pad the buffer by that bounded
|
|
47294
|
+
// skew so short-lived entries do not disappear exactly when they should be
|
|
47295
|
+
// revalidated.
|
|
46777
47296
|
if (staleWhileRevalidate === -Infinity && staleIfError === -Infinity && immutable === -Infinity) {
|
|
46778
|
-
const freshnessLifetime = staleAt -
|
|
46779
|
-
|
|
47297
|
+
const freshnessLifetime = staleAt - baseTime;
|
|
47298
|
+
const datePrecisionPadding = Math.min(Math.max(cachedAt - baseTime, 0), 1000);
|
|
47299
|
+
return staleAt + freshnessLifetime + datePrecisionPadding
|
|
46780
47300
|
}
|
|
46781
47301
|
|
|
46782
47302
|
return Math.max(staleAt, staleWhileRevalidate, staleIfError, immutable)
|
|
@@ -46803,14 +47323,7 @@ function requireCacheHandler () {
|
|
|
46803
47323
|
];
|
|
46804
47324
|
|
|
46805
47325
|
if (resHeaders['connection']) {
|
|
46806
|
-
|
|
46807
|
-
// connection: a
|
|
46808
|
-
// connection: b
|
|
46809
|
-
headersToRemove.push(...resHeaders['connection'].map(header => header.trim()));
|
|
46810
|
-
} else {
|
|
46811
|
-
// connection: a, b
|
|
46812
|
-
headersToRemove.push(...resHeaders['connection'].split(',').map(header => header.trim()));
|
|
46813
|
-
}
|
|
47326
|
+
appendConnectionHeaderTokens(headersToRemove, resHeaders['connection']);
|
|
46814
47327
|
}
|
|
46815
47328
|
|
|
46816
47329
|
if (Array.isArray(cacheControlDirectives['no-cache'])) {
|
|
@@ -46823,7 +47336,7 @@ function requireCacheHandler () {
|
|
|
46823
47336
|
|
|
46824
47337
|
let strippedHeaders;
|
|
46825
47338
|
for (const headerName of headersToRemove) {
|
|
46826
|
-
if (resHeaders
|
|
47339
|
+
if (Object.hasOwn(resHeaders, headerName)) {
|
|
46827
47340
|
strippedHeaders ??= { ...resHeaders };
|
|
46828
47341
|
delete strippedHeaders[headerName];
|
|
46829
47342
|
}
|
|
@@ -46832,14 +47345,6 @@ function requireCacheHandler () {
|
|
|
46832
47345
|
return strippedHeaders ?? resHeaders
|
|
46833
47346
|
}
|
|
46834
47347
|
|
|
46835
|
-
/**
|
|
46836
|
-
* @param {Date} date
|
|
46837
|
-
* @returns {boolean}
|
|
46838
|
-
*/
|
|
46839
|
-
function isValidDate (date) {
|
|
46840
|
-
return date instanceof Date && Number.isFinite(date.valueOf())
|
|
46841
|
-
}
|
|
46842
|
-
|
|
46843
47348
|
cacheHandler = CacheHandler;
|
|
46844
47349
|
return cacheHandler;
|
|
46845
47350
|
}
|
|
@@ -47069,17 +47574,62 @@ function requireMemoryCacheStore () {
|
|
|
47069
47574
|
}
|
|
47070
47575
|
|
|
47071
47576
|
function findEntry (key, entries, now) {
|
|
47072
|
-
|
|
47073
|
-
entry
|
|
47074
|
-
|
|
47075
|
-
|
|
47076
|
-
|
|
47077
|
-
|
|
47577
|
+
for (let i = 0; i < entries.length; i++) {
|
|
47578
|
+
const entry = entries[i];
|
|
47579
|
+
if (
|
|
47580
|
+
entry.deleteAt > now &&
|
|
47581
|
+
entry.method === key.method &&
|
|
47582
|
+
varyMatches(key, entry)
|
|
47583
|
+
) {
|
|
47584
|
+
return entry
|
|
47585
|
+
}
|
|
47586
|
+
}
|
|
47587
|
+
}
|
|
47588
|
+
|
|
47589
|
+
function varyMatches (key, entry) {
|
|
47590
|
+
if (entry.vary == null) {
|
|
47591
|
+
return true
|
|
47592
|
+
}
|
|
47593
|
+
|
|
47594
|
+
for (const headerName in entry.vary) {
|
|
47595
|
+
if (Object.hasOwn(entry.vary, headerName) && !headerValueEquals(key.headers?.[headerName], entry.vary[headerName])) {
|
|
47596
|
+
return false
|
|
47597
|
+
}
|
|
47598
|
+
}
|
|
47599
|
+
|
|
47600
|
+
return true
|
|
47601
|
+
}
|
|
47602
|
+
|
|
47603
|
+
/**
|
|
47604
|
+
* @param {string|string[]|null|undefined} lhs
|
|
47605
|
+
* @param {string|string[]|null|undefined} rhs
|
|
47606
|
+
* @returns {boolean}
|
|
47607
|
+
*/
|
|
47608
|
+
function headerValueEquals (lhs, rhs) {
|
|
47609
|
+
if (lhs == null && rhs == null) {
|
|
47610
|
+
return true
|
|
47611
|
+
}
|
|
47612
|
+
|
|
47613
|
+
if ((lhs == null && rhs != null) ||
|
|
47614
|
+
(lhs != null && rhs == null)) {
|
|
47615
|
+
return false
|
|
47616
|
+
}
|
|
47617
|
+
|
|
47618
|
+
if (Array.isArray(lhs) && Array.isArray(rhs)) {
|
|
47619
|
+
if (lhs.length !== rhs.length) {
|
|
47620
|
+
return false
|
|
47621
|
+
}
|
|
47622
|
+
|
|
47623
|
+
for (let i = 0; i < lhs.length; i++) {
|
|
47624
|
+
if (lhs[i] !== rhs[i]) {
|
|
47625
|
+
return false
|
|
47078
47626
|
}
|
|
47627
|
+
}
|
|
47079
47628
|
|
|
47080
|
-
|
|
47081
|
-
|
|
47082
|
-
|
|
47629
|
+
return true
|
|
47630
|
+
}
|
|
47631
|
+
|
|
47632
|
+
return lhs === rhs
|
|
47083
47633
|
}
|
|
47084
47634
|
|
|
47085
47635
|
memoryCacheStore = MemoryCacheStore;
|
|
@@ -47112,7 +47662,7 @@ function requireCacheRevalidationHandler () {
|
|
|
47112
47662
|
#successful = false
|
|
47113
47663
|
|
|
47114
47664
|
/**
|
|
47115
|
-
* @type {((boolean, any) => void) | null}
|
|
47665
|
+
* @type {((success: boolean, context?: any, statusCode?: number, headers?: import('../../types/header.d.ts').IncomingHttpHeaders) => void) | null}
|
|
47116
47666
|
*/
|
|
47117
47667
|
#callback
|
|
47118
47668
|
|
|
@@ -47129,7 +47679,7 @@ function requireCacheRevalidationHandler () {
|
|
|
47129
47679
|
#allowErrorStatusCodes
|
|
47130
47680
|
|
|
47131
47681
|
/**
|
|
47132
|
-
* @param {(boolean) => void} callback Function to call if the cached value is valid
|
|
47682
|
+
* @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
|
|
47133
47683
|
* @param {import('../../types/dispatcher.d.ts').default.DispatchHandlers} handler
|
|
47134
47684
|
* @param {boolean} allowErrorStatusCodes
|
|
47135
47685
|
*/
|
|
@@ -47164,7 +47714,7 @@ function requireCacheRevalidationHandler () {
|
|
|
47164
47714
|
// https://datatracker.ietf.org/doc/html/rfc5861#section-4
|
|
47165
47715
|
this.#successful = statusCode === 304 ||
|
|
47166
47716
|
(this.#allowErrorStatusCodes && statusCode >= 500 && statusCode <= 504);
|
|
47167
|
-
this.#callback(this.#successful, this.#context);
|
|
47717
|
+
this.#callback(this.#successful, this.#context, statusCode, headers);
|
|
47168
47718
|
this.#callback = null;
|
|
47169
47719
|
|
|
47170
47720
|
if (this.#successful) {
|
|
@@ -47231,8 +47781,9 @@ function requireCache$1 () {
|
|
|
47231
47781
|
const CacheHandler = requireCacheHandler();
|
|
47232
47782
|
const MemoryCacheStore = requireMemoryCacheStore();
|
|
47233
47783
|
const CacheRevalidationHandler = requireCacheRevalidationHandler();
|
|
47234
|
-
const { assertCacheStore, assertCacheMethods, makeCacheKey, normalizeHeaders, parseCacheControlHeader } = requireCache$2();
|
|
47784
|
+
const { assertCacheStore, assertCacheMethods, makeCacheKey, normalizeHeaders, parseCacheControlHeader, isInvalidOrWildcardVaryHeader } = requireCache$2();
|
|
47235
47785
|
const { AbortError } = requireErrors$1();
|
|
47786
|
+
const { parseHttpDate } = requireDate();
|
|
47236
47787
|
|
|
47237
47788
|
/**
|
|
47238
47789
|
* @param {(string | RegExp)[] | undefined} origins
|
|
@@ -47253,6 +47804,44 @@ function requireCache$1 () {
|
|
|
47253
47804
|
|
|
47254
47805
|
const nop = () => {};
|
|
47255
47806
|
|
|
47807
|
+
function trimOWS (value) {
|
|
47808
|
+
return value.replace(/^[\t ]+|[\t ]+$/g, '')
|
|
47809
|
+
}
|
|
47810
|
+
|
|
47811
|
+
function arrayIncludes (array, value) {
|
|
47812
|
+
for (let i = 0; i < array.length; i++) {
|
|
47813
|
+
if (array[i] === value) {
|
|
47814
|
+
return true
|
|
47815
|
+
}
|
|
47816
|
+
}
|
|
47817
|
+
|
|
47818
|
+
return false
|
|
47819
|
+
}
|
|
47820
|
+
|
|
47821
|
+
function hasPragmaNoCache (headers) {
|
|
47822
|
+
const pragma = headers?.pragma;
|
|
47823
|
+
if (!pragma) {
|
|
47824
|
+
return false
|
|
47825
|
+
}
|
|
47826
|
+
|
|
47827
|
+
const values = Array.isArray(pragma) ? pragma : [pragma];
|
|
47828
|
+
for (let i = 0; i < values.length; i++) {
|
|
47829
|
+
const value = values[i];
|
|
47830
|
+
if (typeof value !== 'string') {
|
|
47831
|
+
continue
|
|
47832
|
+
}
|
|
47833
|
+
|
|
47834
|
+
const directives = value.split(',');
|
|
47835
|
+
for (let j = 0; j < directives.length; j++) {
|
|
47836
|
+
if (trimOWS(directives[j]).toLowerCase() === 'no-cache') {
|
|
47837
|
+
return true
|
|
47838
|
+
}
|
|
47839
|
+
}
|
|
47840
|
+
}
|
|
47841
|
+
|
|
47842
|
+
return false
|
|
47843
|
+
}
|
|
47844
|
+
|
|
47256
47845
|
/**
|
|
47257
47846
|
* @typedef {(options: import('../../types/dispatcher.d.ts').default.DispatchOptions, handler: import('../../types/dispatcher.d.ts').default.DispatchHandler) => void} DispatchFn
|
|
47258
47847
|
*/
|
|
@@ -47282,16 +47871,92 @@ function requireCache$1 () {
|
|
|
47282
47871
|
return false
|
|
47283
47872
|
}
|
|
47284
47873
|
|
|
47874
|
+
/**
|
|
47875
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result
|
|
47876
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47877
|
+
* @returns {boolean}
|
|
47878
|
+
*/
|
|
47879
|
+
function staleResponseRequiresRevalidation (result, cacheType) {
|
|
47880
|
+
return result.cacheControlDirectives?.['must-revalidate'] === true ||
|
|
47881
|
+
(cacheType === 'shared' && (
|
|
47882
|
+
result.cacheControlDirectives?.['proxy-revalidate'] === true ||
|
|
47883
|
+
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.10
|
|
47884
|
+
// s-maxage implies proxy-revalidate for shared caches.
|
|
47885
|
+
result.cacheControlDirectives?.['s-maxage'] !== undefined
|
|
47886
|
+
))
|
|
47887
|
+
}
|
|
47888
|
+
|
|
47889
|
+
/**
|
|
47890
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47891
|
+
* @param {import('../../types/header.d.ts').IncomingHttpHeaders} headers
|
|
47892
|
+
* @returns {boolean}
|
|
47893
|
+
*/
|
|
47894
|
+
function revalidationResponseDisallowsCachedReuse (cacheType, headers) {
|
|
47895
|
+
if (headers.vary && isInvalidOrWildcardVaryHeader(headers.vary)) {
|
|
47896
|
+
return true
|
|
47897
|
+
}
|
|
47898
|
+
|
|
47899
|
+
const cacheControl = headers['cache-control'];
|
|
47900
|
+
if (!cacheControl) {
|
|
47901
|
+
return false
|
|
47902
|
+
}
|
|
47903
|
+
|
|
47904
|
+
const cacheControlDirectives = parseCacheControlHeader(cacheControl);
|
|
47905
|
+
return cacheControlDirectives['no-store'] === true ||
|
|
47906
|
+
(cacheType === 'shared' && cacheControlDirectives.private === true)
|
|
47907
|
+
}
|
|
47908
|
+
|
|
47909
|
+
function revalidationResponseUpdatesCacheControl (headers) {
|
|
47910
|
+
return headers['cache-control'] !== undefined
|
|
47911
|
+
}
|
|
47912
|
+
|
|
47913
|
+
function deleteCachedValue (store, cacheKey) {
|
|
47914
|
+
try {
|
|
47915
|
+
store.delete(cacheKey)?.catch?.(nop);
|
|
47916
|
+
} catch {
|
|
47917
|
+
// Fail silently
|
|
47918
|
+
}
|
|
47919
|
+
}
|
|
47920
|
+
|
|
47921
|
+
function getUsableLastModified (headers) {
|
|
47922
|
+
const lastModified = headers?.['last-modified'];
|
|
47923
|
+
if (typeof lastModified === 'string' && parseHttpDate(lastModified)) {
|
|
47924
|
+
return lastModified
|
|
47925
|
+
}
|
|
47926
|
+
}
|
|
47927
|
+
|
|
47928
|
+
function makeRevalidationHeaders (opts, result) {
|
|
47929
|
+
const headers = {
|
|
47930
|
+
...opts.headers,
|
|
47931
|
+
'if-modified-since': getUsableLastModified(result.headers) ?? new Date(result.cachedAt).toUTCString()
|
|
47932
|
+
};
|
|
47933
|
+
|
|
47934
|
+
if (result.etag) {
|
|
47935
|
+
headers['if-none-match'] = result.etag;
|
|
47936
|
+
}
|
|
47937
|
+
|
|
47938
|
+
if (result.vary) {
|
|
47939
|
+
for (const key in result.vary) {
|
|
47940
|
+
if (result.vary[key] != null) {
|
|
47941
|
+
headers[key] = result.vary[key];
|
|
47942
|
+
}
|
|
47943
|
+
}
|
|
47944
|
+
}
|
|
47945
|
+
|
|
47946
|
+
return headers
|
|
47947
|
+
}
|
|
47948
|
+
|
|
47285
47949
|
/**
|
|
47286
47950
|
* @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result
|
|
47287
47951
|
* @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives | undefined} cacheControlDirectives
|
|
47952
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47288
47953
|
* @returns {boolean}
|
|
47289
47954
|
*/
|
|
47290
|
-
function isStale (result, cacheControlDirectives) {
|
|
47955
|
+
function isStale (result, cacheControlDirectives, cacheType) {
|
|
47291
47956
|
const now = Date.now();
|
|
47292
47957
|
if (now > result.staleAt) {
|
|
47293
47958
|
// Response is stale
|
|
47294
|
-
if (cacheControlDirectives?.['max-stale']) {
|
|
47959
|
+
if (!staleResponseRequiresRevalidation(result, cacheType) && cacheControlDirectives?.['max-stale']) {
|
|
47295
47960
|
// There's a threshold where we can serve stale responses, let's see if
|
|
47296
47961
|
// we're in it
|
|
47297
47962
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-max-stale
|
|
@@ -47318,11 +47983,12 @@ function requireCache$1 () {
|
|
|
47318
47983
|
/**
|
|
47319
47984
|
* Check if we're within the stale-while-revalidate window for a stale response
|
|
47320
47985
|
* @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result
|
|
47986
|
+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType
|
|
47321
47987
|
* @returns {boolean}
|
|
47322
47988
|
*/
|
|
47323
|
-
function withinStaleWhileRevalidateWindow (result) {
|
|
47989
|
+
function withinStaleWhileRevalidateWindow (result, cacheType) {
|
|
47324
47990
|
const staleWhileRevalidate = result.cacheControlDirectives?.['stale-while-revalidate'];
|
|
47325
|
-
if (!staleWhileRevalidate) {
|
|
47991
|
+
if (!staleWhileRevalidate || staleResponseRequiresRevalidation(result, cacheType)) {
|
|
47326
47992
|
return false
|
|
47327
47993
|
}
|
|
47328
47994
|
|
|
@@ -47492,14 +48158,10 @@ function requireCache$1 () {
|
|
|
47492
48158
|
}
|
|
47493
48159
|
|
|
47494
48160
|
const age = Math.round((now - result.cachedAt) / 1000);
|
|
47495
|
-
|
|
47496
|
-
// Response is considered expired for this specific request
|
|
47497
|
-
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.1.1
|
|
47498
|
-
return dispatch(opts, handler)
|
|
47499
|
-
}
|
|
48161
|
+
const requestMaxAgeExpired = reqCacheControl?.['max-age'] !== undefined && age >= reqCacheControl['max-age'];
|
|
47500
48162
|
|
|
47501
|
-
const stale = isStale(result, reqCacheControl);
|
|
47502
|
-
const revalidate = needsRevalidation(result, reqCacheControl, opts);
|
|
48163
|
+
const stale = requestMaxAgeExpired || isStale(result, reqCacheControl, globalOpts.type);
|
|
48164
|
+
const revalidate = requestMaxAgeExpired || needsRevalidation(result, reqCacheControl, opts);
|
|
47503
48165
|
|
|
47504
48166
|
// Check if the response is stale
|
|
47505
48167
|
if (stale || revalidate) {
|
|
@@ -47511,28 +48173,13 @@ function requireCache$1 () {
|
|
|
47511
48173
|
|
|
47512
48174
|
// RFC 5861: If we're within stale-while-revalidate window, serve stale immediately
|
|
47513
48175
|
// and revalidate in background, unless immediate revalidation is necessary
|
|
47514
|
-
if (!revalidate && withinStaleWhileRevalidateWindow(result)) {
|
|
48176
|
+
if (!revalidate && withinStaleWhileRevalidateWindow(result, globalOpts.type)) {
|
|
47515
48177
|
// Serve stale response immediately
|
|
47516
48178
|
sendCachedValue(handler, opts, result, age, null, true);
|
|
47517
48179
|
|
|
47518
48180
|
// Start background revalidation (fire-and-forget)
|
|
47519
48181
|
queueMicrotask(() => {
|
|
47520
|
-
const headers =
|
|
47521
|
-
...opts.headers,
|
|
47522
|
-
'if-modified-since': new Date(result.cachedAt).toUTCString()
|
|
47523
|
-
};
|
|
47524
|
-
|
|
47525
|
-
if (result.etag) {
|
|
47526
|
-
headers['if-none-match'] = result.etag;
|
|
47527
|
-
}
|
|
47528
|
-
|
|
47529
|
-
if (result.vary) {
|
|
47530
|
-
for (const key in result.vary) {
|
|
47531
|
-
if (result.vary[key] != null) {
|
|
47532
|
-
headers[key] = result.vary[key];
|
|
47533
|
-
}
|
|
47534
|
-
}
|
|
47535
|
-
}
|
|
48182
|
+
const headers = makeRevalidationHeaders(opts, result);
|
|
47536
48183
|
|
|
47537
48184
|
// Background revalidation - update cache if we get new data
|
|
47538
48185
|
dispatch(
|
|
@@ -47556,28 +48203,15 @@ function requireCache$1 () {
|
|
|
47556
48203
|
}
|
|
47557
48204
|
|
|
47558
48205
|
let withinStaleIfErrorThreshold = false;
|
|
47559
|
-
|
|
47560
|
-
|
|
47561
|
-
|
|
47562
|
-
|
|
47563
|
-
|
|
47564
|
-
const headers = {
|
|
47565
|
-
...opts.headers,
|
|
47566
|
-
'if-modified-since': new Date(result.cachedAt).toUTCString()
|
|
47567
|
-
};
|
|
47568
|
-
|
|
47569
|
-
if (result.etag) {
|
|
47570
|
-
headers['if-none-match'] = result.etag;
|
|
47571
|
-
}
|
|
47572
|
-
|
|
47573
|
-
if (result.vary) {
|
|
47574
|
-
for (const key in result.vary) {
|
|
47575
|
-
if (result.vary[key] != null) {
|
|
47576
|
-
headers[key] = result.vary[key];
|
|
47577
|
-
}
|
|
48206
|
+
if (!staleResponseRequiresRevalidation(result, globalOpts.type)) {
|
|
48207
|
+
const staleIfErrorExpiry = result.cacheControlDirectives['stale-if-error'] ?? reqCacheControl?.['stale-if-error'];
|
|
48208
|
+
if (staleIfErrorExpiry) {
|
|
48209
|
+
withinStaleIfErrorThreshold = now < (result.staleAt + (staleIfErrorExpiry * 1000));
|
|
47578
48210
|
}
|
|
47579
48211
|
}
|
|
47580
48212
|
|
|
48213
|
+
const headers = makeRevalidationHeaders(opts, result);
|
|
48214
|
+
|
|
47581
48215
|
// We need to revalidate the response
|
|
47582
48216
|
return dispatch(
|
|
47583
48217
|
{
|
|
@@ -47585,8 +48219,23 @@ function requireCache$1 () {
|
|
|
47585
48219
|
headers
|
|
47586
48220
|
},
|
|
47587
48221
|
new CacheRevalidationHandler(
|
|
47588
|
-
(success, context) => {
|
|
48222
|
+
(success, context, statusCode, headers) => {
|
|
47589
48223
|
if (success) {
|
|
48224
|
+
if (statusCode === 304) {
|
|
48225
|
+
if (revalidationResponseDisallowsCachedReuse(globalOpts.type, headers)) {
|
|
48226
|
+
if (util.isStream(result.body)) {
|
|
48227
|
+
result.body.on('error', nop).destroy();
|
|
48228
|
+
}
|
|
48229
|
+
|
|
48230
|
+
deleteCachedValue(globalOpts.store, cacheKey);
|
|
48231
|
+
return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler))
|
|
48232
|
+
}
|
|
48233
|
+
|
|
48234
|
+
if (revalidationResponseUpdatesCacheControl(headers)) {
|
|
48235
|
+
deleteCachedValue(globalOpts.store, cacheKey);
|
|
48236
|
+
}
|
|
48237
|
+
}
|
|
48238
|
+
|
|
47590
48239
|
// TODO: successful revalidation should be considered fresh (not give stale warning).
|
|
47591
48240
|
sendCachedValue(handler, opts, result, age, context, stale);
|
|
47592
48241
|
} else if (util.isStream(result.body)) {
|
|
@@ -47643,11 +48292,17 @@ function requireCache$1 () {
|
|
|
47643
48292
|
type
|
|
47644
48293
|
};
|
|
47645
48294
|
|
|
47646
|
-
const safeMethodsToNotCache =
|
|
48295
|
+
const safeMethodsToNotCache = [];
|
|
48296
|
+
for (let i = 0; i < util.safeHTTPMethods.length; i++) {
|
|
48297
|
+
const method = util.safeHTTPMethods[i];
|
|
48298
|
+
if (!arrayIncludes(methods, method)) {
|
|
48299
|
+
safeMethodsToNotCache.push(method);
|
|
48300
|
+
}
|
|
48301
|
+
}
|
|
47647
48302
|
|
|
47648
48303
|
return dispatch => {
|
|
47649
48304
|
return (opts, handler) => {
|
|
47650
|
-
if (!opts.origin || safeMethodsToNotCache
|
|
48305
|
+
if (!opts.origin || arrayIncludes(safeMethodsToNotCache, opts.method)) {
|
|
47651
48306
|
// Not a method we want to cache or we don't have the origin, skip
|
|
47652
48307
|
return dispatch(opts, handler)
|
|
47653
48308
|
}
|
|
@@ -47682,7 +48337,9 @@ function requireCache$1 () {
|
|
|
47682
48337
|
|
|
47683
48338
|
const reqCacheControl = opts.headers?.['cache-control']
|
|
47684
48339
|
? parseCacheControlHeader(opts.headers['cache-control'])
|
|
47685
|
-
:
|
|
48340
|
+
: hasPragmaNoCache(opts.headers)
|
|
48341
|
+
? { 'no-cache': true }
|
|
48342
|
+
: undefined;
|
|
47686
48343
|
|
|
47687
48344
|
if (reqCacheControl?.['no-store']) {
|
|
47688
48345
|
return dispatch(opts, handler)
|
|
@@ -49042,7 +49699,13 @@ function requireSqliteCacheStore () {
|
|
|
49042
49699
|
return false
|
|
49043
49700
|
}
|
|
49044
49701
|
|
|
49045
|
-
|
|
49702
|
+
for (let i = 0; i < lhs.length; i++) {
|
|
49703
|
+
if (lhs[i] !== rhs[i]) {
|
|
49704
|
+
return false
|
|
49705
|
+
}
|
|
49706
|
+
}
|
|
49707
|
+
|
|
49708
|
+
return true
|
|
49046
49709
|
}
|
|
49047
49710
|
|
|
49048
49711
|
return lhs === rhs
|
|
@@ -55442,7 +56105,7 @@ function requireUtil$3 () {
|
|
|
55442
56105
|
|
|
55443
56106
|
if (
|
|
55444
56107
|
code < 0x20 || // exclude CTLs (0-31)
|
|
55445
|
-
code
|
|
56108
|
+
code > 0x7E || // exclude DEL and non-ascii
|
|
55446
56109
|
code === 0x3B // ;
|
|
55447
56110
|
) {
|
|
55448
56111
|
throw new Error('Invalid cookie path')
|
|
@@ -55451,16 +56114,80 @@ function requireUtil$3 () {
|
|
|
55451
56114
|
}
|
|
55452
56115
|
|
|
55453
56116
|
/**
|
|
55454
|
-
*
|
|
55455
|
-
*
|
|
56117
|
+
* <let-dig> ::= <letter> | <digit>
|
|
56118
|
+
*
|
|
56119
|
+
* <letter> ::= any one of the 52 alphabetic characters A through Z in
|
|
56120
|
+
* upper case and a through z in lower case
|
|
56121
|
+
*
|
|
56122
|
+
* <digit> ::= any one of the ten digits 0 through 9r
|
|
56123
|
+
*
|
|
56124
|
+
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
|
|
56125
|
+
* @param {number} code
|
|
56126
|
+
*/
|
|
56127
|
+
function isLetterOrDigit (code) {
|
|
56128
|
+
return (
|
|
56129
|
+
(code >= 0x30 && code <= 0x39) || // 0-9
|
|
56130
|
+
(code >= 0x41 && code <= 0x5A) || // A-Z
|
|
56131
|
+
(code >= 0x61 && code <= 0x7A) // a-z
|
|
56132
|
+
)
|
|
56133
|
+
}
|
|
56134
|
+
|
|
56135
|
+
/**
|
|
56136
|
+
* Validates a cookie domain against the "preferred name syntax".
|
|
56137
|
+
*
|
|
56138
|
+
* <domain> ::= <subdomain> | " "
|
|
56139
|
+
* <subdomain> ::= <label> | <subdomain> "." <label>
|
|
56140
|
+
* <label> ::= <let-dig> [ [ <ldh-str> ] <let-dig> ]
|
|
56141
|
+
* <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
|
|
56142
|
+
* <let-dig-hyp> ::= <let-dig> | "-"
|
|
56143
|
+
*
|
|
56144
|
+
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
|
|
56145
|
+
* @see https://www.rfc-editor.org/rfc/rfc1123#section-2.1
|
|
56146
|
+
* @see https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4
|
|
55456
56147
|
* @param {string} domain
|
|
55457
56148
|
*/
|
|
55458
56149
|
function validateCookieDomain (domain) {
|
|
55459
|
-
|
|
55460
|
-
|
|
55461
|
-
|
|
55462
|
-
|
|
55463
|
-
|
|
56150
|
+
// <domain> ::= <subdomain> | " "
|
|
56151
|
+
if (domain === ' ') {
|
|
56152
|
+
return
|
|
56153
|
+
}
|
|
56154
|
+
|
|
56155
|
+
if (domain.length > 255) {
|
|
56156
|
+
throw new Error('Invalid cookie domain')
|
|
56157
|
+
}
|
|
56158
|
+
|
|
56159
|
+
let labelLength = 0;
|
|
56160
|
+
|
|
56161
|
+
for (let i = 0; i < domain.length; ++i) {
|
|
56162
|
+
const code = domain.charCodeAt(i);
|
|
56163
|
+
|
|
56164
|
+
if (code === 0x2E) {
|
|
56165
|
+
if (labelLength === 0) {
|
|
56166
|
+
throw new Error('Invalid cookie domain')
|
|
56167
|
+
}
|
|
56168
|
+
|
|
56169
|
+
if (domain.charCodeAt(i - 1) === 0x2D) { // "-"
|
|
56170
|
+
throw new Error('Invalid cookie domain')
|
|
56171
|
+
}
|
|
56172
|
+
|
|
56173
|
+
labelLength = 0;
|
|
56174
|
+
continue
|
|
56175
|
+
}
|
|
56176
|
+
|
|
56177
|
+
if (labelLength === 0 && !isLetterOrDigit(code)) {
|
|
56178
|
+
throw new Error('Invalid cookie domain')
|
|
56179
|
+
}
|
|
56180
|
+
|
|
56181
|
+
if (!isLetterOrDigit(code) && code !== 0x2D) { // "-"
|
|
56182
|
+
throw new Error('Invalid cookie domain')
|
|
56183
|
+
}
|
|
56184
|
+
|
|
56185
|
+
if (++labelLength > 63) {
|
|
56186
|
+
throw new Error('Invalid cookie domain')
|
|
56187
|
+
}
|
|
56188
|
+
}
|
|
56189
|
+
|
|
56190
|
+
if (labelLength === 0 || domain.charCodeAt(domain.length - 1) === 0x2D) { // "-"
|
|
55464
56191
|
throw new Error('Invalid cookie domain')
|
|
55465
56192
|
}
|
|
55466
56193
|
}
|
|
@@ -55603,7 +56330,13 @@ function requireUtil$3 () {
|
|
|
55603
56330
|
|
|
55604
56331
|
const [key, ...value] = part.split('=');
|
|
55605
56332
|
|
|
55606
|
-
|
|
56333
|
+
const trimmedKey = key.trim();
|
|
56334
|
+
const joinedValue = value.join('=');
|
|
56335
|
+
|
|
56336
|
+
validateCookieName(trimmedKey);
|
|
56337
|
+
validateCookieValue(joinedValue);
|
|
56338
|
+
|
|
56339
|
+
out.push(`${trimmedKey}=${joinedValue}`);
|
|
55607
56340
|
}
|
|
55608
56341
|
|
|
55609
56342
|
return out.join('; ')
|
|
@@ -87693,15 +88426,19 @@ function requireJson () {
|
|
|
87693
88426
|
function json (options) {
|
|
87694
88427
|
var opts = options || {};
|
|
87695
88428
|
|
|
87696
|
-
var limit = typeof opts.limit
|
|
87697
|
-
?
|
|
87698
|
-
: opts.limit;
|
|
88429
|
+
var limit = typeof opts.limit === 'undefined' || opts.limit === null
|
|
88430
|
+
? 102400 // 100kb default
|
|
88431
|
+
: bytes.parse(opts.limit);
|
|
87699
88432
|
var inflate = opts.inflate !== false;
|
|
87700
88433
|
var reviver = opts.reviver;
|
|
87701
88434
|
var strict = opts.strict !== false;
|
|
87702
88435
|
var type = opts.type || 'application/json';
|
|
87703
88436
|
var verify = opts.verify || false;
|
|
87704
88437
|
|
|
88438
|
+
if (limit === null) {
|
|
88439
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid')
|
|
88440
|
+
}
|
|
88441
|
+
|
|
87705
88442
|
if (verify !== false && typeof verify !== 'function') {
|
|
87706
88443
|
throw new TypeError('option verify must be function')
|
|
87707
88444
|
}
|
|
@@ -87924,12 +88661,16 @@ function requireRaw () {
|
|
|
87924
88661
|
var opts = options || {};
|
|
87925
88662
|
|
|
87926
88663
|
var inflate = opts.inflate !== false;
|
|
87927
|
-
var limit = typeof opts.limit
|
|
87928
|
-
?
|
|
87929
|
-
: opts.limit;
|
|
88664
|
+
var limit = typeof opts.limit === 'undefined' || opts.limit === null
|
|
88665
|
+
? 102400 // 100kb default
|
|
88666
|
+
: bytes.parse(opts.limit);
|
|
87930
88667
|
var type = opts.type || 'application/octet-stream';
|
|
87931
88668
|
var verify = opts.verify || false;
|
|
87932
88669
|
|
|
88670
|
+
if (limit === null) {
|
|
88671
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid')
|
|
88672
|
+
}
|
|
88673
|
+
|
|
87933
88674
|
if (verify !== false && typeof verify !== 'function') {
|
|
87934
88675
|
throw new TypeError('option verify must be function')
|
|
87935
88676
|
}
|
|
@@ -88035,12 +88776,16 @@ function requireText () {
|
|
|
88035
88776
|
|
|
88036
88777
|
var defaultCharset = opts.defaultCharset || 'utf-8';
|
|
88037
88778
|
var inflate = opts.inflate !== false;
|
|
88038
|
-
var limit = typeof opts.limit
|
|
88039
|
-
?
|
|
88040
|
-
: opts.limit;
|
|
88779
|
+
var limit = typeof opts.limit === 'undefined' || opts.limit === null
|
|
88780
|
+
? 102400 // 100kb default
|
|
88781
|
+
: bytes.parse(opts.limit);
|
|
88041
88782
|
var type = opts.type || 'text/plain';
|
|
88042
88783
|
var verify = opts.verify || false;
|
|
88043
88784
|
|
|
88785
|
+
if (limit === null) {
|
|
88786
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid')
|
|
88787
|
+
}
|
|
88788
|
+
|
|
88044
88789
|
if (verify !== false && typeof verify !== 'function') {
|
|
88045
88790
|
throw new TypeError('option verify must be function')
|
|
88046
88791
|
}
|
|
@@ -91307,12 +92052,16 @@ function requireUrlencoded () {
|
|
|
91307
92052
|
|
|
91308
92053
|
var extended = opts.extended !== false;
|
|
91309
92054
|
var inflate = opts.inflate !== false;
|
|
91310
|
-
var limit = typeof opts.limit
|
|
91311
|
-
?
|
|
91312
|
-
: opts.limit;
|
|
92055
|
+
var limit = typeof opts.limit === 'undefined' || opts.limit === null
|
|
92056
|
+
? 102400 // 100kb default
|
|
92057
|
+
: bytes.parse(opts.limit);
|
|
91313
92058
|
var type = opts.type || 'application/x-www-form-urlencoded';
|
|
91314
92059
|
var verify = opts.verify || false;
|
|
91315
92060
|
|
|
92061
|
+
if (limit === null) {
|
|
92062
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid')
|
|
92063
|
+
}
|
|
92064
|
+
|
|
91316
92065
|
if (verify !== false && typeof verify !== 'function') {
|
|
91317
92066
|
throw new TypeError('option verify must be function')
|
|
91318
92067
|
}
|
|
@@ -112028,6 +112777,17 @@ const closePattern = /\\}/g;
|
|
|
112028
112777
|
const commaPattern = /\\,/g;
|
|
112029
112778
|
const periodPattern = /\\\./g;
|
|
112030
112779
|
const EXPANSION_MAX = 100_000;
|
|
112780
|
+
// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An
|
|
112781
|
+
// input like `'{a,b}'.repeat(1500)` stays under that count - its output is
|
|
112782
|
+
// truncated to 100k results - while making every result ~1500 characters
|
|
112783
|
+
// long. The result set, and the intermediate arrays built while combining
|
|
112784
|
+
// brace sets, then grow large enough to exhaust memory and crash the process
|
|
112785
|
+
// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of
|
|
112786
|
+
// characters the accumulator may hold at any point, so memory stays flat no
|
|
112787
|
+
// matter how many brace groups are chained. The limit sits well above any
|
|
112788
|
+
// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
|
|
112789
|
+
// characters) so legitimate input is unaffected.
|
|
112790
|
+
const EXPANSION_MAX_LENGTH = 4_000_000;
|
|
112031
112791
|
function numeric(str) {
|
|
112032
112792
|
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
|
112033
112793
|
}
|
|
@@ -112076,7 +112836,7 @@ function expand(str, options = {}) {
|
|
|
112076
112836
|
if (!str) {
|
|
112077
112837
|
return [];
|
|
112078
112838
|
}
|
|
112079
|
-
const { max = EXPANSION_MAX } = options;
|
|
112839
|
+
const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options;
|
|
112080
112840
|
// I don't know why Bash 4.3 does this, but it does.
|
|
112081
112841
|
// Anything starting with {} will have the first two bytes preserved
|
|
112082
112842
|
// but *only* at the top level, so {},a}b will not expand to anything,
|
|
@@ -112086,7 +112846,7 @@ function expand(str, options = {}) {
|
|
|
112086
112846
|
if (str.slice(0, 2) === '{}') {
|
|
112087
112847
|
str = '\\{\\}' + str.slice(2);
|
|
112088
112848
|
}
|
|
112089
|
-
return expand_(escapeBraces(str), max, true).map(unescapeBraces);
|
|
112849
|
+
return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
|
|
112090
112850
|
}
|
|
112091
112851
|
function embrace(str) {
|
|
112092
112852
|
return '{' + str + '}';
|
|
@@ -112100,22 +112860,117 @@ function lte(i, y) {
|
|
|
112100
112860
|
function gte(i, y) {
|
|
112101
112861
|
return i >= y;
|
|
112102
112862
|
}
|
|
112103
|
-
|
|
112104
|
-
|
|
112105
|
-
|
|
112106
|
-
|
|
112107
|
-
|
|
112108
|
-
|
|
112109
|
-
|
|
112110
|
-
|
|
112111
|
-
|
|
112112
|
-
|
|
112113
|
-
|
|
112114
|
-
|
|
112115
|
-
|
|
112863
|
+
// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
|
|
112864
|
+
// number of results at `max` and the total number of characters at `maxLength`.
|
|
112865
|
+
// This is the one place output grows, so bounding it here keeps the single
|
|
112866
|
+
// accumulator - and therefore memory - flat regardless of how many brace groups
|
|
112867
|
+
// are combined (CVE-2026-14257).
|
|
112868
|
+
function combine(acc, pre, values, max, maxLength, dropEmpties) {
|
|
112869
|
+
const out = [];
|
|
112870
|
+
let length = 0;
|
|
112871
|
+
for (let a = 0; a < acc.length; a++) {
|
|
112872
|
+
for (let v = 0; v < values.length; v++) {
|
|
112873
|
+
if (out.length >= max)
|
|
112874
|
+
return out;
|
|
112875
|
+
const expansion = acc[a] + pre + values[v];
|
|
112876
|
+
// Bash drops empty results at the top level. Skip them before they count
|
|
112877
|
+
// against `max`, so `max` bounds the number of *kept* results.
|
|
112878
|
+
if (dropEmpties && !expansion)
|
|
112879
|
+
continue;
|
|
112880
|
+
if (length + expansion.length > maxLength)
|
|
112881
|
+
return out;
|
|
112882
|
+
out.push(expansion);
|
|
112883
|
+
length += expansion.length;
|
|
112116
112884
|
}
|
|
112117
112885
|
}
|
|
112118
|
-
|
|
112886
|
+
return out;
|
|
112887
|
+
}
|
|
112888
|
+
// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
|
|
112889
|
+
// sequence body.
|
|
112890
|
+
function expandSequence(body, isAlphaSequence, max, maxLength) {
|
|
112891
|
+
const n = body.split(/\.\./);
|
|
112892
|
+
const N = [];
|
|
112893
|
+
// A sequence body always splits into two or three parts, but the compiler
|
|
112894
|
+
// can't know that.
|
|
112895
|
+
/* c8 ignore start */
|
|
112896
|
+
if (n[0] === undefined || n[1] === undefined) {
|
|
112897
|
+
return N;
|
|
112898
|
+
}
|
|
112899
|
+
/* c8 ignore stop */
|
|
112900
|
+
const x = numeric(n[0]);
|
|
112901
|
+
const y = numeric(n[1]);
|
|
112902
|
+
const width = Math.max(n[0].length, n[1].length);
|
|
112903
|
+
let incr = n.length === 3 && n[2] !== undefined ?
|
|
112904
|
+
Math.max(Math.abs(numeric(n[2])), 1)
|
|
112905
|
+
: 1;
|
|
112906
|
+
let test = lte;
|
|
112907
|
+
const reverse = y < x;
|
|
112908
|
+
if (reverse) {
|
|
112909
|
+
incr *= -1;
|
|
112910
|
+
test = gte;
|
|
112911
|
+
}
|
|
112912
|
+
const pad = n.some(isPadded);
|
|
112913
|
+
let length = 0;
|
|
112914
|
+
for (let i = x; test(i, y) && N.length < max; i += incr) {
|
|
112915
|
+
let c;
|
|
112916
|
+
if (isAlphaSequence) {
|
|
112917
|
+
c = String.fromCharCode(i);
|
|
112918
|
+
if (c === '\\') {
|
|
112919
|
+
c = '';
|
|
112920
|
+
}
|
|
112921
|
+
}
|
|
112922
|
+
else {
|
|
112923
|
+
c = String(i);
|
|
112924
|
+
if (pad) {
|
|
112925
|
+
const need = width - c.length;
|
|
112926
|
+
if (need > 0) {
|
|
112927
|
+
const z = new Array(need + 1).join('0');
|
|
112928
|
+
if (i < 0) {
|
|
112929
|
+
c = '-' + z + c.slice(1);
|
|
112930
|
+
}
|
|
112931
|
+
else {
|
|
112932
|
+
c = z + c;
|
|
112933
|
+
}
|
|
112934
|
+
}
|
|
112935
|
+
}
|
|
112936
|
+
}
|
|
112937
|
+
if (length + c.length > maxLength)
|
|
112938
|
+
break;
|
|
112939
|
+
N.push(c);
|
|
112940
|
+
length += c.length;
|
|
112941
|
+
}
|
|
112942
|
+
return N;
|
|
112943
|
+
}
|
|
112944
|
+
function expand_(str, max, maxLength, isTop) {
|
|
112945
|
+
// Consume the string's top-level brace groups left to right, threading a
|
|
112946
|
+
// running set of combined prefixes (`acc`). Expanding the tail iteratively -
|
|
112947
|
+
// rather than recursing on `m.post` once per group - keeps the native stack
|
|
112948
|
+
// depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no
|
|
112949
|
+
// longer overflow the stack, and leaves a single accumulator whose size
|
|
112950
|
+
// `maxLength` bounds directly (CVE-2026-14257).
|
|
112951
|
+
let acc = [''];
|
|
112952
|
+
// Bash drops empty results, but only when the *first* top-level group is a
|
|
112953
|
+
// comma set - a sequence like `{a..\}` may legitimately yield ''. The drop
|
|
112954
|
+
// is on the final strings, so it is applied to whichever `combine` produces
|
|
112955
|
+
// them (the one with no brace set left in the tail).
|
|
112956
|
+
let dropEmpties = false;
|
|
112957
|
+
let firstGroup = true;
|
|
112958
|
+
for (;;) {
|
|
112959
|
+
const m = balanced('{', '}', str);
|
|
112960
|
+
// No brace set left: the rest of the string is literal.
|
|
112961
|
+
if (!m) {
|
|
112962
|
+
return combine(acc, str, [''], max, maxLength, dropEmpties);
|
|
112963
|
+
}
|
|
112964
|
+
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|
112965
|
+
const pre = m.pre;
|
|
112966
|
+
if (/\$$/.test(pre)) {
|
|
112967
|
+
acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length);
|
|
112968
|
+
firstGroup = false;
|
|
112969
|
+
if (!m.post.length)
|
|
112970
|
+
break;
|
|
112971
|
+
str = m.post;
|
|
112972
|
+
continue;
|
|
112973
|
+
}
|
|
112119
112974
|
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
112120
112975
|
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
112121
112976
|
const isSequence = isNumericSequence || isAlphaSequence;
|
|
@@ -112124,87 +112979,69 @@ function expand_(str, max, isTop) {
|
|
|
112124
112979
|
// {a},b}
|
|
112125
112980
|
if (m.post.match(/,(?!,).*\}/)) {
|
|
112126
112981
|
str = m.pre + '{' + m.body + escClose + m.post;
|
|
112127
|
-
|
|
112982
|
+
isTop = true;
|
|
112983
|
+
continue;
|
|
112128
112984
|
}
|
|
112129
|
-
|
|
112985
|
+
// Nothing here expands, so the whole remaining string is literal.
|
|
112986
|
+
return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties);
|
|
112130
112987
|
}
|
|
112131
|
-
|
|
112988
|
+
if (firstGroup) {
|
|
112989
|
+
dropEmpties = isTop && !isSequence;
|
|
112990
|
+
firstGroup = false;
|
|
112991
|
+
}
|
|
112992
|
+
let values;
|
|
112132
112993
|
if (isSequence) {
|
|
112133
|
-
|
|
112994
|
+
values = expandSequence(m.body, isAlphaSequence, max, maxLength);
|
|
112134
112995
|
}
|
|
112135
112996
|
else {
|
|
112136
|
-
n = parseCommaParts(m.body);
|
|
112997
|
+
let n = parseCommaParts(m.body);
|
|
112137
112998
|
if (n.length === 1 && n[0] !== undefined) {
|
|
112138
112999
|
// x{{a,b}}y ==> x{a}y x{b}y
|
|
112139
|
-
n = expand_(n[0], max, false).map(embrace);
|
|
113000
|
+
n = expand_(n[0], max, maxLength, false).map(embrace);
|
|
112140
113001
|
//XXX is this necessary? Can't seem to hit it in tests.
|
|
112141
113002
|
/* c8 ignore start */
|
|
112142
113003
|
if (n.length === 1) {
|
|
112143
|
-
|
|
113004
|
+
acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length);
|
|
113005
|
+
if (!m.post.length)
|
|
113006
|
+
break;
|
|
113007
|
+
str = m.post;
|
|
113008
|
+
continue;
|
|
112144
113009
|
}
|
|
112145
113010
|
/* c8 ignore stop */
|
|
112146
113011
|
}
|
|
112147
|
-
|
|
112148
|
-
|
|
112149
|
-
|
|
112150
|
-
|
|
112151
|
-
|
|
112152
|
-
|
|
112153
|
-
|
|
112154
|
-
|
|
112155
|
-
|
|
112156
|
-
|
|
112157
|
-
|
|
112158
|
-
|
|
112159
|
-
|
|
112160
|
-
|
|
112161
|
-
|
|
112162
|
-
|
|
112163
|
-
|
|
112164
|
-
|
|
112165
|
-
|
|
112166
|
-
|
|
112167
|
-
|
|
112168
|
-
if (isAlphaSequence) {
|
|
112169
|
-
c = String.fromCharCode(i);
|
|
112170
|
-
if (c === '\\') {
|
|
112171
|
-
c = '';
|
|
112172
|
-
}
|
|
112173
|
-
}
|
|
112174
|
-
else {
|
|
112175
|
-
c = String(i);
|
|
112176
|
-
if (pad) {
|
|
112177
|
-
const need = width - c.length;
|
|
112178
|
-
if (need > 0) {
|
|
112179
|
-
const z = new Array(need + 1).join('0');
|
|
112180
|
-
if (i < 0) {
|
|
112181
|
-
c = '-' + z + c.slice(1);
|
|
112182
|
-
}
|
|
112183
|
-
else {
|
|
112184
|
-
c = z + c;
|
|
112185
|
-
}
|
|
112186
|
-
}
|
|
113012
|
+
// Values that `combine` is going to drop as empty produce no result, so
|
|
113013
|
+
// they must not count against `max` - otherwise `{a,,b}` with `max: 2`
|
|
113014
|
+
// would stop at `['a', '']` and yield one result instead of two. Skipping
|
|
113015
|
+
// them outright keeps `values` bounded while leaving `max` a bound on
|
|
113016
|
+
// *kept* results.
|
|
113017
|
+
let dropsEmpties = dropEmpties && !m.post.length && !pre;
|
|
113018
|
+
for (let d = 0; dropsEmpties && d < acc.length; d++) {
|
|
113019
|
+
if (acc[d]) {
|
|
113020
|
+
dropsEmpties = false;
|
|
113021
|
+
}
|
|
113022
|
+
}
|
|
113023
|
+
values = [];
|
|
113024
|
+
let valuesLength = 0;
|
|
113025
|
+
outer: for (let j = 0; j < n.length; j++) {
|
|
113026
|
+
const expanded = expand_(n[j], max, maxLength, false);
|
|
113027
|
+
for (let k = 0; k < expanded.length; k++) {
|
|
113028
|
+
const v = expanded[k];
|
|
113029
|
+
if (dropsEmpties && !v)
|
|
113030
|
+
continue;
|
|
113031
|
+
if (values.length >= max || valuesLength + v.length > maxLength) {
|
|
113032
|
+
break outer;
|
|
112187
113033
|
}
|
|
112188
|
-
|
|
112189
|
-
|
|
112190
|
-
}
|
|
112191
|
-
}
|
|
112192
|
-
else {
|
|
112193
|
-
N = [];
|
|
112194
|
-
for (let j = 0; j < n.length; j++) {
|
|
112195
|
-
N.push.apply(N, expand_(n[j], max, false));
|
|
112196
|
-
}
|
|
112197
|
-
}
|
|
112198
|
-
for (let j = 0; j < N.length; j++) {
|
|
112199
|
-
for (let k = 0; k < post.length && expansions.length < max; k++) {
|
|
112200
|
-
const expansion = pre + N[j] + post[k];
|
|
112201
|
-
if (!isTop || isSequence || expansion) {
|
|
112202
|
-
expansions.push(expansion);
|
|
113034
|
+
values.push(v);
|
|
113035
|
+
valuesLength += v.length;
|
|
112203
113036
|
}
|
|
112204
113037
|
}
|
|
112205
113038
|
}
|
|
113039
|
+
acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
|
|
113040
|
+
if (!m.post.length)
|
|
113041
|
+
break;
|
|
113042
|
+
str = m.post;
|
|
112206
113043
|
}
|
|
112207
|
-
return
|
|
113044
|
+
return acc;
|
|
112208
113045
|
}
|
|
112209
113046
|
|
|
112210
113047
|
const MAX_PATTERN_LENGTH = 1024 * 64;
|
|
@@ -170189,7 +171026,12 @@ function requireFastUri () {
|
|
|
170189
171026
|
*/
|
|
170190
171027
|
function resolve (baseURI, relativeURI, options) {
|
|
170191
171028
|
const schemelessOptions = options ? Object.assign({ scheme: 'null' }, options) : { scheme: 'null' };
|
|
170192
|
-
const
|
|
171029
|
+
const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
|
|
171030
|
+
const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
|
|
171031
|
+
if (baseMalformed || relativeMalformed) {
|
|
171032
|
+
throw new Error(baseParsed.error || relativeParsed.error || 'URI is malformed.')
|
|
171033
|
+
}
|
|
171034
|
+
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
170193
171035
|
schemelessOptions.skipEscape = true;
|
|
170194
171036
|
return serialize(resolved, schemelessOptions)
|
|
170195
171037
|
}
|
|
@@ -170365,6 +171207,19 @@ function requireFastUri () {
|
|
|
170365
171207
|
|
|
170366
171208
|
const URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
170367
171209
|
|
|
171210
|
+
// Captures the authority component (between "//" and the next "/", "?" or "#"),
|
|
171211
|
+
// with or without a scheme prefix, for the literal-backslash rejection below.
|
|
171212
|
+
const AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
|
|
171213
|
+
|
|
171214
|
+
// Captures the leading authority-introducer region after an optional scheme: a
|
|
171215
|
+
// run of forward slashes, backslashes, and the characters the WHATWG URL parser
|
|
171216
|
+
// removes before parsing (TAB U+0009, LF U+000A, CR U+000D). A valid introducer
|
|
171217
|
+
// is exactly "//". Node treats "\" as "/" on special schemes and strips those
|
|
171218
|
+
// characters first, so forms like "\\", "/\", "\/", "/<TAB>/", or a leading
|
|
171219
|
+
// "<TAB>//" reach an authority in Node while fast-uri's URI_PARSE folds them into
|
|
171220
|
+
// the path group (host confusion / SSRF / redirect bypass).
|
|
171221
|
+
const AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
|
|
171222
|
+
|
|
170368
171223
|
/**
|
|
170369
171224
|
* @param {import('./types/index').URIComponent} parsed
|
|
170370
171225
|
* @param {RegExpMatchArray} matches
|
|
@@ -170411,6 +171266,41 @@ function requireFastUri () {
|
|
|
170411
171266
|
}
|
|
170412
171267
|
}
|
|
170413
171268
|
|
|
171269
|
+
// A literal backslash (U+005C) is not a valid RFC 3986 URI character and is
|
|
171270
|
+
// not an authority delimiter. Reject it in the authority rather than
|
|
171271
|
+
// rewriting it: normalizing "\" -> "/" (WHATWG error recovery) could silently
|
|
171272
|
+
// change the resource identified by an otherwise-invalid input, and lets "\"
|
|
171273
|
+
// act as a host delimiter here while Node's native URL parses a different
|
|
171274
|
+
// host (SSRF / redirect / origin-allowlist bypass). Percent-encoded %5C is
|
|
171275
|
+
// untouched and remains valid encoded data.
|
|
171276
|
+
const authorityMatch = uri.match(AUTHORITY_PREFIX);
|
|
171277
|
+
if (authorityMatch !== null && authorityMatch[1].indexOf('\\') !== -1) {
|
|
171278
|
+
parsed.error = 'URI authority must not contain a literal backslash.';
|
|
171279
|
+
malformedAuthorityOrPort = true;
|
|
171280
|
+
}
|
|
171281
|
+
|
|
171282
|
+
// Reject a malformed or whitespace-smuggled authority introducer. fast-uri
|
|
171283
|
+
// only recognizes a literal "//"; anything else in the leading separator run
|
|
171284
|
+
// (a backslash, or a "//" that appears only after removing the TAB/LF/CR that
|
|
171285
|
+
// Node strips) means the authority fast-uri parses differs from the one Node's
|
|
171286
|
+
// URL resolves. Reject rather than rewrite, mirroring the literal-backslash
|
|
171287
|
+
// guard above. Percent-encoded forms (%5C, %09) are untouched, valid data.
|
|
171288
|
+
const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION);
|
|
171289
|
+
if (introducerMatch !== null) {
|
|
171290
|
+
const region = introducerMatch[1];
|
|
171291
|
+
const normalizedRegion = region.replace(/[\t\n\r]/g, '');
|
|
171292
|
+
// Two or more leading separators introduce an authority.
|
|
171293
|
+
if (normalizedRegion.length >= 2) {
|
|
171294
|
+
if (normalizedRegion.slice(0, 2) !== '//') {
|
|
171295
|
+
parsed.error = parsed.error || 'URI authority must not contain a literal backslash.';
|
|
171296
|
+
malformedAuthorityOrPort = true;
|
|
171297
|
+
} else if (region.length !== normalizedRegion.length) {
|
|
171298
|
+
parsed.error = parsed.error || 'URI authority introducer must not contain whitespace.';
|
|
171299
|
+
malformedAuthorityOrPort = true;
|
|
171300
|
+
}
|
|
171301
|
+
}
|
|
171302
|
+
}
|
|
171303
|
+
|
|
170414
171304
|
const matches = uri.match(URI_PARSE);
|
|
170415
171305
|
|
|
170416
171306
|
if (matches) {
|
|
@@ -170468,7 +171358,7 @@ function requireFastUri () {
|
|
|
170468
171358
|
if (parsed.host && (options.domainHost || (schemeHandler && schemeHandler.domainHost)) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
170469
171359
|
// convert Unicode IDN -> ASCII IDN
|
|
170470
171360
|
try {
|
|
170471
|
-
parsed.host = URL
|
|
171361
|
+
parsed.host = new URL('http://' + parsed.host).hostname;
|
|
170472
171362
|
} catch (e) {
|
|
170473
171363
|
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
170474
171364
|
}
|