thejagstudio's picture
Upload 56 files
b32c7e6 verified
'use strict';
var parseUrl = require('url').parse;
var DEFAULT_PORTS = {
'ftp:': 21,
'gopher:': 70,
'http:': 80,
'https:': 443,
'ws:': 80,
'wss:': 443,
};
var stringEndsWith = String.prototype.endsWith || function(s) {
return s.length <= this.length &&
this.indexOf(s, this.length - s.length) !== -1;
};
/**
* @param {string} url - The URL
* @return {string} The URL of the proxy that should handle the request to the
* given URL. If no proxy is set, this will be an empty string.
*/
function getProxyForUrl(url) {
var parsedUrl = parseUrl(url);
if (!parsedUrl.host || !shouldProxy(parsedUrl)) {
return ''; // Don't proxy invalid URLs or URLs that match NO_PROXY.
}
var proto = url.split(':', 1)[0];
return getEnv(proto + '_proxy') || getEnv('all_proxy');
}
/**
* Determines whether a given URL should be proxied.
*
* @param {object} parsedUrl - The result of url.parse
* @returns {boolean} Whether the given URL should be proxied.
* @private
*/
function shouldProxy(parsedUrl) {
var NO_PROXY = getEnv('no_proxy').toLowerCase();
if (!NO_PROXY) {
return true; // Always proxy if NO_PROXY is not set.
}
if (NO_PROXY === '*') {
return false; // Never proxy if wildcard is set.
}
var port = parseInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || 0;
// Stripping ports in this way instead of using parsedUrl.hostname to make
// sure that the brackets around IPv6 addresses are kept.
var hostname = parsedUrl.host.replace(/:\d*$/, '');
return NO_PROXY.split(/[,\s]/).every(function(proxy) {
if (!proxy) {
return true; // Skip zero-length hosts.
}
var parsedProxy = proxy.match(/^(.+):(\d+)$/);
var parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy;
var parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
if (parsedProxyPort && parsedProxyPort !== port) {
return true; // Skip if ports don't match.
}
if (!/^[.*]/.test(parsedProxyHostname)) {
// No wildcards, so stop proxying if there is an exact match.
return hostname !== parsedProxyHostname;
}
if (parsedProxyHostname.charAt(0) === '*') {
// Remove leading wildcard.
parsedProxyHostname = parsedProxyHostname.slice(1);
}
// Stop proxying if the hostname ends with the no_proxy host.
return !stringEndsWith.call(hostname, parsedProxyHostname);
});
}
/**
* Get the value for an environment variable.
*
* @param {string} key - The name of the environment variable.
* @return {string} The value of the environment variable.
* @private
*/
function getEnv(key) {
return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
}
exports.getProxyForUrl = getProxyForUrl;