MCPcopy
hub / github.com/angular/angular / needToRevalidate

Function needToRevalidate

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

* Some resources are cached without a hash, meaning that their expiration is controlled * by HTTP caching headers. Check whether the given request/response pair is still valid * per the caching headers.

(req: Request, res: Response)

Source from the content-addressed store, hash-verified

181 * per the caching headers.
182 */
183 private async needToRevalidate(req: Request, res: Response): Promise<boolean> {
184 // Three different strategies apply here:
185 // 1) The request has a Cache-Control header, and thus expiration needs to be based on its age.
186 // 2) The request has an Expires header, and expiration is based on the current timestamp.
187 // 3) The request has no applicable caching headers, and must be revalidated.
188 if (res.headers.has('Cache-Control')) {
189 // Figure out if there is a max-age directive in the Cache-Control header.
190 const cacheControl = res.headers.get('Cache-Control')!;
191 const cacheDirectives = cacheControl
192 // Directives are comma-separated within the Cache-Control header value.
193 .split(',')
194 // Make sure each directive doesn't have extraneous whitespace.
195 .map((v) => v.trim())
196 // Some directives have values (like maxage and s-maxage)
197 .map((v) => v.split('='));
198
199 // Lowercase all the directive names.
200 cacheDirectives.forEach((v) => (v[0] = v[0].toLowerCase()));
201
202 // Find the max-age directive, if one exists.
203 const maxAgeDirective = cacheDirectives.find((v) => v[0] === 'max-age');
204 const cacheAge = maxAgeDirective ? maxAgeDirective[1] : undefined;
205
206 if (!cacheAge) {
207 // No usable TTL defined. Must assume that the response is stale.
208 return true;
209 }
210 try {
211 const maxAge = 1000 * parseInt(cacheAge);
212
213 // Determine the origin time of this request. If the SW has metadata on the request (which
214 // it
215 // should), it will have the time the request was added to the cache. If it doesn't for some
216 // reason, the request may have a Date header which will serve the same purpose.
217 let ts: number;
218 try {
219 // Check the metadata table. If a timestamp is there, use it.
220 const metaTable = await this.metadata;
221 ts = (await metaTable.read<UrlMetadata>(req.url)).ts;
222 } catch {
223 // Otherwise, look for a Date header.
224 const date = res.headers.get('Date');
225 if (date === null) {
226 // Unable to determine when this response was created. Assume that it's stale, and
227 // revalidate it.
228 return true;
229 }
230 ts = Date.parse(date);
231 }
232 const age = this.adapter.time - ts;
233 return age < 0 || age > maxAge;
234 } catch {
235 // Assume stale.
236 return true;
237 }
238 } else if (res.headers.has('Expires')) {
239 // Determine if the expiration time has passed.
240 const expiresStr = res.headers.get('Expires')!;

Callers

nothing calls this directly

Calls 6

mapMethod · 0.80
hasMethod · 0.65
getMethod · 0.65
parseMethod · 0.65
forEachMethod · 0.45
findMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…