MCPcopy
hub / github.com/angular/angular / cacheBustedFetchFromNetwork

Function cacheBustedFetchFromNetwork

packages/service-worker/worker/src/assets.ts:389–467  ·  view source on GitHub ↗

* Load a particular asset from the network, accounting for hash validation.

(req: Request)

Source from the content-addressed store, hash-verified

387 * Load a particular asset from the network, accounting for hash validation.
388 */
389 protected async cacheBustedFetchFromNetwork(req: Request): Promise<Response> {
390 const url = this.adapter.normalizeUrl(req.url);
391
392 // If a hash is available for this resource, then compare the fetched version with the
393 // canonical hash. Otherwise, the network version will have to be trusted.
394 if (this.hashes.has(url)) {
395 // It turns out this resource does have a hash. Look it up. Unless the fetched version
396 // matches this hash, it's invalid and the whole manifest may need to be thrown out.
397 const canonicalHash = this.hashes.get(url)!;
398
399 // Ideally, the resource would be requested with cache-busting to guarantee the SW gets
400 // the freshest version. However, doing this would eliminate any chance of the response
401 // being in the HTTP cache. Given that the browser has recently actively loaded the page,
402 // it's likely that many of the responses the SW needs to cache are in the HTTP cache and
403 // are fresh enough to use. In the future, this could be done by setting cacheMode to
404 // *only* check the browser cache for a cached version of the resource, when cacheMode is
405 // fully supported. For now, the resource is fetched directly, without cache-busting, and
406 // if the hash test fails a cache-busted request is tried before concluding that the
407 // resource isn't correct. This gives the benefit of acceleration via the HTTP cache
408 // without the risk of stale data, at the expense of a duplicate request in the event of
409 // a stale response.
410
411 // Fetch the resource from the network (possibly hitting the HTTP cache).
412 let response = await this.safeFetch(req);
413
414 // Decide whether a cache-busted request is necessary. A cache-busted request is necessary
415 // only if the request was successful but the hash of the retrieved contents does not match
416 // the canonical hash from the manifest.
417 let makeCacheBustedRequest = response.ok;
418 if (makeCacheBustedRequest) {
419 // The request was successful. A cache-busted request is only necessary if the hashes
420 // don't match.
421 // (Make sure to clone the response so it can be used later if it proves to be valid.)
422 const fetchedHash = sha1Binary(await response.clone().arrayBuffer());
423 makeCacheBustedRequest = fetchedHash !== canonicalHash;
424 }
425
426 // Make a cache busted request to the network, if necessary.
427 if (makeCacheBustedRequest) {
428 // Hash failure, the version that was retrieved under the default URL did not have the
429 // hash expected. This could be because the HTTP cache got in the way and returned stale
430 // data, or because the version on the server really doesn't match. A cache-busting
431 // request will differentiate these two situations.
432 // TODO: handle case where the URL has parameters already (unlikely for assets).
433 const cacheBustReq = this.newRequestWithMetadata(this.cacheBust(req.url), req);
434 response = await this.safeFetch(cacheBustReq);
435
436 // If the response was successful, check the contents against the canonical hash.
437 if (response.ok) {
438 // Hash the contents.
439 // (Make sure to clone the response so it can be used later if it proves to be valid.)
440 const cacheBustedHash = sha1Binary(await response.clone().arrayBuffer());
441
442 // If the cache-busted version doesn't match, then the manifest is not an accurate
443 // representation of the server's current set of files, and the SW should give up.
444 if (canonicalHash !== cacheBustedHash) {
445 throw new SwCriticalError(
446 `Hash mismatch (cacheBustedFetchFromNetwork): ${req.url}: expected ${canonicalHash}, got ${cacheBustedHash} (after cache busting)`,

Callers

nothing calls this directly

Calls 7

sha1BinaryFunction · 0.90
normalizeUrlMethod · 0.80
arrayBufferMethod · 0.80
hasMethod · 0.65
getMethod · 0.65
cloneMethod · 0.65
safeFetchMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…