mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.1 KiB
108 lines
3.1 KiB
'use strict'
|
|
|
|
const BB = require('bluebird')
|
|
const Buffer = require('safe-buffer').Buffer
|
|
|
|
const checkWarnings = require('./check-warning-header')
|
|
const fetch = require('make-fetch-happen')
|
|
const registryKey = require('./registry-key')
|
|
const url = require('url')
|
|
|
|
module.exports = regFetch
|
|
function regFetch (uri, registry, opts) {
|
|
const startTime = Date.now()
|
|
return fetch(uri, {
|
|
agent: opts.agent,
|
|
algorithms: opts.algorithms,
|
|
cache: getCacheMode(opts),
|
|
cacheManager: opts.cache,
|
|
ca: opts.ca,
|
|
cert: opts.cert,
|
|
headers: getHeaders(uri, registry, opts),
|
|
integrity: opts.integrity,
|
|
key: opts.key,
|
|
localAddress: opts.localAddress,
|
|
memoize: opts.memoize,
|
|
noProxy: opts.noProxy,
|
|
Promise: BB,
|
|
proxy: opts.proxy,
|
|
referer: opts.refer,
|
|
retry: opts.retry,
|
|
strictSSL: !!opts.strictSSL,
|
|
timeout: opts.timeout,
|
|
uid: opts.uid,
|
|
gid: opts.gid
|
|
}).then(res => {
|
|
if (res.headers.has('npm-notice') && !res.headers.has('x-local-cache')) {
|
|
opts.log.warn('notice', res.headers.get('npm-notice'))
|
|
}
|
|
checkWarnings(res, registry, opts)
|
|
if (res.status >= 400) {
|
|
const err = new Error(`${res.status} ${res.statusText}: ${
|
|
opts.spec ? opts.spec : uri
|
|
}`)
|
|
err.code = `E${res.status}`
|
|
err.uri = uri
|
|
err.response = res
|
|
err.spec = opts.spec
|
|
logRequest(uri, res, startTime, opts)
|
|
throw err
|
|
} else {
|
|
res.body.on('end', () => logRequest(uri, res, startTime, opts))
|
|
return res
|
|
}
|
|
})
|
|
}
|
|
|
|
function logRequest (uri, res, startTime, opts) {
|
|
const elapsedTime = Date.now() - startTime
|
|
const attempt = res.headers.get('x-fetch-attempts')
|
|
const attemptStr = attempt && attempt > 1 ? ` attempt #${attempt}` : ''
|
|
const cacheStr = res.headers.get('x-local-cache') ? ' (from cache)' : ''
|
|
opts.log.http(
|
|
'fetch',
|
|
`GET ${res.status} ${uri} ${elapsedTime}ms${attemptStr}${cacheStr}`
|
|
)
|
|
}
|
|
|
|
function getCacheMode (opts) {
|
|
return opts.offline
|
|
? 'only-if-cached'
|
|
: opts.preferOffline
|
|
? 'force-cache'
|
|
: opts.preferOnline
|
|
? 'no-cache'
|
|
: 'default'
|
|
}
|
|
|
|
function getHeaders (uri, registry, opts) {
|
|
const headers = Object.assign({
|
|
'npm-in-ci': opts.isFromCI,
|
|
'npm-scope': opts.projectScope,
|
|
'npm-session': opts.npmSession,
|
|
'user-agent': opts.userAgent,
|
|
'referer': opts.refer
|
|
}, opts.headers)
|
|
// check for auth settings specific to this registry
|
|
let auth = (
|
|
opts.auth &&
|
|
opts.auth[registryKey(registry)]
|
|
) || opts.auth
|
|
// If a tarball is hosted on a different place than the manifest, only send
|
|
// credentials on `alwaysAuth`
|
|
const shouldAuth = auth && (
|
|
auth.alwaysAuth ||
|
|
url.parse(uri).host === url.parse(registry).host
|
|
)
|
|
if (shouldAuth && auth.token) {
|
|
headers.authorization = `Bearer ${auth.token}`
|
|
} else if (shouldAuth && auth.username && auth.password) {
|
|
const encoded = Buffer.from(
|
|
`${auth.username}:${auth.password}`, 'utf8'
|
|
).toString('base64')
|
|
headers.authorization = `Basic ${encoded}`
|
|
} else if (shouldAuth && auth._auth) {
|
|
headers.authorization = `Basic ${auth._auth}`
|
|
}
|
|
return headers
|
|
}
|
|
|