Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getProxyFromURI Extraction Refactor #1346

Merged
merged 1 commit into from Jan 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about calling this parseNoProxyZone, then you can do ...


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
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

||
null

or

|| null

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops this was a typo aha, but it poses an interesting question.
I kind of like the second one, so I'll make the other conform


// 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