Socket
Socket
Sign inDemoInstall

pac-proxy-agent

Package Overview
Dependencies
99
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.0 to 1.0.0

.travis.yml

23

History.md
1.0.0 / 2015-07-10
==================
* package: update "extend" to v3
* refactor to use proxy agent classes directly
* upgrade to `agent-base` v2 API
* use "stream-to-buffer"
* use %o formatter for debug() calls
* package: update "get-uri" to v1
* package: update "mocha" to v2
* travis: test node v0.8, v0.10, and v0.12
* test: add initial test cases
* test: add basic "https" module tests
* README: use SVG for Travis-CI badge
0.2.0 / 2014-11-10
==================
* index: add reference link for Chrome's "HTTPS" support
* index: throw an error for unknown proxy types (#2, @michaelansel)
* index: support HTTPS proxies (#2, @michaelansel)
* package: alloy any "debug" v2
* index: add reference link for Chrome's "HTTPS" support
* index: throw an error for unknown proxy types (#2, @michaelansel)
* index: support HTTPS proxies (#2, @michaelansel)
* package: allow any "debug" v2

@@ -10,0 +25,0 @@ 0.1.2 / 2014-04-04

84

index.js
/**
* Module exports.
*
* XXX: exports going first here so that the circular require with
* `proxy-agent` doesn't result in an empty `exports` object for
* this module when `proxy-agent` requires us.
*/

@@ -34,5 +30,7 @@

var Agent = require('agent-base');
var ProxyAgent = require('proxy-agent');
var HttpProxyAgent = require('http-proxy-agent');
var HttpsProxyAgent = require('https-proxy-agent');
var SocksProxyAgent = require('socks-proxy-agent');
var PacResolver = require('pac-resolver');
var toArray = require('stream-to-array');
var toBuffer = require('stream-to-buffer');
var inherits = require('util').inherits;

@@ -56,20 +54,27 @@ var debug = require('debug')('pac-proxy-agent');

function PacProxyAgent (opts) {
if (!(this instanceof PacProxyAgent)) return new PacProxyAgent(opts);
var uri;
if ('string' == typeof opts) {
uri = opts;
} else {
if (opts.path && !opts.pathname) {
opts.pathname = opts.path;
function PacProxyAgent (uri, opts) {
if (!(this instanceof PacProxyAgent)) return new PacProxyAgent(uri, opts);
// was an options object passed in first?
if ('object' === typeof uri) {
opts = uri;
// result of a url.parse() call?
if (opts.href) {
if (opts.path && !opts.pathname) {
opts.pathname = opts.path;
}
opts.slashes = true;
uri = format(opts);
} else {
uri = opts.uri;
}
opts.slashes = true;
uri = format(opts);
}
if (!uri) throw new Error('a PAC file location must be specified!');
if (!opts) opts = {};
if (!uri) throw new Error('a PAC file URI must be specified!');
debug('creating PacProxyAgent with URI %o and options %o', uri, opts);
Agent.call(this, connect);
// if `true`, then connect to the destination endpoint over TLS, defaults to `false`
this.secureEndpoint = Boolean(opts.secureEndpoint);
// strip the "pac+" prefix

@@ -80,2 +85,4 @@ this.uri = uri.replace(/^pac\+/i, '');

this.proxy = opts;
this.cache = this._resolver = null;

@@ -143,3 +150,3 @@ }

PacProxyAgent.prototype.loadPacFile = function (fn) {
debug('loading PAC file: %j', this.uri);
debug('loading PAC file: %o', this.uri);
var self = this;

@@ -158,9 +165,8 @@

self.cache = rs;
toArray(rs, onarray);
toBuffer(rs, onbuffer);
}
function onarray (err, arr) {
function onbuffer (err, buf) {
if (err) return fn(err);
var buf = Buffer.concat(arr);
debug('read %d byte PAC file from URI', buf.length);
debug('read %o byte PAC file from URI', buf.length);
fn(null, buf.toString('utf8'));

@@ -180,2 +186,3 @@ }

var self = this;
var secure = Boolean(opts.secureEndpoint);

@@ -191,3 +198,2 @@ // first we need get a generated FindProxyForURL() function,

// calculate the `url` parameter
var secure = self.secureEndpoint;
var defaultPort = secure ? 443 : 80;

@@ -217,3 +223,3 @@ var path = req.path;

debug('url: %j, host: %j', url, host);
debug('url: %o, host: %o', url, host);
FindProxyForURL(url, host, onproxy);

@@ -229,7 +235,7 @@ }

var proxies = String(proxy).trim().split(/\b\s*;\s*?\b/);
var proxies = String(proxy).trim().split(/\s*;\s*/g).filter(Boolean);
// XXX: right now, only the first proxy specified will be used
var first = proxies[0];
debug('using proxy: "%s"', first);
debug('using proxy: %o', first);

@@ -239,3 +245,2 @@ var agent;

var type = parts[0];
var secure = self.secureEndpoint;

@@ -251,12 +256,15 @@ if ('DIRECT' == type) {

return fn(null, socket);
} else if ('PROXY' == type) {
// use an HTTP proxy
agent = ProxyAgent('http://' + parts[1], secure);
} else if ('HTTPS' == type) {
// use an HTTPS proxy
// http://dev.chromium.org/developers/design-documents/secure-web-proxy
agent = ProxyAgent('https://' + parts[1], secure);
} else if ('SOCKS' == type) {
// use a SOCKS proxy
agent = ProxyAgent('socks://' + parts[1], secure);
agent = new SocksProxyAgent('socks://' + parts[1]);
} else if ('PROXY' == type || 'HTTPS' == type) {
// use an HTTP or HTTPS proxy
// http://dev.chromium.org/developers/design-documents/secure-web-proxy
var proxyURL = ('HTTPS' === type ? 'https' : 'http') + '://' + parts[1];
var proxy = extend({}, self.proxy, parse(proxyURL));
if (secure) {
agent = new HttpsProxyAgent(proxy);
} else {
agent = new HttpProxyAgent(proxy);
}
} else {

@@ -263,0 +271,0 @@ throw new Error('Unknown proxy type: ' + type);

{
"name": "pac-proxy-agent",
"version": "0.2.0",
"version": "1.0.0",
"description": "A PAC file proxy `http.Agent` implementation for HTTP",

@@ -30,13 +30,17 @@ "main": "index.js",

"dependencies": {
"agent-base": "~1.0.1",
"extend": "~1.2.1",
"agent-base": "2",
"debug": "2",
"extend": "3",
"get-uri": "1",
"http-proxy-agent": "1",
"https-proxy-agent": "1",
"pac-resolver": "~1.2.1",
"proxy-agent": "1",
"get-uri": "~0.1.0",
"stream-to-array": "~1.0.0",
"debug": "2"
"socks-proxy-agent": "2",
"stream-to-buffer": "0.1.0"
},
"devDependencies": {
"mocha": "~1.16.2"
"mocha": "2",
"proxy": "0.2.3",
"socksv5": "0.0.6"
}
}
pac-proxy-agent
===============
### A [PAC file][pac-wikipedia] proxy `http.Agent` implementation for HTTP and HTTPS
[![Build Status](https://travis-ci.org/TooTallNate/node-pac-proxy-agent.png?branch=master)](https://travis-ci.org/TooTallNate/node-pac-proxy-agent)
[![Build Status](https://travis-ci.org/TooTallNate/node-pac-proxy-agent.svg?branch=master)](https://travis-ci.org/TooTallNate/node-pac-proxy-agent)

@@ -6,0 +6,0 @@ This module provides an `http.Agent` implementation that retreives the specified

@@ -6,25 +6,303 @@

var fs = require('fs');
var url = require('url');
var http = require('http');
var https = require('https');
var assert = require('assert');
var toBuffer = require('stream-to-buffer');
var Proxy = require('proxy');
var socks = require('socksv5');
var PacProxyAgent = require('../');
describe('PacProxyAgent', function () {
// target servers
var httpServer, httpPort;
var httpsServer, httpsPort;
describe('"file" transport', function () {
it('should work', function () {
// proxy servers
var socksServer, socksPort;
var proxyServer, proxyPort;
var proxyHttpsServer, proxyHttpsPort;
before(function (done) {
// setup target HTTP server
httpServer = http.createServer();
httpServer.listen(function () {
httpPort = httpServer.address().port;
done();
});
});
describe('"http" transport', function () {
it('should work', function () {
before(function (done) {
// setup target SSL HTTPS server
var options = {
key: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.key'),
cert: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.pem')
};
httpsServer = https.createServer(options);
httpsServer.listen(function () {
httpsPort = httpsServer.address().port;
done();
});
});
describe('"https" transport', function () {
it('should work', function () {
before(function (done) {
// setup SOCKS proxy server
socksServer = socks.createServer(function(info, accept, deny) {
accept();
});
socksServer.listen(function() {
socksPort = socksServer.address().port;
done();
});
socksServer.useAuth(socks.auth.None());
});
before(function (done) {
// setup HTTP proxy server
proxyServer = Proxy();
proxyServer.listen(function () {
proxyPort = proxyServer.address().port;
done();
});
});
before(function (done) {
// setup SSL HTTPS proxy server
var options = {
key: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.key'),
cert: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.pem')
};
proxyHttpsServer = Proxy(https.createServer(options));
proxyHttpsServer.listen(function () {
proxyHttpsPort = proxyHttpsServer.address().port;
done();
});
});
after(function (done) {
socksServer.once('close', function () { done(); });
socksServer.close();
});
after(function (done) {
httpServer.once('close', function () { done(); });
httpServer.close();
});
after(function (done) {
httpsServer.once('close', function () { done(); });
httpsServer.close();
});
after(function (done) {
proxyServer.once('close', function () { done(); });
proxyServer.close();
});
after(function (done) {
proxyHttpsServer.once('close', function () { done(); });
proxyHttpsServer.close();
});
describe('constructor', function () {
it('should throw an Error if no "proxy" argument is given', function () {
assert.throws(function () {
new PacProxyAgent();
});
});
it('should accept a "string" proxy argument', function () {
var agent = new PacProxyAgent('pac+ftp://example.com/proxy.pac');
assert.equal('ftp://example.com/proxy.pac', agent.uri);
});
it('should accept a `url.parse()` result object argument', function () {
var opts = url.parse('pac+ftp://example.com/proxy.pac');
var agent = new PacProxyAgent(opts);
assert.equal('ftp://example.com/proxy.pac', agent.uri);
});
it('should accept a `uri` on the options object', function () {
var agent = new PacProxyAgent({ uri: 'pac+ftp://example.com/proxy.pac' });
assert.equal('ftp://example.com/proxy.pac', agent.uri);
});
});
describe('"http" module', function () {
it('should work over an HTTP proxy', function (done) {
httpServer.once('request', function (req, res) {
res.end(JSON.stringify(req.headers));
});
function FindProxyForURL(url, host) {
return "PROXY 127.0.0.1:PORT;"
}
var uri = 'data:,' + encodeURIComponent(FindProxyForURL.toString().replace('PORT', proxyPort));
var agent = new PacProxyAgent(uri);
var opts = url.parse('http://127.0.0.1:' + httpPort + '/test');
opts.agent = agent;
var req = http.get(opts, function (res) {
toBuffer(res, function (err, buf) {
if (err) return done(err);
var data = JSON.parse(buf.toString('utf8'));
assert.equal('127.0.0.1:' + httpPort, data.host);
assert('via' in data);
done();
});
});
req.once('error', done);
});
it('should work over an HTTPS proxy', function (done) {
httpServer.once('request', function (req, res) {
res.end(JSON.stringify(req.headers));
});
function FindProxyForURL(url, host) {
return "HTTPS 127.0.0.1:PORT;"
}
var uri = 'data:,' + encodeURIComponent(FindProxyForURL.toString().replace('PORT', proxyHttpsPort));
var proxy = url.parse(uri);
proxy.rejectUnauthorized = false;
var agent = new PacProxyAgent(proxy);
var opts = url.parse('http://127.0.0.1:' + httpPort + '/test');
opts.agent = agent;
var req = http.get(opts, function (res) {
toBuffer(res, function (err, buf) {
if (err) return done(err);
var data = JSON.parse(buf.toString('utf8'));
assert.equal('127.0.0.1:' + httpPort, data.host);
assert('via' in data);
done();
});
});
req.once('error', done);
});
it('should work over a SOCKS proxy', function (done) {
httpServer.once('request', function (req, res) {
res.end(JSON.stringify(req.headers));
});
function FindProxyForURL(url, host) {
return "SOCKS 127.0.0.1:PORT;"
}
var uri = 'data:,' + encodeURIComponent(FindProxyForURL.toString().replace('PORT', socksPort));
var agent = new PacProxyAgent(uri);
var opts = url.parse('http://127.0.0.1:' + httpPort + '/test');
opts.agent = agent;
var req = http.get(opts, function (res) {
toBuffer(res, function (err, buf) {
if (err) return done(err);
var data = JSON.parse(buf.toString('utf8'));
assert.equal('127.0.0.1:' + httpPort, data.host);
done();
});
});
req.once('error', done);
});
});
describe('"https" module', function () {
it('should work over an HTTP proxy', function (done) {
httpsServer.once('request', function (req, res) {
res.end(JSON.stringify(req.headers));
});
function FindProxyForURL(url, host) {
return "PROXY 127.0.0.1:PORT;"
}
var uri = 'data:,' + encodeURIComponent(FindProxyForURL.toString().replace('PORT', proxyPort));
var agent = new PacProxyAgent(uri);
var opts = url.parse('https://127.0.0.1:' + httpsPort + '/test');
opts.agent = agent;
opts.rejectUnauthorized = false;
var req = https.get(opts, function (res) {
toBuffer(res, function (err, buf) {
if (err) return done(err);
var data = JSON.parse(buf.toString('utf8'));
assert.equal('127.0.0.1:' + httpsPort, data.host);
done();
});
});
req.once('error', done);
});
it('should work over an HTTPS proxy', function (done) {
var gotReq = false;
httpsServer.once('request', function (req, res) {
gotReq = true;
res.end(JSON.stringify(req.headers));
});
function FindProxyForURL(url, host) {
return "HTTPS 127.0.0.1:PORT;"
}
var uri = 'data:,' + encodeURIComponent(FindProxyForURL.toString().replace('PORT', proxyHttpsPort));
var agent = new PacProxyAgent(uri, {
rejectUnauthorized: false
});
var opts = url.parse('https://127.0.0.1:' + httpsPort + '/test');
opts.agent = agent;
opts.rejectUnauthorized = false;
var req = https.get(opts, function (res) {
toBuffer(res, function (err, buf) {
if (err) return done(err);
var data = JSON.parse(buf.toString('utf8'));
assert.equal('127.0.0.1:' + httpsPort, data.host);
assert(gotReq);
done();
});
});
req.once('error', done);
});
it('should work over a SOCKS proxy', function (done) {
var gotReq = false;
httpsServer.once('request', function (req, res) {
gotReq = true;
res.end(JSON.stringify(req.headers));
});
function FindProxyForURL(url, host) {
return "SOCKS 127.0.0.1:PORT;"
}
var uri = 'data:,' + encodeURIComponent(FindProxyForURL.toString().replace('PORT', socksPort));
var agent = new PacProxyAgent(uri);
var opts = url.parse('https://127.0.0.1:' + httpsPort + '/test');
opts.agent = agent;
opts.rejectUnauthorized = false;
var req = https.get(opts, function (res) {
toBuffer(res, function (err, buf) {
if (err) return done(err);
var data = JSON.parse(buf.toString('utf8'));
assert.equal('127.0.0.1:' + httpsPort, data.host);
assert(gotReq);
done();
});
});
req.once('error', done);
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc