* @see https://www.rfc-editor.org/rfc/rfc9111.html#name-storing-responses-to-authen * * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType * @param {string} method * @param {number} statusCode * @param {import('../../types/header.d.ts').IncomingHttpHead
(cacheType, method, statusCode, resHeaders, cacheControlDirectives, reqHeaders)
| 508 | * @param {import('../../types/header.d.ts').IncomingHttpHeaders} [reqHeaders] |
| 509 | */ |
| 510 | function canCacheResponse (cacheType, method, statusCode, resHeaders, cacheControlDirectives, reqHeaders) { |
| 511 | if (!arrayIncludes(util.safeHTTPMethods, method)) { |
| 512 | return false |
| 513 | } |
| 514 | // Status code must be final and understood. |
| 515 | if (statusCode < 200 || arrayIncludes(NOT_UNDERSTOOD_STATUS_CODES, statusCode)) { |
| 516 | return false |
| 517 | } |
| 518 | // Responses with neither status codes that are heuristically cacheable, nor "explicit enough" caching |
| 519 | // directives, are not cacheable. "Explicit enough": see https://www.rfc-editor.org/rfc/rfc9111.html#section-3 |
| 520 | if (!arrayIncludes(HEURISTICALLY_CACHEABLE_STATUS_CODES, statusCode) && !resHeaders['expires'] && |
| 521 | !cacheControlDirectives.public && |
| 522 | cacheControlDirectives['max-age'] === undefined && |
| 523 | // RFC 9111: a private response directive, if the cache is not shared |
| 524 | !(cacheControlDirectives.private && cacheType === 'private') && |
| 525 | !(cacheControlDirectives['s-maxage'] !== undefined && cacheType === 'shared') |
| 526 | ) { |
| 527 | return false |
| 528 | } |
| 529 | |
| 530 | if (cacheControlDirectives['no-store']) { |
| 531 | return false |
| 532 | } |
| 533 | |
| 534 | if (cacheType === 'shared' && ( |
| 535 | cacheControlDirectives.private === true || |
| 536 | Object.hasOwn(resHeaders, 'set-cookie') |
| 537 | )) { |
| 538 | return false |
| 539 | } |
| 540 | |
| 541 | // https://www.rfc-editor.org/rfc/rfc9111.html#section-4.1-5 |
| 542 | if (resHeaders.vary && hasVaryStar(resHeaders.vary)) { |
| 543 | return false |
| 544 | } |
| 545 | |
| 546 | // https://www.rfc-editor.org/rfc/rfc9111.html#name-storing-responses-to-authen |
| 547 | if (reqHeaders != null && Object.hasOwn(reqHeaders, 'authorization')) { |
| 548 | if ( |
| 549 | !cacheControlDirectives.public && |
| 550 | !cacheControlDirectives['s-maxage'] && |
| 551 | !cacheControlDirectives['must-revalidate'] |
| 552 | ) { |
| 553 | return false |
| 554 | } |
| 555 | |
| 556 | if (typeof reqHeaders.authorization !== 'string') { |
| 557 | return false |
| 558 | } |
| 559 | |
| 560 | if ( |
| 561 | Array.isArray(cacheControlDirectives['no-cache']) && |
| 562 | arrayIncludes(cacheControlDirectives['no-cache'], 'authorization') |
| 563 | ) { |
| 564 | return false |
| 565 | } |
| 566 | |
| 567 | if ( |
no test coverage detected