blob: 0ea724279cbbad17afed3cbd68e5dbb0077430ea [file] [log] [blame]
/**
* Module dependencies.
*/
var co = require('co');
var vm = require('vm');
var thunkify = require('thunkify');
var degenerator = require('degenerator');
/**
* Built-in PAC functions.
*/
var dateRange = require('./dateRange');
var dnsDomainIs = require('./dnsDomainIs');
var dnsDomainLevels = require('./dnsDomainLevels');
var dnsResolve = require('./dnsResolve');
var isInNet = require('./isInNet');
var isPlainHostName = require('./isPlainHostName');
var isResolvable = require('./isResolvable');
var localHostOrDomainIs = require('./localHostOrDomainIs');
var myIpAddress = require('./myIpAddress');
var shExpMatch = require('./shExpMatch');
var timeRange = require('./timeRange');
var weekdayRange = require('./weekdayRange');
/**
* Module exports.
*/
module.exports = generate;
/**
* Returns an asyncronous `FindProxyForURL` function from the
* given JS string (from a PAC file).
*
* @param {String} str JS string
* @param {Object} opts optional "options" object
* @return {Function} async resolver function
*/
function generate (str, opts) {
var i;
// the sandbox to use for the vm
var sandbox = {
dateRange: dateRange,
dnsDomainIs: dnsDomainIs,
dnsDomainLevels: dnsDomainLevels,
dnsResolve: dnsResolve,
isInNet: isInNet,
isPlainHostName: isPlainHostName,
isResolvable: isResolvable,
localHostOrDomainIs: localHostOrDomainIs,
myIpAddress: myIpAddress,
shExpMatch: shExpMatch,
timeRange: timeRange,
weekdayRange: weekdayRange
};
// copy the properties from the user-provided `sandbox` onto ours
if (opts && opts.sandbox) {
for (i in opts.sandbox) {
sandbox[i] = opts.sandbox[i];
}
}
// construct the array of async function names to add `yield` calls to.
// user-provided async functions added to the `sandbox` must have an
// `async = true` property set on the function instance
var names = [];
for (i in sandbox) {
if (sandbox[i].async) {
names.push(i);
sandbox[i] = thunkify(sandbox[i]);
}
}
//console.log(names);
// convert the JS FindProxyForURL function into a generator function
var js = degenerator(str, names);
// filename of the pac file for the vm
var filename = opts && opts.filename ? opts.filename : 'proxy.pac';
// evaluate the JS string and extract the FindProxyForURL generator function
var fn = vm.runInNewContext(js + ';FindProxyForURL', sandbox, filename);
if ('function' != typeof fn) {
throw new TypeError('PAC file JavaScript contents must define a `FindProxyForURL` function');
}
// return the async resolver function
var resolver = co(fn);
return function FindProxyForURL (url, host, fn) {
resolver(url, host, fn);
};
}