Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function cachingFetch (uri, _opts) {
const opts = configureOptions(_opts)
if (opts.integrity) {
initializeSsri()
// if verifying integrity, node-fetch must not decompress
opts.compress = false
}
const isCachable = (opts.method === 'GET' || opts.method === 'HEAD') &&
opts.cacheManager &&
opts.cache !== 'no-store' &&
opts.cache !== 'reload'
if (isCachable) {
const req = new fetch.Request(uri, {
method: opts.method,
headers: opts.headers
})
return opts.cacheManager.match(req, opts).then(res => {
if (res) {
const warningCode = (res.headers.get('Warning') || '').match(/^\d+/)
if (warningCode && +warningCode >= 100 && +warningCode < 200) {
// https://tools.ietf.org/html/rfc7234#section-4.3.4
//
// If a stored response is selected for update, the cache MUST:
//
// * delete any Warning header fields in the stored response with
// warn-code 1xx (see Section 5.5);
//
// * retain any Warning header fields in the stored response with
!isStream && (
res.status === 408 || // Request Timeout
res.status === 420 || // Enhance Your Calm (usually Twitter rate-limit)
res.status === 429 || // Too Many Requests ("standard" rate-limiting)
res.status >= 500 // Assume server errors are momentary hiccups
)
if (isRetriable) {
if (typeof opts.onRetry === 'function') {
opts.onRetry(res)
}
return retryHandler(res)
}
if (!fetch.isRedirect(res.status) || opts.redirect === 'manual') {
return res
}
// handle redirects - matches behavior of npm-fetch: https://github.com/bitinn/node-fetch
if (opts.redirect === 'error') {
const err = new Error(`redirect mode is set to error: ${uri}`)
err.code = 'ENOREDIRECT'
throw err
}
if (!res.headers.get('location')) {
const err = new Error(`redirect location header missing at: ${uri}`)
err.code = 'EINVALIDREDIRECT'
throw err
}
function remoteFetch (uri, opts) {
const agent = getAgent(uri, opts)
const headers = Object.assign({
'connection': agent ? 'keep-alive' : 'close',
'user-agent': USER_AGENT
}, opts.headers || {})
const reqOpts = {
agent,
body: opts.body,
compress: opts.compress,
follow: opts.follow,
headers: new fetch.Headers(headers),
method: opts.method,
redirect: 'manual',
size: opts.size,
counter: opts.counter,
timeout: opts.timeout
}
return retry(
(retryHandler, attemptNum) => {
const req = new fetch.Request(uri, reqOpts)
return fetch(req)
.then(res => {
res.headers.set('x-fetch-attempts', attemptNum)
if (opts.integrity) {
remoteFetchHandleIntegrity(res, opts.integrity)
.then(newRes => {
newRes.headers = new fetch.Headers(revalidatedPolicy.policy.responseHeaders())
return newRes
})
}
(retryHandler, attemptNum) => {
const req = new fetch.Request(uri, reqOpts)
return fetch(req)
.then(res => {
res.headers.set('x-fetch-attempts', attemptNum)
if (opts.integrity) {
remoteFetchHandleIntegrity(res, opts.integrity)
}
const isStream = req.body instanceof Stream
if (opts.cacheManager) {
const isMethodGetHead = req.method === 'GET' ||
req.method === 'HEAD'
const isCachable = opts.cache !== 'no-store' &&
isMethodGetHead &&
function cacheDelete (uri, opts) {
opts = configureOptions(opts)
if (opts.cacheManager) {
const req = new fetch.Request(uri, {
method: opts.method,
headers: opts.headers
})
return opts.cacheManager.delete(req, opts)
}
}