function ProxyAgent(opts) {
if (!(this instanceof ProxyAgent)) return new ProxyAgent(opts);
if ('string' == typeof opts) opts = url.parse(opts);
if (!opts) throw new TypeError('an HTTP(S) proxy server `host` and `protocol` must be specified!');
debug('creating new ProxyAgent instance: %o', opts);
Agent.call(this, connect);
var proxies;
if (opts.proxies) {
proxies = extend(Object.create(exports.proxies), opts.proxies);
} else {
proxies = exports.proxies;
}
// get the requested proxy "protocol"
var protocol = opts.protocol;
if (!protocol) {
throw new TypeError('You must specify a string "protocol" for the ' +
'proxy type (' + types().join(', ') + ')');
}
// strip the trailing ":" if present
if (':' == protocol[protocol.length - 1]) {
protocol = protocol.substring(0, protocol.length - 1);
}
// get the proxy `http.Agent` creation function
var proxyFn = proxies[protocol];
if ('function' != typeof proxyFn) {
throw new TypeError('unsupported proxy protocol: "' + protocol + '"');
}
this.proxy = opts;
// format the proxy info back into a URI, since an opts object
// could have been passed in originally. This generated URI is used
// as part of the "key" for the LRU cache
this.proxyUri = url.format({
protocol: protocol + ':',
slashes: true,
hostname: opts.hostname || opts.host,
port: opts.port
});
this.proxyFn = proxyFn;
}n/a
function SocksProxyAgent(opts) {
if (!(this instanceof SocksProxyAgent)) return new SocksProxyAgent(opts);
if ('string' == typeof opts) opts = url.parse(opts);
if (!opts) throw new Error('a SOCKS proxy server `host` and `port` must be specified!');
Agent.call(this, connect);
var proxy = extend({}, opts);
// prefer `hostname` over `host`, because of `url.parse()`
proxy.host = proxy.hostname || proxy.host;
// SOCKS doesn't *technically* have a default port, but this is
// the same default that `curl(1)` uses
proxy.port = +proxy.port || 1080;
if (proxy.host && proxy.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete proxy.path;
delete proxy.pathname;
}
// figure out if we want socks v4 or v5, based on the "protocol" used.
// Defaults to 5.
proxy.lookup = false;
switch (proxy.protocol) {
case 'socks4:':
proxy.lookup = true;
// pass through
case 'socks4a:':
proxy.version = 4;
break;
case 'socks5:':
proxy.lookup = true;
// pass through
case 'socks:': // no version specified, default to 5h
case 'socks5h:':
proxy.version = 5;
break;
default:
throw new TypeError('A "socks" protocol must be specified! Got: ' + proxy.protocol);
}
this.proxy = proxy;
}n/a
function Agent(callback) {
if (!(this instanceof Agent)) return new Agent(callback);
if ('function' != typeof callback) throw new Error('Must pass a "callback function"');
EventEmitter.call(this);
this.callback = callback;
}n/a
function naiveLength() { return 1 }n/a
function httpOrHttpsProxy(opts, secureEndpoint) {
if (secureEndpoint) {
// HTTPS
return new HttpsProxyAgent(opts);
} else {
// HTTP
return new HttpProxyAgent(opts);
}
}n/a
function httpOrHttpsProxy(opts, secureEndpoint) {
if (secureEndpoint) {
// HTTPS
return new HttpsProxyAgent(opts);
} else {
// HTTP
return new HttpProxyAgent(opts);
}
}n/a
function SocksProxyAgent(opts) {
if (!(this instanceof SocksProxyAgent)) return new SocksProxyAgent(opts);
if ('string' == typeof opts) opts = url.parse(opts);
if (!opts) throw new Error('a SOCKS proxy server `host` and `port` must be specified!');
Agent.call(this, connect);
var proxy = extend({}, opts);
// prefer `hostname` over `host`, because of `url.parse()`
proxy.host = proxy.hostname || proxy.host;
// SOCKS doesn't *technically* have a default port, but this is
// the same default that `curl(1)` uses
proxy.port = +proxy.port || 1080;
if (proxy.host && proxy.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete proxy.path;
delete proxy.pathname;
}
// figure out if we want socks v4 or v5, based on the "protocol" used.
// Defaults to 5.
proxy.lookup = false;
switch (proxy.protocol) {
case 'socks4:':
proxy.lookup = true;
// pass through
case 'socks4a:':
proxy.version = 4;
break;
case 'socks5:':
proxy.lookup = true;
// pass through
case 'socks:': // no version specified, default to 5h
case 'socks5h:':
proxy.version = 5;
break;
default:
throw new TypeError('A "socks" protocol must be specified! Got: ' + proxy.protocol);
}
this.proxy = proxy;
}n/a
function SocksProxyAgent(opts) {
if (!(this instanceof SocksProxyAgent)) return new SocksProxyAgent(opts);
if ('string' == typeof opts) opts = url.parse(opts);
if (!opts) throw new Error('a SOCKS proxy server `host` and `port` must be specified!');
Agent.call(this, connect);
var proxy = extend({}, opts);
// prefer `hostname` over `host`, because of `url.parse()`
proxy.host = proxy.hostname || proxy.host;
// SOCKS doesn't *technically* have a default port, but this is
// the same default that `curl(1)` uses
proxy.port = +proxy.port || 1080;
if (proxy.host && proxy.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete proxy.path;
delete proxy.pathname;
}
// figure out if we want socks v4 or v5, based on the "protocol" used.
// Defaults to 5.
proxy.lookup = false;
switch (proxy.protocol) {
case 'socks4:':
proxy.lookup = true;
// pass through
case 'socks4a:':
proxy.version = 4;
break;
case 'socks5:':
proxy.lookup = true;
// pass through
case 'socks:': // no version specified, default to 5h
case 'socks5h:':
proxy.version = 5;
break;
default:
throw new TypeError('A "socks" protocol must be specified! Got: ' + proxy.protocol);
}
this.proxy = proxy;
}n/a
function SocksProxyAgent(opts) {
if (!(this instanceof SocksProxyAgent)) return new SocksProxyAgent(opts);
if ('string' == typeof opts) opts = url.parse(opts);
if (!opts) throw new Error('a SOCKS proxy server `host` and `port` must be specified!');
Agent.call(this, connect);
var proxy = extend({}, opts);
// prefer `hostname` over `host`, because of `url.parse()`
proxy.host = proxy.hostname || proxy.host;
// SOCKS doesn't *technically* have a default port, but this is
// the same default that `curl(1)` uses
proxy.port = +proxy.port || 1080;
if (proxy.host && proxy.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete proxy.path;
delete proxy.pathname;
}
// figure out if we want socks v4 or v5, based on the "protocol" used.
// Defaults to 5.
proxy.lookup = false;
switch (proxy.protocol) {
case 'socks4:':
proxy.lookup = true;
// pass through
case 'socks4a:':
proxy.version = 4;
break;
case 'socks5:':
proxy.lookup = true;
// pass through
case 'socks:': // no version specified, default to 5h
case 'socks5h:':
proxy.version = 5;
break;
default:
throw new TypeError('A "socks" protocol must be specified! Got: ' + proxy.protocol);
}
this.proxy = proxy;
}n/a
function SocksProxyAgent(opts) {
if (!(this instanceof SocksProxyAgent)) return new SocksProxyAgent(opts);
if ('string' == typeof opts) opts = url.parse(opts);
if (!opts) throw new Error('a SOCKS proxy server `host` and `port` must be specified!');
Agent.call(this, connect);
var proxy = extend({}, opts);
// prefer `hostname` over `host`, because of `url.parse()`
proxy.host = proxy.hostname || proxy.host;
// SOCKS doesn't *technically* have a default port, but this is
// the same default that `curl(1)` uses
proxy.port = +proxy.port || 1080;
if (proxy.host && proxy.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete proxy.path;
delete proxy.pathname;
}
// figure out if we want socks v4 or v5, based on the "protocol" used.
// Defaults to 5.
proxy.lookup = false;
switch (proxy.protocol) {
case 'socks4:':
proxy.lookup = true;
// pass through
case 'socks4a:':
proxy.version = 4;
break;
case 'socks5:':
proxy.lookup = true;
// pass through
case 'socks:': // no version specified, default to 5h
case 'socks5h:':
proxy.version = 5;
break;
default:
throw new TypeError('A "socks" protocol must be specified! Got: ' + proxy.protocol);
}
this.proxy = proxy;
}n/a
function SocksProxyAgent(opts) {
if (!(this instanceof SocksProxyAgent)) return new SocksProxyAgent(opts);
if ('string' == typeof opts) opts = url.parse(opts);
if (!opts) throw new Error('a SOCKS proxy server `host` and `port` must be specified!');
Agent.call(this, connect);
var proxy = extend({}, opts);
// prefer `hostname` over `host`, because of `url.parse()`
proxy.host = proxy.hostname || proxy.host;
// SOCKS doesn't *technically* have a default port, but this is
// the same default that `curl(1)` uses
proxy.port = +proxy.port || 1080;
if (proxy.host && proxy.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete proxy.path;
delete proxy.pathname;
}
// figure out if we want socks v4 or v5, based on the "protocol" used.
// Defaults to 5.
proxy.lookup = false;
switch (proxy.protocol) {
case 'socks4:':
proxy.lookup = true;
// pass through
case 'socks4a:':
proxy.version = 4;
break;
case 'socks5:':
proxy.lookup = true;
// pass through
case 'socks:': // no version specified, default to 5h
case 'socks5h:':
proxy.version = 5;
break;
default:
throw new TypeError('A "socks" protocol must be specified! Got: ' + proxy.protocol);
}
this.proxy = proxy;
}n/a
function SocksProxyAgent(opts) {
if (!(this instanceof SocksProxyAgent)) return new SocksProxyAgent(opts);
if ('string' == typeof opts) opts = url.parse(opts);
if (!opts) throw new Error('a SOCKS proxy server `host` and `port` must be specified!');
Agent.call(this, connect);
var proxy = extend({}, opts);
// prefer `hostname` over `host`, because of `url.parse()`
proxy.host = proxy.hostname || proxy.host;
// SOCKS doesn't *technically* have a default port, but this is
// the same default that `curl(1)` uses
proxy.port = +proxy.port || 1080;
if (proxy.host && proxy.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete proxy.path;
delete proxy.pathname;
}
// figure out if we want socks v4 or v5, based on the "protocol" used.
// Defaults to 5.
proxy.lookup = false;
switch (proxy.protocol) {
case 'socks4:':
proxy.lookup = true;
// pass through
case 'socks4a:':
proxy.version = 4;
break;
case 'socks5:':
proxy.lookup = true;
// pass through
case 'socks:': // no version specified, default to 5h
case 'socks5h:':
proxy.version = 5;
break;
default:
throw new TypeError('A "socks" protocol must be specified! Got: ' + proxy.protocol);
}
this.proxy = proxy;
}n/a
function Agent(callback) {
if (!(this instanceof Agent)) return new Agent(callback);
if ('function' != typeof callback) throw new Error('Must pass a "callback function"');
EventEmitter.call(this);
this.callback = callback;
}n/a
function EventEmitter() {
EventEmitter.init.call(this);
}n/a
addRequest = function (req, host, port, localAddress) {
var opts;
if ('object' == typeof host) {
// >= v0.11.x API
opts = extend({}, req._options, host);
} else {
// <= v0.10.x API
opts = extend({}, req._options, { host: host, port: port });
if (null != localAddress) {
opts.localAddress = localAddress;
}
}
if (opts.host && opts.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete opts.path;
}
// set default `port` if none was explicitly specified
if (null == opts.port) {
opts.port = opts.secureEndpoint ? 443 : 80;
}
delete opts.agent;
delete opts.hostname;
delete opts._defaultAgent;
delete opts.defaultPort;
delete opts.createConnection;
// hint to use "Connection: close"
// XXX: non-documented `http` module API :(
req._last = true;
req.shouldKeepAlive = false;
// clean up a bit of memory since we're no longer using this
req._options = null;
// create the `net.Socket` instance
var sync = true;
this.callback(req, opts, function (err, socket) {
function emitErr () {
req.emit('error', err);
// For Safety. Some additional errors might fire later on
// and we need to make sure we don't double-fire the error event.
req._hadError = true;
}
if (err) {
if (sync) {
// need to defer the "error" event, when sync, because by now the `req`
// instance hasn't event been passed back to the user yet...
process.nextTick(emitErr);
} else {
emitErr();
}
} else {
req.onSocket(socket);
}
});
sync = false;
}...
if (agent) exports.cache.set(key, agent);
} else {
debug('cache hit with key: %o', key);
}
// XXX: agent.callback() is an agent-base-ism
// TODO: add support for generic `http.Agent` instances by calling
// agent.addRequest(), but with support for <= 0.10.x and >= 0.12.x
agent.callback(req, opts, fn);
}
/**
* Returns an Array of supported protocol string names.
*
* @return {Array}
...