123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- 'use strict';
-
- /**
- * Module dependencies.
- */
-
- var co = require('co');
- var vm = require('vm');
- var parse = require('url').parse;
- 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;
- var str = String(_str)
-
- // 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) || '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.wrap(fn);
-
- return function FindProxyForURL (url, _host, _callback) {
- let host
- let callback
- switch (arguments.length) {
- case 3:
- host = _host
- callback = _callback
- break;
- case 2:
- if (typeof _host === 'function') {
- callback = _host
- } else {
- host = _host
- }
- break;
- }
-
- if (!host) {
- host = parse(url).hostname;
- }
-
- const promise = resolver(url, host, callback);
-
- if (typeof callback === 'function') {
- toCallback(promise, callback)
- } else {
- return promise
- }
- };
- }
-
- function toCallback (promise, callback) {
- let called = false
- function resolve(rtn) {
- if (called) return
- called = true
- callback(null, rtn)
- }
- function reject(err) {
- if (called) return
- called = true
- callback(err)
- }
- promise.then(resolve, reject)
- }
|