Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
})
c.pipe(body)
}
: () => {
removeOnResume()
cacache.get.byDigest(cachePath, info.integrity, {
memoize: opts.memoize
})
.then(data => body.end(data))
.catch(/* istanbul ignore next */ err => {
body.emit('error', err)
})
}
body.once('resume', onResume)
body.once('end', () => removeOnResume)
return this.Promise.resolve(new fetch.Response(body, {
url: req.url,
headers: resHeaders,
status: 200,
size: info.size
}))
}
})
}
}
if (opts.redirect === 'manual') {
return res
}
// if (!fetch.isRedirect(res.status) || opts.redirect === 'manual') {
// return res
// }
// handle redirects - matches behavior of fetch: https://github.com/bitinn/node-fetch
if (opts.redirect === 'error') {
const err = new fetch.FetchError(`redirect mode is set to error: ${uri}`, 'no-redirect', { code: 'ENOREDIRECT' })
throw err
}
if (!res.headers.get('location')) {
const err = new fetch.FetchError(`redirect location header missing at: ${uri}`, 'no-location', { code: 'EINVALIDREDIRECT' })
throw err
}
if (req.counter >= req.follow) {
const err = new fetch.FetchError(`maximum redirect reached at: ${uri}`, 'max-redirect', { code: 'EMAXREDIRECT' })
throw err
}
const resolvedUrlParsed = new url.URL(res.headers.get('location'), req.url)
const resolvedUrl = url.format(resolvedUrlParsed)
const redirectURL = (isURL.test(res.headers.get('location')))
? new url.URL(res.headers.get('location'))
: resolvedUrlParsed
// Remove authorization if changing hostnames (but not if just
// changing ports or protocols). This matches the behavior of request:
// return res
// }
// handle redirects - matches behavior of fetch: https://github.com/bitinn/node-fetch
if (opts.redirect === 'error') {
const err = new fetch.FetchError(`redirect mode is set to error: ${uri}`, 'no-redirect', { code: 'ENOREDIRECT' })
throw err
}
if (!res.headers.get('location')) {
const err = new fetch.FetchError(`redirect location header missing at: ${uri}`, 'no-location', { code: 'EINVALIDREDIRECT' })
throw err
}
if (req.counter >= req.follow) {
const err = new fetch.FetchError(`maximum redirect reached at: ${uri}`, 'max-redirect', { code: 'EMAXREDIRECT' })
throw err
}
const resolvedUrlParsed = new url.URL(res.headers.get('location'), req.url)
const resolvedUrl = url.format(resolvedUrlParsed)
const redirectURL = (isURL.test(res.headers.get('location')))
? new url.URL(res.headers.get('location'))
: resolvedUrlParsed
// Remove authorization if changing hostnames (but not if just
// changing ports or protocols). This matches the behavior of request:
// https://github.com/request/request/blob/b12a6245/lib/redirect.js#L134-L138
if (new url.URL(req.url).hostname !== redirectURL.hostname) {
req.headers.delete('authorization')
}
return retryHandler(res)
}
if (!fetch.isRedirect(res.status)) {
return res
}
if (opts.redirect === 'manual') {
return res
}
// if (!fetch.isRedirect(res.status) || opts.redirect === 'manual') {
// return res
// }
// handle redirects - matches behavior of fetch: https://github.com/bitinn/node-fetch
if (opts.redirect === 'error') {
const err = new fetch.FetchError(`redirect mode is set to error: ${uri}`, 'no-redirect', { code: 'ENOREDIRECT' })
throw err
}
if (!res.headers.get('location')) {
const err = new fetch.FetchError(`redirect location header missing at: ${uri}`, 'no-location', { code: 'EINVALIDREDIRECT' })
throw err
}
if (req.counter >= req.follow) {
const err = new fetch.FetchError(`maximum redirect reached at: ${uri}`, 'max-redirect', { code: 'EMAXREDIRECT' })
throw err
}
const resolvedUrlParsed = new url.URL(res.headers.get('location'), req.url)
const resolvedUrl = url.format(resolvedUrlParsed)
const redirectURL = (isURL.test(res.headers.get('location')))
}).then(info => {
if (info && info.metadata && matchDetails(req, {
url: info.metadata.url,
reqHeaders: new fetch.Headers(info.metadata.reqHeaders),
resHeaders: new fetch.Headers(info.metadata.resHeaders),
cacheIntegrity: info.integrity,
integrity: opts && opts.integrity
})) {
const resHeaders = new fetch.Headers(info.metadata.resHeaders)
addCacheHeaders(resHeaders, this._path, key, info.integrity, info.time)
if (req.method === 'HEAD') {
return new fetch.Response(null, {
url: req.url,
headers: resHeaders,
status: 200
})
}
const cachePath = this._path
// avoid opening cache file handles until a user actually tries to
// read from it.
const body = new Minipass()
const fitInMemory = info.size < MAX_MEM_SIZE
const removeOnResume = () => body.removeListener('resume', onResume)
const onResume =
opts.memoize !== false && fitInMemory
? () => {
const c = cacache.get.stream.byDigest(cachePath, info.integrity, {
memoize: opts.memoize
headers: iterableToObject(condRes.headers)
})
if (condRes.status >= 500 && !mustRevalidate(cachedRes)) {
// 111 Revalidation failed
// MUST be included if a cache returns a stale response because an
// attempt to revalidate the response failed, due to an inability to
// reach the server.
// (https://tools.ietf.org/html/rfc2616#section-14.46)
setWarning(cachedRes, 111, 'Revalidation failed')
return cachedRes
}
if (condRes.status === 304) { // 304 Not Modified
// Create a synthetic response from the cached body and original req
const synthRes = new fetch.Response(cachedRes.body, condRes)
return opts.cacheManager.put(req, synthRes, opts)
.then(newRes => {
// Get the list first, because if we delete while iterating,
// it'll throw off the count and not make it through all
// of them.
const newHeaders = revalidatedPolicy.policy.responseHeaders()
const toDelete = [...newRes.headers.keys()]
.filter(k => !newHeaders[k])
for (const key of toDelete) {
newRes.headers.delete(key)
}
for (const [key, val] of Object.entries(newHeaders)) {
newRes.headers.set(key, val)
}
return newRes
})
// if verifying integrity, fetch must not decompress
opts.compress = false
}
const isCachable = (
(
opts.method === 'GET' ||
opts.method === 'HEAD'
) &&
Boolean(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
}).then(info => {
if (info && info.metadata && matchDetails(req, {
url: info.metadata.url,
reqHeaders: new fetch.Headers(info.metadata.reqHeaders),
resHeaders: new fetch.Headers(info.metadata.resHeaders),
cacheIntegrity: info.integrity,
integrity: opts && opts.integrity
})) {
const resHeaders = new fetch.Headers(info.metadata.resHeaders)
addCacheHeaders(resHeaders, this._path, key, info.integrity, info.time)
if (req.method === 'HEAD') {
return new fetch.Response(null, {
url: req.url,
headers: resHeaders,
status: 200
})
}
const cachePath = this._path
// avoid opening cache file handles until a user actually tries to
// read from it.
const body = new Minipass()
const fitInMemory = info.size < MAX_MEM_SIZE
const removeOnResume = () => body.removeListener('resume', onResume)
const onResume =
opts.memoize !== false && fitInMemory
}).then(info => {
if (info && info.metadata && matchDetails(req, {
url: info.metadata.url,
reqHeaders: new fetch.Headers(info.metadata.reqHeaders),
resHeaders: new fetch.Headers(info.metadata.resHeaders),
cacheIntegrity: info.integrity,
integrity: opts && opts.integrity
})) {
const resHeaders = new fetch.Headers(info.metadata.resHeaders)
addCacheHeaders(resHeaders, this._path, key, info.integrity, info.time)
if (req.method === 'HEAD') {
return new fetch.Response(null, {
url: req.url,
headers: resHeaders,
status: 200
})
}
const cachePath = this._path
// avoid opening cache file handles until a user actually tries to
// read from it.
}).then(info => {
if (info && info.metadata && matchDetails(req, {
url: info.metadata.url,
reqHeaders: new fetch.Headers(info.metadata.reqHeaders),
resHeaders: new fetch.Headers(info.metadata.resHeaders),
cacheIntegrity: info.integrity,
integrity: opts && opts.integrity
})) {
const resHeaders = new fetch.Headers(info.metadata.resHeaders)
addCacheHeaders(resHeaders, this._path, key, info.integrity, info.time)
if (req.method === 'HEAD') {
return new fetch.Response(null, {
url: req.url,
headers: resHeaders,
status: 200
})
}
const cachePath = this._path
// avoid opening cache file handles until a user actually tries to
// read from it.
const body = new Minipass()