"Fossies" - the Fresh Open Source Software Archive 
Member "Atom/resources/app/apm/node_modules/npm/lib/cache/add-remote-tarball.js" (16 Apr 2018, 4467 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 var mkdir = require('mkdirp')
2 var assert = require('assert')
3 var log = require('npmlog')
4 var path = require('path')
5 var sha = require('sha')
6 var retry = require('retry')
7 var writeStreamAtomic = require('fs-write-stream-atomic')
8 var PassThrough = require('readable-stream').PassThrough
9 var npm = require('../npm.js')
10 var inflight = require('inflight')
11 var addLocalTarball = require('./add-local-tarball.js')
12 var cacheFile = require('npm-cache-filename')
13 var rimraf = require('rimraf')
14 var pulseTillDone = require('../utils/pulse-till-done.js')
15
16 module.exports = addRemoteTarball
17
18 function addRemoteTarball (u, pkgData, shasum, auth, cb_) {
19 assert(typeof u === 'string', 'must have module URL')
20 assert(typeof cb_ === 'function', 'must have callback')
21
22 function cb (er, data) {
23 if (data) {
24 data._from = u
25 data._resolved = u
26 data._shasum = data._shasum || shasum
27 }
28 cb_(er, data)
29 }
30
31 cb_ = inflight(u, cb_)
32 if (!cb_) return log.verbose('addRemoteTarball', u, 'already in flight; waiting')
33 log.verbose('addRemoteTarball', u, 'not in flight; adding')
34
35 // XXX Fetch direct to cache location, store tarballs under
36 // ${cache}/registry.npmjs.org/pkg/-/pkg-1.2.3.tgz
37 var tmp = cacheFile(npm.tmp, u)
38
39 function next (er, resp, shasum) {
40 if (er) return cb(er)
41 addLocalTarball(tmp, pkgData, shasum, cleanup)
42 }
43 function cleanup (er, data) {
44 if (er) return cb(er)
45 rimraf(tmp, function () {
46 cb(er, data)
47 })
48 }
49
50 log.verbose('addRemoteTarball', [u, shasum])
51 mkdir(path.dirname(tmp), function (er) {
52 if (er) return cb(er)
53 addRemoteTarball_(u, tmp, shasum, auth, next)
54 })
55 }
56
57 function addRemoteTarball_ (u, tmp, shasum, auth, cb) {
58 // Tuned to spread 3 attempts over about a minute.
59 // See formula at <https://github.com/tim-kos/node-retry>.
60 var operation = retry.operation({
61 retries: npm.config.get('fetch-retries'),
62 factor: npm.config.get('fetch-retry-factor'),
63 minTimeout: npm.config.get('fetch-retry-mintimeout'),
64 maxTimeout: npm.config.get('fetch-retry-maxtimeout')
65 })
66
67 operation.attempt(function (currentAttempt) {
68 log.info(
69 'retry',
70 'fetch attempt', currentAttempt,
71 'at', (new Date()).toLocaleTimeString()
72 )
73 fetchAndShaCheck(u, tmp, shasum, auth, function (er, response, shasum) {
74 // Only retry on 408, 5xx or no `response`.
75 var sc = response && response.statusCode
76 var statusRetry = !sc || (sc === 408 || sc >= 500)
77 if (er && statusRetry && operation.retry(er)) {
78 log.warn('retry', 'will retry, error on last attempt: ' + er)
79 return
80 }
81 cb(er, response, shasum)
82 })
83 })
84 }
85
86 function fetchAndShaCheck (u, tmp, shasum, auth, cb) {
87 cb = pulseTillDone('fetchTarball', cb)
88 npm.registry.fetch(u, { auth: auth }, function (er, response) {
89 if (er) {
90 log.error('fetch failed', u)
91 return cb(er, response)
92 }
93
94 var tarball = writeStreamAtomic(tmp, { mode: npm.modes.file })
95 tarball.on('error', function (er) {
96 cb(er)
97 tarball.destroy()
98 })
99
100 tarball.on('finish', function () {
101 if (!shasum) {
102 // Well, we weren't given a shasum, so at least sha what we have
103 // in case we want to compare it to something else later
104 return sha.get(tmp, function (er, shasum) {
105 log.silly('fetchAndShaCheck', 'shasum', shasum)
106 cb(er, response, shasum)
107 })
108 }
109
110 // validate that the url we just downloaded matches the expected shasum.
111 log.silly('fetchAndShaCheck', 'shasum', shasum)
112 sha.check(tmp, shasum, function (er) {
113 if (er && er.message) {
114 // add original filename for better debuggability
115 er.message = er.message + '\n' + 'From: ' + u
116 }
117 return cb(er, response, shasum)
118 })
119 })
120
121 // 0.8 http streams have a bug, where if they're paused with data in
122 // their buffers when the socket closes, they call `end` before emptying
123 // those buffers, which results in the entire pipeline ending and thus
124 // the point that applied backpressure never being able to trigger a
125 // `resume`.
126 // We work around this by piping into a pass through stream that has
127 // unlimited buffering. The pass through stream is from readable-stream
128 // and is thus a current streams3 implementation that is free of these
129 // bugs even on 0.8.
130 response.pipe(PassThrough({highWaterMark: Infinity})).pipe(tarball)
131 })
132 }