"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/npm/lib/cache/caching-client.js" (11 Apr 2017, 6681 Bytes) of package /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 module.exports = CachingRegistryClient
    2 
    3 var path = require('path')
    4 var fs = require('graceful-fs')
    5 var url = require('url')
    6 var assert = require('assert')
    7 var inherits = require('util').inherits
    8 
    9 var RegistryClient = require('npm-registry-client')
   10 var npm = require('../npm.js')
   11 var log = require('npmlog')
   12 var getCacheStat = require('./get-stat.js')
   13 var cacheFile = require('npm-cache-filename')
   14 var mkdirp = require('mkdirp')
   15 var rimraf = require('rimraf')
   16 var chownr = require('chownr')
   17 var writeFile = require('write-file-atomic')
   18 var parseJSON = require('../utils/parse-json')
   19 
   20 function CachingRegistryClient (config) {
   21   RegistryClient.call(this, adaptConfig(config))
   22 
   23   this._mapToCache = cacheFile(config.get('cache'))
   24 
   25   // swizzle in our custom cache invalidation logic
   26   this._request = this.request
   27   this.request = this._invalidatingRequest
   28   this.get = get
   29 }
   30 inherits(CachingRegistryClient, RegistryClient)
   31 
   32 CachingRegistryClient.prototype._invalidatingRequest = function (uri, params, cb) {
   33   var client = this
   34   this._request(uri, params, function () {
   35     var args = arguments
   36 
   37     var method = params.method
   38     if (method !== 'HEAD' && method !== 'GET') {
   39       var invalidated = client._mapToCache(uri)
   40       // invalidate cache
   41       //
   42       // This is irrelevant for commands that do etag / last-modified caching,
   43       // but ls and view also have a timed cache, so this keeps the user from
   44       // thinking that it didn't work when it did.
   45       // Note that failure is an acceptable option here, since the only
   46       // result will be a stale cache for some helper commands.
   47       log.verbose('request', 'invalidating', invalidated, 'on', method)
   48       return rimraf(invalidated, function () {
   49         cb.apply(undefined, args)
   50       })
   51     }
   52 
   53     cb.apply(undefined, args)
   54   })
   55 }
   56 
   57 function get (uri, params, cb) {
   58   assert(typeof uri === 'string', 'must pass registry URI to get')
   59   assert(params && typeof params === 'object', 'must pass params to get')
   60   assert(typeof cb === 'function', 'must pass callback to get')
   61 
   62   var parsed = url.parse(uri)
   63   assert(
   64     parsed.protocol === 'http:' || parsed.protocol === 'https:',
   65     'must have a URL that starts with http: or https:'
   66   )
   67 
   68   var cacheBase = cacheFile(npm.config.get('cache'))(uri)
   69   var cachePath = path.join(cacheBase, '.cache.json')
   70 
   71   // If the GET is part of a write operation (PUT or DELETE), then
   72   // skip past the cache entirely, but still save the results.
   73   if (uri.match(/\?write=true$/)) {
   74     log.verbose('get', 'GET as part of write; not caching result')
   75     return get_.call(this, uri, cachePath, params, cb)
   76   }
   77 
   78   if (params.skipCache) {
   79     return get_.call(this, uri, cachePath, params, cb)
   80   }
   81 
   82   var client = this
   83   fs.stat(cachePath, function (er, stat) {
   84     if (!er) {
   85       fs.readFile(cachePath, function (er, data) {
   86         data = parseJSON.noExceptions(data)
   87 
   88         params.stat = stat
   89         params.data = data
   90 
   91         get_.call(client, uri, cachePath, params, cb)
   92       })
   93     } else {
   94       get_.call(client, uri, cachePath, params, cb)
   95     }
   96   })
   97 }
   98 
   99 function get_ (uri, cachePath, params, cb) {
  100   var staleOk = params.staleOk === undefined ? false : params.staleOk
  101   var timeout = params.timeout === undefined ? -1 : params.timeout
  102   var data = params.data
  103   var stat = params.stat
  104   var etag
  105   var lastModified
  106 
  107   timeout = Math.min(timeout, npm.config.get('cache-max') || 0)
  108   timeout = Math.max(timeout, npm.config.get('cache-min') || -Infinity)
  109   if (process.env.COMP_CWORD !== undefined &&
  110       process.env.COMP_LINE !== undefined &&
  111       process.env.COMP_POINT !== undefined) {
  112     timeout = Math.max(timeout, 60000)
  113   }
  114 
  115   if (data) {
  116     if (data._etag) etag = data._etag
  117     if (data._lastModified) lastModified = data._lastModified
  118 
  119     data._cached = true
  120 
  121     if (stat && timeout && timeout > 0) {
  122       if ((Date.now() - stat.mtime.getTime()) / 1000 < timeout) {
  123         log.verbose('get', uri, 'not expired, no request')
  124         delete data._etag
  125         delete data._lastModified
  126         return cb(null, data, JSON.stringify(data), { statusCode: 304 })
  127       }
  128 
  129       if (staleOk) {
  130         log.verbose('get', uri, 'staleOk, background update')
  131         delete data._etag
  132         delete data._lastModified
  133         process.nextTick(
  134           cb.bind(null, null, data, JSON.stringify(data), { statusCode: 304 })
  135         )
  136         cb = function () {}
  137       }
  138     }
  139   }
  140 
  141   var options = {
  142     etag: etag,
  143     lastModified: lastModified,
  144     follow: params.follow,
  145     auth: params.auth
  146   }
  147   this.request(uri, options, function (er, remoteData, raw, response) {
  148     // if we get an error talking to the registry, but we have it
  149     // from the cache, then just pretend we got it.
  150     if (er && cachePath && data && !data.error) {
  151       er = null
  152       response = { statusCode: 304 }
  153     }
  154 
  155     if (response) {
  156       log.silly('get', 'cb', [response.statusCode, response.headers])
  157       if (response.statusCode === 304 && (etag || lastModified)) {
  158         remoteData = data
  159         log.verbose(etag ? 'etag' : 'lastModified', uri + ' from cache')
  160       }
  161     }
  162 
  163     data = remoteData
  164     if (!data) er = er || new Error('failed to fetch from registry: ' + uri)
  165 
  166     if (er) return cb(er, data, raw, response)
  167 
  168     saveToCache(cachePath, data, saved)
  169 
  170     // just give the write the old college try.  if it fails, whatever.
  171     function saved () {
  172       delete data._etag
  173       delete data._lastModified
  174       cb(er, data, raw, response)
  175     }
  176 
  177     function saveToCache (cachePath, data, saved) {
  178       log.verbose('get', 'saving', data.name, 'to', cachePath)
  179       getCacheStat(function (er, st) {
  180         mkdirp(path.dirname(cachePath), function (er, made) {
  181           if (er) return saved()
  182 
  183           writeFile(cachePath, JSON.stringify(data), function (er) {
  184             if (er) return saved()
  185 
  186             chownr(made || cachePath, st.uid, st.gid, saved)
  187           })
  188         })
  189       })
  190     }
  191   })
  192 }
  193 
  194 function adaptConfig (config) {
  195   return {
  196     proxy: {
  197       http: config.get('proxy'),
  198       https: config.get('https-proxy'),
  199       localAddress: config.get('local-address')
  200     },
  201     ssl: {
  202       certificate: config.get('cert'),
  203       key: config.get('key'),
  204       ca: config.get('ca'),
  205       strict: config.get('strict-ssl')
  206     },
  207     retry: {
  208       retries: config.get('fetch-retries'),
  209       factor: config.get('fetch-retry-factor'),
  210       minTimeout: config.get('fetch-retry-mintimeout'),
  211       maxTimeout: config.get('fetch-retry-maxtimeout')
  212     },
  213     userAgent: config.get('user-agent'),
  214     log: log,
  215     defaultTag: config.get('tag'),
  216     couchToken: config.get('_token'),
  217     maxSockets: config.get('maxsockets')
  218   }
  219 }