summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/request/lib/tunnel.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/request/lib/tunnel.js')
-rw-r--r--deps/npm/node_modules/request/lib/tunnel.js183
1 files changed, 183 insertions, 0 deletions
diff --git a/deps/npm/node_modules/request/lib/tunnel.js b/deps/npm/node_modules/request/lib/tunnel.js
new file mode 100644
index 000000000..cf28016e2
--- /dev/null
+++ b/deps/npm/node_modules/request/lib/tunnel.js
@@ -0,0 +1,183 @@
+'use strict'
+
+var url = require('url')
+ , tunnel = require('tunnel-agent')
+
+var defaultProxyHeaderWhiteList = [
+ 'accept',
+ 'accept-charset',
+ 'accept-encoding',
+ 'accept-language',
+ 'accept-ranges',
+ 'cache-control',
+ 'content-encoding',
+ 'content-language',
+ 'content-length',
+ 'content-location',
+ 'content-md5',
+ 'content-range',
+ 'content-type',
+ 'connection',
+ 'date',
+ 'expect',
+ 'max-forwards',
+ 'pragma',
+ 'referer',
+ 'te',
+ 'transfer-encoding',
+ 'user-agent',
+ 'via'
+]
+
+var defaultProxyHeaderExclusiveList = [
+ 'proxy-authorization'
+]
+
+function constructProxyHost(uriObject) {
+ var port = uriObject.portA
+ , protocol = uriObject.protocol
+ , proxyHost = uriObject.hostname + ':'
+
+ if (port) {
+ proxyHost += port
+ } else if (protocol === 'https:') {
+ proxyHost += '443'
+ } else {
+ proxyHost += '80'
+ }
+
+ return proxyHost
+}
+
+function constructProxyHeaderWhiteList(headers, proxyHeaderWhiteList) {
+ var whiteList = proxyHeaderWhiteList
+ .reduce(function (set, header) {
+ set[header.toLowerCase()] = true
+ return set
+ }, {})
+
+ return Object.keys(headers)
+ .filter(function (header) {
+ return whiteList[header.toLowerCase()]
+ })
+ .reduce(function (set, header) {
+ set[header] = headers[header]
+ return set
+ }, {})
+}
+
+function constructTunnelOptions (request, proxyHeaders) {
+ var proxy = request.proxy
+
+ var tunnelOptions = {
+ proxy : {
+ host : proxy.hostname,
+ port : +proxy.port,
+ proxyAuth : proxy.auth,
+ headers : proxyHeaders
+ },
+ headers : request.headers,
+ ca : request.ca,
+ cert : request.cert,
+ key : request.key,
+ passphrase : request.passphrase,
+ pfx : request.pfx,
+ ciphers : request.ciphers,
+ rejectUnauthorized : request.rejectUnauthorized,
+ secureOptions : request.secureOptions,
+ secureProtocol : request.secureProtocol
+ }
+
+ return tunnelOptions
+}
+
+function constructTunnelFnName(uri, proxy) {
+ var uriProtocol = (uri.protocol === 'https:' ? 'https' : 'http')
+ var proxyProtocol = (proxy.protocol === 'https:' ? 'Https' : 'Http')
+ return [uriProtocol, proxyProtocol].join('Over')
+}
+
+function getTunnelFn(request) {
+ var uri = request.uri
+ var proxy = request.proxy
+ var tunnelFnName = constructTunnelFnName(uri, proxy)
+ return tunnel[tunnelFnName]
+}
+
+
+function Tunnel (request) {
+ this.request = request
+ this.proxyHeaderWhiteList = defaultProxyHeaderWhiteList
+ this.proxyHeaderExclusiveList = []
+}
+
+Tunnel.prototype.isEnabled = function (options) {
+ var request = this.request
+ // Tunnel HTTPS by default, or if a previous request in the redirect chain
+ // was tunneled. Allow the user to override this setting.
+
+ // If self.tunnel is already set (because this is a redirect), use the
+ // existing value.
+ if (typeof request.tunnel !== 'undefined') {
+ return request.tunnel
+ }
+
+ // If options.tunnel is set (the user specified a value), use it.
+ if (typeof options.tunnel !== 'undefined') {
+ return options.tunnel
+ }
+
+ // If the destination is HTTPS, tunnel.
+ if (request.uri.protocol === 'https:') {
+ return true
+ }
+
+ // Otherwise, leave tunnel unset, because if a later request in the redirect
+ // chain is HTTPS then that request (and any subsequent ones) should be
+ // tunneled.
+ return undefined
+}
+
+Tunnel.prototype.setup = function (options) {
+ var self = this
+ , request = self.request
+
+ options = options || {}
+
+ if (typeof request.proxy === 'string') {
+ request.proxy = url.parse(request.proxy)
+ }
+
+ if (!request.proxy || !request.tunnel) {
+ return false
+ }
+
+ // Setup Proxy Header Exclusive List and White List
+ if (options.proxyHeaderWhiteList) {
+ self.proxyHeaderWhiteList = options.proxyHeaderWhiteList
+ }
+ if (options.proxyHeaderExclusiveList) {
+ self.proxyHeaderExclusiveList = options.proxyHeaderExclusiveList
+ }
+
+ var proxyHeaderExclusiveList = self.proxyHeaderExclusiveList.concat(defaultProxyHeaderExclusiveList)
+ var proxyHeaderWhiteList = self.proxyHeaderWhiteList.concat(proxyHeaderExclusiveList)
+
+ // Setup Proxy Headers and Proxy Headers Host
+ // Only send the Proxy White Listed Header names
+ var proxyHeaders = constructProxyHeaderWhiteList(request.headers, proxyHeaderWhiteList)
+ proxyHeaders.host = constructProxyHost(request.uri)
+
+ proxyHeaderExclusiveList.forEach(request.removeHeader, request)
+
+ // Set Agent from Tunnel Data
+ var tunnelFn = getTunnelFn(request)
+ var tunnelOptions = constructTunnelOptions(request, proxyHeaders)
+ request.agent = tunnelFn(tunnelOptions)
+
+ return true
+}
+
+Tunnel.defaultProxyHeaderWhiteList = defaultProxyHeaderWhiteList
+Tunnel.defaultProxyHeaderExclusiveList = defaultProxyHeaderExclusiveList
+exports.Tunnel = Tunnel