MCPcopy Create free account
hub / github.com/nodejs/node / handleResult

Function handleResult

deps/undici/src/lib/interceptor/cache.js:263–396  ·  view source on GitHub ↗

* @param {DispatchFn} dispatch * @param {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions} globalOpts * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey * @param {import('../../types/dispatcher.d.ts').default.DispatchHandler} handler * @para

(
  dispatch,
  globalOpts,
  cacheKey,
  handler,
  opts,
  reqCacheControl,
  result
)

Source from the content-addressed store, hash-verified

261 * @param {import('../../types/cache-interceptor.d.ts').default.GetResult | undefined} result
262 */
263function handleResult (
264 dispatch,
265 globalOpts,
266 cacheKey,
267 handler,
268 opts,
269 reqCacheControl,
270 result
271) {
272 if (!result) {
273 return handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl)
274 }
275
276 const now = Date.now()
277 if (now > result.deleteAt) {
278 // Response is expired, cache store shouldn't have given this to us
279 return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler))
280 }
281
282 const age = Math.round((now - result.cachedAt) / 1000)
283 if (reqCacheControl?.['max-age'] && age >= reqCacheControl['max-age']) {
284 // Response is considered expired for this specific request
285 // https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.1.1
286 return dispatch(opts, handler)
287 }
288
289 const stale = isStale(result, reqCacheControl)
290 const revalidate = needsRevalidation(result, reqCacheControl, opts)
291
292 // Check if the response is stale
293 if (stale || revalidate) {
294 if (util.isStream(opts.body) && util.bodyLength(opts.body) !== 0) {
295 // If body is a stream we can't revalidate...
296 // TODO (fix): This could be less strict...
297 return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler))
298 }
299
300 // RFC 5861: If we're within stale-while-revalidate window, serve stale immediately
301 // and revalidate in background, unless immediate revalidation is necessary
302 if (!revalidate && withinStaleWhileRevalidateWindow(result)) {
303 // Serve stale response immediately
304 sendCachedValue(handler, opts, result, age, null, true)
305
306 // Start background revalidation (fire-and-forget)
307 queueMicrotask(() => {
308 const headers = {
309 ...opts.headers,
310 'if-modified-since': new Date(result.cachedAt).toUTCString()
311 }
312
313 if (result.etag) {
314 headers['if-none-match'] = result.etag
315 }
316
317 if (result.vary) {
318 for (const key in result.vary) {
319 if (result.vary[key] != null) {
320 headers[key] = result.vary[key]

Callers 1

cache.jsFile · 0.85

Calls 10

handleUncachedResponseFunction · 0.85
isStaleFunction · 0.85
needsRevalidationFunction · 0.85
sendCachedValueFunction · 0.85
queueMicrotaskFunction · 0.85
nowMethod · 0.80
dispatchFunction · 0.50
destroyMethod · 0.45
onMethod · 0.45

Tested by

no test coverage detected