| |
| /** |
| * 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); |
| }; |
| } |