GT2/GT2-Android/node_modules/pac-resolver/index.js

144 lines
3.5 KiB
JavaScript
Raw Normal View History

'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)
}