File Explorer

/var/lang/lib/node_modules/npm/node_modules/make-fetch-happen/lib/cache

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

policy.js4.4 KB · 162 lines
const CacheSemantics = require('http-cache-semantics')const Negotiator = require('negotiator')const ssri = require('ssri') // options passed to http-cache-semantics constructorconst policyOptions = {  shared: false,  ignoreCargoCult: true,} // a fake empty response, used when only testing the// request for storabilityconst emptyResponse = { status: 200, headers: {} } // returns a plain object representation of the Requestconst requestObject = (request) => {  const _obj = {    method: request.method,    url: request.url,    headers: {},    compress: request.compress,  }   request.headers.forEach((value, key) => {    _obj.headers[key] = value  })   return _obj} // returns a plain object representation of the Responseconst responseObject = (response) => {  const _obj = {    status: response.status,    headers: {},  }   response.headers.forEach((value, key) => {    _obj.headers[key] = value  })   return _obj} class CachePolicy {  constructor ({ entry, request, response, options }) {    this.entry = entry    this.request = requestObject(request)    this.response = responseObject(response)    this.options = options    this.policy = new CacheSemantics(this.request, this.response, policyOptions)     if (this.entry) {      // if we have an entry, copy the timestamp to the _responseTime      // this is necessary because the CacheSemantics constructor forces      // the value to Date.now() which means a policy created from a      // cache entry is likely to always identify itself as stale      this.policy._responseTime = this.entry.metadata.time    }  }   // static method to quickly determine if a request alone is storable  static storable (request, options) {    // no cachePath means no caching    if (!options.cachePath) {      return false    }     // user explicitly asked not to cache    if (options.cache === 'no-store') {      return false    }     // we only cache GET and HEAD requests    if (!['GET', 'HEAD'].includes(request.method)) {      return false    }     // otherwise, let http-cache-semantics make the decision    // based on the request's headers    const policy = new CacheSemantics(requestObject(request), emptyResponse, policyOptions)    return policy.storable()  }   // returns true if the policy satisfies the request  satisfies (request) {    const _req = requestObject(request)    if (this.request.headers.host !== _req.headers.host) {      return false    }     if (this.request.compress !== _req.compress) {      return false    }     const negotiatorA = new Negotiator(this.request)    const negotiatorB = new Negotiator(_req)     if (JSON.stringify(negotiatorA.mediaTypes()) !== JSON.stringify(negotiatorB.mediaTypes())) {      return false    }     if (JSON.stringify(negotiatorA.languages()) !== JSON.stringify(negotiatorB.languages())) {      return false    }     if (JSON.stringify(negotiatorA.encodings()) !== JSON.stringify(negotiatorB.encodings())) {      return false    }     if (this.options.integrity) {      return ssri.parse(this.options.integrity).match(this.entry.integrity)    }     return true  }   // returns true if the request and response allow caching  storable () {    return this.policy.storable()  }   // NOTE: this is a hack to avoid parsing the cache-control  // header ourselves, it returns true if the response's  // cache-control contains must-revalidate  get mustRevalidate () {    return !!this.policy._rescc['must-revalidate']  }   // returns true if the cached response requires revalidation  // for the given request  needsRevalidation (request) {    const _req = requestObject(request)    // force method to GET because we only cache GETs    // but can serve a HEAD from a cached GET    _req.method = 'GET'    return !this.policy.satisfiesWithoutRevalidation(_req)  }   responseHeaders () {    return this.policy.responseHeaders()  }   // returns a new object containing the appropriate headers  // to send a revalidation request  revalidationHeaders (request) {    const _req = requestObject(request)    return this.policy.revalidationHeaders(_req)  }   // returns true if the request/response was revalidated  // successfully. returns false if a new response was received  revalidated (request, response) {    const _req = requestObject(request)    const _res = responseObject(response)    const policy = this.policy.revalidatedPolicy(_req, _res)    return !policy.modified  }} module.exports = CachePolicy