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.
		
		
		
		
		
			
		
			
				
					
					
						
							176 lines
						
					
					
						
							4.3 KiB
						
					
					
				
			
		
		
	
	
							176 lines
						
					
					
						
							4.3 KiB
						
					
					
				'use strict'
 | 
						|
 | 
						|
var url = require('url')
 | 
						|
var tunnel = require('tunnel-agent')
 | 
						|
 | 
						|
var defaultProxyHeaderWhiteList = [
 | 
						|
  'accept',
 | 
						|
  'accept-charset',
 | 
						|
  'accept-encoding',
 | 
						|
  'accept-language',
 | 
						|
  'accept-ranges',
 | 
						|
  'cache-control',
 | 
						|
  'content-encoding',
 | 
						|
  'content-language',
 | 
						|
  'content-location',
 | 
						|
  'content-md5',
 | 
						|
  'content-range',
 | 
						|
  'content-type',
 | 
						|
  'connection',
 | 
						|
  'date',
 | 
						|
  'expect',
 | 
						|
  'max-forwards',
 | 
						|
  'pragma',
 | 
						|
  'referer',
 | 
						|
  'te',
 | 
						|
  'user-agent',
 | 
						|
  'via'
 | 
						|
]
 | 
						|
 | 
						|
var defaultProxyHeaderExclusiveList = [
 | 
						|
  'proxy-authorization'
 | 
						|
]
 | 
						|
 | 
						|
function constructProxyHost (uriObject) {
 | 
						|
  var port = uriObject.port
 | 
						|
  var protocol = uriObject.protocol
 | 
						|
  var 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 = []
 | 
						|
  if (typeof request.tunnel !== 'undefined') {
 | 
						|
    this.tunnelOverride = request.tunnel
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
Tunnel.prototype.isEnabled = function () {
 | 
						|
  var self = this
 | 
						|
  var request = self.request
 | 
						|
    // Tunnel HTTPS by default. Allow the user to override this setting.
 | 
						|
 | 
						|
  // If self.tunnelOverride is set (the user specified a value), use it.
 | 
						|
  if (typeof self.tunnelOverride !== 'undefined') {
 | 
						|
    return self.tunnelOverride
 | 
						|
  }
 | 
						|
 | 
						|
  // If the destination is HTTPS, tunnel.
 | 
						|
  if (request.uri.protocol === 'https:') {
 | 
						|
    return true
 | 
						|
  }
 | 
						|
 | 
						|
  // Otherwise, do not use tunnel.
 | 
						|
  return false
 | 
						|
}
 | 
						|
 | 
						|
Tunnel.prototype.setup = function (options) {
 | 
						|
  var self = this
 | 
						|
  var 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
 |