Skip to content
This repository has been archived by the owner on Jun 12, 2022. It is now read-only.

Commit

Permalink
feat(agent): add ca/cert/key support to auto-agent (#15)
Browse files Browse the repository at this point in the history
Fixes: #14

Incidentally, got rid of proxy-agent because the pac thing I'm sure
literally no one would use (heh) was basically a MASSIVE dependency.
  • Loading branch information
zkat authored Apr 9, 2017
1 parent 9aed397 commit fadb851
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 25 deletions.
106 changes: 88 additions & 18 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

let Cache
const fetch = require('node-fetch')
let ProxyAgent
const LRU = require('lru-cache')
const pkg = require('./package.json')
const retry = require('promise-retry')
let ssri
const Stream = require('stream')
const url = require('url')

const RETRY_ERRORS = [
'ECONNRESET', // remote socket closed on us
Expand Down Expand Up @@ -339,32 +340,101 @@ function remoteFetch (uri, opts) {
})
}

let httpsAgent
let httpAgent
let AGENT_CACHE = new LRU({
max: 50
})
let HttpsAgent
let HttpAgent
function getAgent (uri, opts) {
const parsedUri = url.parse(uri)
const isHttps = parsedUri.protocol === 'https:'
const pxuri = getProxyUri(uri, opts)
const key = [
`https:${isHttps}`,
pxuri
? `proxy:${pxuri.protocol}//${pxuri.host}:${pxuri.port}`
: '>no-proxy<',
`ca:${(isHttps && opts.ca) || '>no-ca<'}`,
`cert:${(isHttps && opts.cert) || '>no-cert<'}`,
`key:${(isHttps && opts.key) || '>no-key<'}`
].join(':')
if (opts.agent != null) {
// `agent: false` has special behavior!
return opts.agent
} else if (opts.proxy) {
if (!ProxyAgent) {
ProxyAgent = require('proxy-agent')
}
return new ProxyAgent(opts.proxy)
} else if (uri.trim().startsWith('https:')) {
if (!httpsAgent) {
const Agent = require('agentkeepalive').HttpsAgent
httpsAgent = new Agent({maxSockets: 15})
}
return httpsAgent
} else if (AGENT_CACHE.peek(key)) {
return AGENT_CACHE.get(key)
} else if (pxuri) {
const proxy = getProxy(pxuri, opts)
AGENT_CACHE.set(key, proxy)
return proxy
} else {
if (!httpAgent) {
const Agent = require('agentkeepalive')
httpAgent = new Agent({maxSockets: 15})
if (isHttps && !HttpsAgent) {
HttpsAgent = require('agentkeepalive').HttpsAgent
} else if (!isHttps && !HttpAgent) {
HttpAgent = require('agentkeepalive')
}
return httpAgent
const agent = isHttps
? new HttpsAgent({
maxSockets: opts.maxSockets || 15,
ca: opts.ca,
cert: opts.cert,
key: opts.key
})
: new HttpAgent({
maxSockets: opts.maxSockets || 15
})
AGENT_CACHE.set(key, agent)
return agent
}
}

function getProxyUri (uri, opts) {
const puri = url.parse(uri)
const proxy = opts.proxy || (
puri.protocol === 'https:' && process.env.https_proxy
) || (
puri.protocol === 'http:' && (
process.env.https_proxy || process.env.http_proxy || process.env.proxy
)
)
return !checkNoProxy(uri) && (
typeof proxy === 'string'
? url.parse(proxy)
: proxy
)
}

let HttpProxyAgent
let HttpsProxyAgent
let SocksProxyAgent
function getProxy (proxyUrl, opts) {
let popts = {
host: proxyUrl.hostname,
port: proxyUrl.port,
protocol: proxyUrl.protocol,
path: proxyUrl.path,
ca: opts.ca,
cert: opts.cert,
key: opts.key,
maxSockets: opts.maxSockets || 15
}
if (proxyUrl.protocol === 'http:') {
if (!HttpProxyAgent) { HttpProxyAgent = require('http-proxy-agent') }
return new HttpProxyAgent(popts)
} else if (proxyUrl.protocol === 'https:') {
if (!HttpsProxyAgent) { HttpsProxyAgent = require('https-proxy-agent') }
return new HttpsProxyAgent(popts)
} else if (proxyUrl.startsWith('socks')) {
if (!SocksProxyAgent) { SocksProxyAgent = require('socks-proxy-agent') }
return new SocksProxyAgent(popts)
}
}

function checkNoProxy (uri) {
// TODO
return false
}

function isConditional (headers) {
return Object.keys(headers).some(h => {
h = h.toLowerCase()
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@
"bluebird": "^3.5.0",
"cacache": "^7.0.3",
"checksum-stream": "^1.0.2",
"http-proxy-agent": "^1.0.0",
"https-proxy-agent": "^1.0.0",
"lru-cache": "^4.0.2",
"mississippi": "^1.2.0",
"node-fetch": "file:node-fetch-pkg.tgz",
"promise-retry": "^1.1.1",
"proxy-agent": "^2.0.0",
"safe-buffer": "^5.0.1",
"socks-proxy-agent": "^2.0.0",
"ssri": "^4.0.0"
},
"devDependencies": {
Expand Down
7 changes: 1 addition & 6 deletions test/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,9 @@ test('supports proxy configurations', t => {
})
})
})
}).listen(9854)
}).listen(9854).on('error', err => { throw err })
fetch(`http://npm.im/make-fetch-happen`, {
proxy: 'http://localhost:9854',
proxyOpts: {
headers: {
foo: 'bar'
}
},
retry: {
retries: 0
}
Expand Down

0 comments on commit fadb851

Please sign in to comment.