Skip to content

Commit

Permalink
Merge pull request #1346 from seanstrom/support/extract-getProxyFromURI
Browse files Browse the repository at this point in the history
getProxyFromURI Extraction Refactor
  • Loading branch information
nylen committed Jan 13, 2015
2 parents 2100b49 + b205b73 commit 5d515b0
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 54 deletions.
79 changes: 79 additions & 0 deletions lib/getProxyFromURI.js
@@ -0,0 +1,79 @@
'use strict'

function formatHostname(hostname) {
// canonicalize the hostname, so that 'oogle.com' won't match 'google.com'
return hostname.replace(/^\.*/, '.').toLowerCase()
}

function parseNoProxyZone(zone) {
zone = zone.trim().toLowerCase()

var zoneParts = zone.split(':', 2)
, zoneHost = formatHostname(zoneParts[0])
, zonePort = zoneParts[1]
, hasPort = zone.indexOf(':') > -1

return {hostname: zoneHost, port: zonePort, hasPort: hasPort}
}

function uriInNoProxy(uri, noProxy) {
var port = uri.port || (uri.protocol === 'https:' ? '443' : '80')
, hostname = formatHostname(uri.hostname)
, noProxyList = noProxy.split(',')

// iterate through the noProxyList until it finds a match.
return noProxyList.map(parseNoProxyZone).some(function(noProxyZone) {
var isMatchedAt = hostname.indexOf(noProxyZone.hostname)
, hostnameMatched = (
isMatchedAt > -1 &&
(isMatchedAt === hostname.length - noProxyZone.hostname.length)
)

if (noProxyZone.hasPort) {
return (port === noProxyZone.port) && hostnameMatched
}

return hostnameMatched
})
}

function getProxyFromURI(uri) {
// Decide the proper request proxy to use based on the request URI object and the
// environmental variables (NO_PROXY, HTTP_PROXY, etc.)
// respect NO_PROXY environment variables (see: http://lynx.isc.org/current/breakout/lynx_help/keystrokes/environments.html)

var noProxy = process.env.NO_PROXY || process.env.no_proxy || ''

// if the noProxy is a wildcard then return null

if (noProxy === '*') {
return null
}

// if the noProxy is not empty and the uri is found return null

if (noProxy !== '' && uriInNoProxy(uri, noProxy)) {
return null
}

// Check for HTTP or HTTPS Proxy in environment Else default to null

if (uri.protocol === 'http:') {
return process.env.HTTP_PROXY ||
process.env.http_proxy || null
}

if (uri.protocol === 'https:') {
return process.env.HTTPS_PROXY ||
process.env.https_proxy ||
process.env.HTTP_PROXY ||
process.env.http_proxy || null
}

// if none of that works, return null
// (What uri protocol are you using then?)

return null
}

module.exports = getProxyFromURI
55 changes: 1 addition & 54 deletions request.js
Expand Up @@ -27,6 +27,7 @@ var http = require('http')
, net = require('net')
, CombinedStream = require('combined-stream')
, isstream = require('isstream')
, getProxyFromURI = require('./lib/getProxyFromURI')

var safeStringify = helpers.safeStringify
, md5 = helpers.md5
Expand Down Expand Up @@ -165,60 +166,6 @@ function getTunnelFn(request) {
return tunnel[tunnelFnName]
}

// Decide the proper request proxy to use based on the request URI object and the
// environmental variables (NO_PROXY, HTTP_PROXY, etc.)
function getProxyFromURI(uri) {
// respect NO_PROXY environment variables (see: http://lynx.isc.org/current/breakout/lynx_help/keystrokes/environments.html)
var noProxy = process.env.NO_PROXY || process.env.no_proxy || null

// easy case first - if NO_PROXY is '*'
if (noProxy === '*') {
return null
}

// otherwise, parse the noProxy value to see if it applies to the URL
if (noProxy !== null) {
var noProxyItem, hostname, port, noProxyItemParts, noProxyHost, noProxyPort, noProxyList

// canonicalize the hostname, so that 'oogle.com' won't match 'google.com'
hostname = uri.hostname.replace(/^\.*/, '.').toLowerCase()
noProxyList = noProxy.split(',')

for (var i = 0, len = noProxyList.length; i < len; i++) {
noProxyItem = noProxyList[i].trim().toLowerCase()

// no_proxy can be granular at the port level, which complicates things a bit.
if (noProxyItem.indexOf(':') > -1) {
noProxyItemParts = noProxyItem.split(':', 2)
noProxyHost = noProxyItemParts[0].replace(/^\.*/, '.')
noProxyPort = noProxyItemParts[1]
port = uri.port || (uri.protocol === 'https:' ? '443' : '80')

// we've found a match - ports are same and host ends with no_proxy entry.
if (port === noProxyPort && hostname.indexOf(noProxyHost) === hostname.length - noProxyHost.length) {
return null
}
} else {
noProxyItem = noProxyItem.replace(/^\.*/, '.')
var isMatchedAt = hostname.indexOf(noProxyItem)
if (isMatchedAt > -1 && isMatchedAt === hostname.length - noProxyItem.length) {
return null
}
}
}
}

// check for HTTP(S)_PROXY environment variables
if (uri.protocol === 'http:') {
return process.env.HTTP_PROXY || process.env.http_proxy || null
} else if (uri.protocol === 'https:') {
return process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || null
}

// return null if all else fails (What uri protocol are you using then?)
return null
}

// Function for properly handling a connection error
function connectionErrorHandler(error) {
var socket = this
Expand Down

0 comments on commit 5d515b0

Please sign in to comment.