refactored

This commit is contained in:
Ilya Ig. Petrov 2015-11-28 14:20:45 +05:00
parent 2000a3020d
commit 00d23d0292
35 changed files with 688 additions and 693 deletions

View File

@ -44,4 +44,34 @@ blocked-ips-switch.js: 30 bytes, 1339607 ns, Missed: 84 bytes,
blocked-ips-binary.js: 31 bytes, 3552007 ns, Missed: 76 bytes, 603872 ns
======================
blocked-hosts-binary-trie.js: 364 bytes, 27134555ns, Missed: 218 bytes, 725467 ns
blocked-hosts-simple-trie.js: 364 bytes, 4085395 ns, Missed: 219 bytes, 649011 ns
blocked-hosts-simple-trie.js: 364 bytes, 4085395 ns, Missed: 219 bytes, 649011 ns
======================
blocked-hosts-plain-switch.js: 69 bytes, 2850095 ns, Missed: 96 bytes, 590933 ns
blocked-hosts-switch.js: 93 bytes, 854636 ns, Missed: 77 bytes, 597410 ns
blocked-hosts-reversed-binary.js: 109 bytes, 3710108 ns, Missed: 96 bytes, 604745 ns
blocked-hosts-hash.js: 351 bytes, 5112411 ns, Missed: 203 bytes, 605303 ns
blocked-hosts-binary.js: 355 bytes, 3691874 ns, Missed: 207 bytes, 615506 ns
blocked-ips-binary.js: 33 bytes, 3558958 ns, Missed: 81 bytes, 607783 ns
blocked-ips-indexOf.js: 35 bytes, 4832252 ns, Missed: 77 bytes, 593958 ns
blocked-ips-switch.js: 36 bytes, 1341637 ns, Missed: 76 bytes, 613332 ns
======================
blocked-hosts-binary.js: 356 bytes, 3763269 ns, Missed: 211 bytes, 595469 ns
blocked-hosts-plain-switch.js: 364 bytes, 2865722 ns, Missed: 223 bytes, 597233 ns
blocked-hosts-reversed-binary.js: 106 bytes, 3680757 ns, Missed: 96 bytes, 604607 ns
blocked-hosts-switch.js: 93 bytes, 865423 ns, Missed: 81 bytes, 606328 ns
blocked-hosts-hash.js: 347 bytes, 5163575 ns, Missed: 207 bytes, 607421 ns
blocked-ips-indexOf.js: 33 bytes, 4845498 ns, Missed: 77 bytes, 594833 ns
blocked-ips-switch.js: 35 bytes, 1345531 ns, Missed: 77 bytes, 601800 ns
blocked-ips-binary.js: 38 bytes, 3575806 ns, Missed: 80 bytes, 608611 ns
======================
blocked-hosts-reversed-binary.js: 109 bytes, 3704594 ns, Missed: 96 bytes, 602820 ns
blocked-hosts-binary.js: 351 bytes, 3718253 ns, Missed: 210 bytes, 605188 ns
blocked-hosts-plain-switch.js: 367 bytes, 2874843 ns, Missed: 88 bytes, 607200 ns
blocked-hosts-hash.js: 347 bytes, 5062512 ns, Missed: 207 bytes, 609278 ns
blocked-hosts-switch.js: 88 bytes, 894410 ns, Missed: 77 bytes, 614169 ns
blocked-ips-switch.js: 37 bytes, 1348111 ns, Missed: 72 bytes, 597439 ns
blocked-ips-indexOf.js: 35 bytes, 4853437 ns, Missed: 72 bytes, 599850 ns
blocked-ips-binary.js: 31 bytes, 3542401 ns, Missed: 77 bytes, 602958 ns

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,414 +0,0 @@
var fs = require('fs');
var input = fs.readFileSync('dump.csv').toString();
var outputDir = 'generated-PACs';
try {
fs.mkdirSync( outputDir );
} catch(e) {
if ( e.code != 'EEXIST' ) throw e;
}
var punycode = require('punycode')
/*
CVS Format:
IP(s);host(s);URL(s);organization(s);reason;yyyy-mm-dd
* multiple values are joind by " | "
* url may have wierd protocol, e.g.: Newcamd525://
*/
var columnsSep = ';';
var valuesSep = /\s*\|\s*/g;
var ips = [], hosts = [], urls = [], orgs = [], date, reason;
for(var line of input.trim().split(/\r?\n/g).slice(1)) {
var values = line.split( columnsSep );
var newIps = values.shift().split( valuesSep );
var newHosts = values.shift().split( valuesSep ).map( punycode.toASCII ).map( host => host.replace(/\.+$/g) );
var newUrls = values.shift().split( valuesSep );
var newOrgs = values.shift().split( valuesSep );
var newDate = values.pop();
var newReason = values.join(';');
ips.push.apply(ips, newIps);
hosts.push.apply(hosts, newHosts);
}
function toHash(arr) {
var res = {};
arr.forEach( el => res[el] = true );
return res;
}
var ipsHash = toHash(ips);
var hostsHash = toHash(hosts);
// Remove duplicates and sort.
var ips = Object.keys(ipsHash).sort();
var hosts = Object.keys(hostsHash).sort();
function FindProxyForURL(url, host) {
// ProstoVPN.AntiZapret PAC-ip File
// Generated on Sun Nov 22 10:12:29 MSK 2015
// The whole PAC script is reevaluated on each call of this function.
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
// Supported only in Chrome and Firefox.
// http://www.chromium.org/developers/design-documents/secure-web-proxy
// This is to bypass FULL DPI
var isIE = /*@cc_on!@*/!1;
var viaProxy = isIE
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
return IFPROXY() ? viaProxy : 'DIRECT';
}
var pacTemplate = FindProxyForURL.toString();
function stringifyCall() {
var fun = arguments[0];
var args = [].slice.call( arguments, 1 )
.map( a => typeof a !== 'string' ? JSON.stringify(a) : a ).join(', ');
return '('+fun+')('+args+')';
}
function produceOutput() {
var args = [].slice.call( arguments )
var scriptName = args.shift();
var script = pacTemplate
.replace( 'IFPROXY()', stringifyCall.apply(this, args) );
fs.writeFileSync(outputDir +'/'+ scriptName +'.js', script);
}
// BLOCKED IPS ARRAY
function ifProxyByIp(host, blockedIpsArray) {
// Internet Explorer
if (!Array.prototype.indexOf)
Array.prototype.indexOf = function(obj, start) {
for (var i = (start || 0), j = this.length; i < j; i++)
if (this[i] === obj) return i;
return -1;
}
return blockedIpsArray.indexOf( dnsResolve(host) ) !== -1
}
produceOutput('blocked-ips-indexOf', ifProxyByIp, 'host', ips);
// BLOCKED IPS SWITCH
function ifProxyBySwitch(host) {
switch( dnsResolve(host) ) {
/*{CASES}*/
default:
return false;
}
}
var cases = ips.map( ip => 'case "'+ip+'":' ).join('\n') +'\nreturn true;';
var ifProxySwitchStr = ifProxyBySwitch.toString().replace('/*{CASES}*/', cases);
produceOutput('blocked-ips-switch', ifProxySwitchStr, 'host' );
// BLOCKED IPS BINARY
function ifBinaryFound(target, sortedArray) {
var istart = 0;
var iend = sortedArray.length - 1;
while (istart < iend) {
var imid = istart + Math.floor( (iend - istart)*0.5 );
if (target > sortedArray[imid])
istart = imid + 1;
else
iend = imid;
}
return target === sortedArray[iend];
}
produceOutput('blocked-ips-binary', ifBinaryFound, 'dnsResolve(host)', ips);
// BLOCKED HOSTS BINARY
produceOutput('blocked-hosts-binary', ifBinaryFound, 'host', hosts);
// REVERSED BINARY
var reverse = str => str.split('').reverse().join('');
var reversedHosts = hosts.map( reverse ).sort();
function ifReversedBinaryFound(host, sortedArray) {
target = host.split('').reverse().join('');
var istart = 0;
var iend = sortedArray.length - 1;
while (istart < iend) {
var imid = istart + Math.floor( (iend - istart)*0.5 );
if (target > sortedArray[imid])
istart = imid + 1;
else
iend = imid;
}
return dnsDomainIs( host, sortedArray[iend].split('').reverse().join('') );
}
produceOutput('blocked-hosts-reversed-binary', ifReversedBinaryFound, 'host', reversedHosts);
// REVERSED HOSTS SWITCH
function populateTrie(trie, doms) {
var dom = doms.pop();
if (!doms.length || doms.length === 1 && doms[0] === 'www') {
trie[''] = trie[''] || [];
trie[''].push( dom )
return trie;
}
if (trie[''] && trie[''].indexOf(dom) !== -1) // Subdomain of a blocked domain.
return trie;
trie[dom] = trie[dom] || {};
populateTrie( trie[dom], doms );
return trie;
}
var trie = {};
for(var host of hosts) {
var doms = host.split('.');
populateTrie(trie, doms);
}
function trieToSwitch(trie, indent) {
var _indent = indent || '';
var indent = _indent + ' ';
var keys = Object.keys(trie).sort();
if (!trie[''] && keys.length === 1) {
var key = keys[0];
return _indent + 'if (doms.pop() === "'+key+'")\n'+ trieToSwitch(trie[key], indent);
}
var cases = '';
if (trie['']) {
var values = trie[''].sort();
if (values.length === 1 && keys.length === 1)
return _indent + 'return doms.pop() === "'+values[0]+'";\n';
cases =
values.filter( v => v ).map( val => indent +'case "'+val+'":\n' ).join('') + indent +' return true;\n';
delete trie[''];
keys = Object.keys(trie).sort();
}
cases += keys.filter( k => k ).map(
key => {
var tmp = trieToSwitch( trie[key], indent+' ');
if (!/^\s*return/.test(tmp))
tmp += indent+' break;\n';
return indent +'case "'+key+'":\n' +tmp;
}
).join('');
return ''
+ _indent +'switch( doms.pop() ) {\n'
+ cases
+ _indent +'}\n';
}
function ifProxyByTrie(host) {
//SWITCH
return false;
}
var ifProxyByTrieStr = ifProxyByTrie.toString().replace('//SWITCH', trieToSwitch(trie, ' '));
produceOutput('blocked-hosts-switch', ifProxyByTrieStr, 'host' );
/* REVERSED HOSTS BINARY TRIE
function populateBinTrie(trie, doms) {
var dom = doms.pop();
if (!doms.length || doms.length === 1 && doms[0] === 'www') {
trie[dom] = 'blocked';
return trie;
}
if (trie[dom] === 'blocked') // Subdomain of a blocked domain.
return trie;
trie[dom] = trie[dom] || {};
populateBinTrie( trie[dom], doms );
return trie;
}
var trie = {};
for(var host of hosts) {
var doms = host.split('.');
populateBinTrie(trie, doms);
}
function trie2sorted(trie) {
if (trie === 'blocked')
return trie;
var keys = Object.keys(trie).sort();
return keys.map( key => trie[key] !== 'blocked' ? [ key, trie2sorted( trie[key] ) ] : [key] );
}
var sortedTrie = trie2sorted(trie);
function ifProxyByBinTrie(host, sortedTrie) {
var doms = host.split('.');
function ifBinaryBlocked(sortedTrie) {
var target = doms.pop();
if (!target)
return false;
var istart = 0;
var iend = sortedTrie.length - 1;
while (istart < iend) {
var imid = istart + Math.floor( (iend - istart)*0.5 );
if (target > sortedTrie[imid][0])
istart = imid + 1;
else
iend = imid;
}
if (target !== sortedTrie[iend][0])
return false;
return sortedTrie[iend].length < 2 ? true : ifBinaryBlocked( sortedTrie[iend][1] );
}
return ifBinaryBlocked(sortedTrie)
}
produceOutput('blocked-hosts-binary-trie', ifProxyByBinTrie, 'host', sortedTrie);
*/
// BLOCKED HOSTS PLAIN SWITCH
function ifProxyByPlainSwitch(host) {
function ifBlocked(host) {
switch( host ) {
//CASES
}
return false;
}
var doms = host.split('.');
for( var endi = doms.length-1; endi >= 0; --endi )
if (ifBlocked( doms.slice( endi ).join('.') ))
return true;
return false;
}
var cases = hosts.map( host => 'case "'+host+'":' ).join('\n') +'\nreturn true;';
var tmp = ifProxyByPlainSwitch.toString().replace('//CASES', cases);
produceOutput( 'blocked-hosts-plain-switch', tmp, 'host' );
// SIMPLY TRIE
function populateSimpleTrie(trie, letters) {
if (!letters.length || !trie)
return trie;
var letter = letters.shift();
if (!letters.length) {
trie[letter] = ['', false];
return trie;
}
if (trie[letter] === ['', false]) // Subdomain of a blocked domain.
return trie;
if (!trie[letter]) {
trie[letter] = [letters.join(''), false]
return trie;
}
var arr = trie[letter];
var link = arr[0].split('');
var linkTrie = arr[1];
function commonPrefix(wa, wb) {
var len = Math.min(wa.length, wb.length);
var i = -1;
while(++i < len)
if (wa[i] !== wb[i])
break;
return wa.slice(0, i)
}
var prefix = commonPrefix(link, letters);
var suffixLetters = letters.slice(prefix.length);
var suffixLink = link.slice(prefix.length);
var newTrie = {};
if (!suffixLink.length)
var newTrie = linkTrie;
if (!suffixLetters.length)
var newTrie = false;
if (newTrie) {
newTrie = populateSimpleTrie( newTrie, suffixLetters );
newTrie = populateSimpleTrie( newTrie, suffixLink );
}
trie[letter] = [prefix.join(''), newTrie];
return trie;
}
var simpleTrie = {};
for(var host of hosts)
populateSimpleTrie(simpleTrie, host.split('').reverse());
function ifProxyBySimpleTrie(host, simpleTrie) {
var letters = host.split('').reverse();
while(letters.length) {
var letter = letters.shift();
var arr = simpleTrie[letter];
var link = arr[0];
if (link.length > letters.length)
return false;
for( var i=0; i < link.length; ++i )
if ( letters[i] !== link.charAt(i) )
return false;
letters = letters.slice(link.length);
simpleTrie = arr[1];
if (!simpleTrie)
return true;
}
}
produceOutput('blocked-hosts-simple-trie', ifProxyBySimpleTrie, 'host', simpleTrie);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

Can't render this file because it is too large.

29
pac-generator/generate-PACs.js Executable file
View File

@ -0,0 +1,29 @@
'use strict';
var generator = require('./pac-generator');
var normalizedPath = require('path').join(__dirname, 'src');
var outputDir = './generated-PACs';
var fs = require('fs')
try {
fs.mkdirSync( outputDir );
} catch(e) {
if ( e.code != 'EEXIST' ) throw e;
}
fs.readdirSync( normalizedPath )
.filter( file => file.startsWith('blocked-') )
.forEach( file =>
require('./src/'+ file)(
generator.hosts,
generator.ips,
generator,
function generatePac() {
var args = [].slice.call( arguments );
args.unshift( outputDir +'/'+ file )
generator.writeOutputToFile.apply( generator, args );
}
)
);

File diff suppressed because one or more lines are too long

View File

@ -1,24 +1,24 @@
function FindProxyForURL(url, host) {
// ProstoVPN.AntiZapret PAC-ip File
// Generated on Sun Nov 22 10:12:29 MSK 2015
// The whole PAC script is reevaluated on each call of this function.
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
// Supported only in Chrome and Firefox.
// http://www.chromium.org/developers/design-documents/secure-web-proxy
// This is to bypass FULL DPI
var isIE = /*@cc_on!@*/!1;
var viaProxy = isIE
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
return (function ifProxyByPlainSwitch(host) {
function ifBlocked(host) {
switch( host ) {
function FindProxyForURL(url, host) {
// ProstoVPN.AntiZapret PAC-ip File
// Generated on Sun Nov 22 10:12:29 MSK 2015
// The whole PAC script is reevaluated on each call of this function.
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
// Supported only in Chrome and Firefox.
// http://www.chromium.org/developers/design-documents/secure-web-proxy
// This is to bypass FULL DPI
var isIE = /*@cc_on!@*/!1;
var viaProxy = isIE
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
return (function ifProxyByPlainSwitch(host) {
function ifBlocked(host) {
switch( host ) {
case "03magnet.ru":
case "0chan.cc":
case "1-kino.com":
@ -9842,16 +9842,16 @@ case "zubromix.com":
case "zubrrotzdg2m2uy7.onion.to":
case "zuu9ieth.cserver.tv":
case "zz.jofra.biz":
return true;
}
return false;
}
var doms = host.split('.');
for( var endi = doms.length-1; endi >= 0; --endi )
if (ifBlocked( doms.slice( endi ).join('.') ))
return true;
return false;
})(host) ? viaProxy : 'DIRECT';
return true;
}
return false;
}
var doms = host.split('.');
for( var endi = doms.length-1; endi >= 0; --endi )
if (ifBlocked( doms.slice( endi ).join('.') ))
return true;
return false;
})(host) ? viaProxy : 'DIRECT';
}

File diff suppressed because one or more lines are too long

View File

@ -1,21 +1,22 @@
function FindProxyForURL(url, host) {
// ProstoVPN.AntiZapret PAC-ip File
// Generated on Sun Nov 22 10:12:29 MSK 2015
// The whole PAC script is reevaluated on each call of this function.
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
// Supported only in Chrome and Firefox.
// http://www.chromium.org/developers/design-documents/secure-web-proxy
// This is to bypass FULL DPI
var isIE = /*@cc_on!@*/!1;
var viaProxy = isIE
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
return (function ifProxyByTrie(host) {
function FindProxyForURL(url, host) {
// ProstoVPN.AntiZapret PAC-ip File
// Generated on Sun Nov 22 10:12:29 MSK 2015
// The whole PAC script is reevaluated on each call of this function.
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
// Supported only in Chrome and Firefox.
// http://www.chromium.org/developers/design-documents/secure-web-proxy
// This is to bypass FULL DPI
var isIE = /*@cc_on!@*/!1;
var viaProxy = isIE
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
return (function ifProxyByTrie(host) {
var doms = host.split('.');
switch( doms.pop() ) {
case "102":
if (doms.pop() === "120")
@ -10124,7 +10125,7 @@ function FindProxyForURL(url, host) {
}
break;
}
return false;
})(host) ? viaProxy : 'DIRECT';
return false;
})(host) ? viaProxy : 'DIRECT';
}

File diff suppressed because one or more lines are too long

View File

@ -1,22 +1,22 @@
function FindProxyForURL(url, host) {
// ProstoVPN.AntiZapret PAC-ip File
// Generated on Sun Nov 22 10:12:29 MSK 2015
// The whole PAC script is reevaluated on each call of this function.
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
// Supported only in Chrome and Firefox.
// http://www.chromium.org/developers/design-documents/secure-web-proxy
// This is to bypass FULL DPI
var isIE = /*@cc_on!@*/!1;
var viaProxy = isIE
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
return (function ifProxyBySwitch(host) {
switch( dnsResolve(host) ) {
function FindProxyForURL(url, host) {
// ProstoVPN.AntiZapret PAC-ip File
// Generated on Sun Nov 22 10:12:29 MSK 2015
// The whole PAC script is reevaluated on each call of this function.
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
// Supported only in Chrome and Firefox.
// http://www.chromium.org/developers/design-documents/secure-web-proxy
// This is to bypass FULL DPI
var isIE = /*@cc_on!@*/!1;
var viaProxy = isIE
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
return (function ifProxyBySwitch(host) {
switch( dnsResolve(host) ) {
case "101.1.29.82":
case "103.21.58.156":
case "103.240.151.25":
@ -9540,9 +9540,8 @@ case "98.139.135.198":
case "98.142.213.26":
case "99.192.182.57":
case "99.198.117.212":
return true;
default:
return false;
}
})(host) ? viaProxy : 'DIRECT';
return true;
}
return false;
})(host) ? viaProxy : 'DIRECT';
}

95
pac-generator/pac-generator.js Executable file
View File

@ -0,0 +1,95 @@
'use strict';
var fs = require('fs');
var input = fs.readFileSync('dump.csv').toString();
var punycode = require('punycode')
/*
CVS Format:
IP(s);host(s);URL(s);organization(s);reason;yyyy-mm-dd
* multiple values are joind by " | "
* url may have wierd protocol, e.g.: Newcamd525://
*/
var columnsSep = ';';
var valuesSep = /\s*\|\s*/g;
var ips = [], hosts = [], urls = [], orgs = [], date, reason;
for(var line of input.trim().split(/\r?\n/g).slice(1)) {
var values = line.split( columnsSep );
var newIps = values.shift().split( valuesSep );
var newHosts = values.shift().split( valuesSep ).map( punycode.toASCII ).map( host => host.replace(/\.+$/g) );
var newUrls = values.shift().split( valuesSep );
var newOrgs = values.shift().split( valuesSep );
var newDate = values.pop();
var newReason = values.join(';');
ips.push.apply(ips, newIps);
hosts.push.apply(hosts, newHosts);
}
function toHash(arr) {
var res = {};
arr.forEach( el => res[el] = true );
return res;
}
var ipsHash = toHash(ips);
var hostsHash = toHash(hosts);
// Remove duplicates and sort.
var ips = Object.keys(ipsHash).sort();
var hosts = Object.keys(hostsHash).sort();
function FindProxyForURL(url, host) {
// ProstoVPN.AntiZapret PAC-ip File
// Generated on Sun Nov 22 10:12:29 MSK 2015
// The whole PAC script is reevaluated on each call of this function.
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
// Supported only in Chrome and Firefox.
// http://www.chromium.org/developers/design-documents/secure-web-proxy
// This is to bypass FULL DPI
var isIE = /*@cc_on!@*/!1;
var viaProxy = isIE
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
return IFPROXY() ? viaProxy : 'DIRECT';
}
var pacTemplate = FindProxyForURL.toString();
function stringifyCall() {
var args = [].slice.call( arguments );
var fun = args.shift();
var args = args
.map( a => typeof a !== 'string' ? JSON.stringify(a) : a ).join(', ');
return '('+fun+')('+args+')';
}
function ifProxy2pac() {
return pacTemplate.replace( 'IFPROXY()', stringifyCall.apply(this, arguments) );
}
function writeOutputToFile() {
var args = [].slice.call( arguments );
var scriptPath = args.shift();
var pac = ifProxy2pac.apply(this, args);
fs.writeFileSync( scriptPath, pac);
}
module.exports = {
hosts: hosts,
ips: ips,
stringifyCall: stringifyCall,
writeOutputToFile: writeOutputToFile,
}

15
pac-generator/package.json Executable file
View File

@ -0,0 +1,15 @@
{
"name": "subjective-good-is-evil",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node generate-PACs.js",
"serve": "http-server generated-PACs"
},
"author": "ilyaigpetrov",
"license": "ISC",
"devDependencies": {
"http-server": "^0.8.5"
}
}

View File

@ -0,0 +1,85 @@
'use strict';
module.exports = (hosts, ips, generator, generatePac) => {
function populateSimpleTrie(trie, letters) {
if (!letters.length || !trie)
return trie;
var letter = letters.shift();
if (!letters.length) {
trie[letter] = ['', false];
return trie;
}
if (trie[letter] === ['', false]) // Subdomain of a blocked domain.
return trie;
if (!trie[letter]) {
trie[letter] = [letters.join(''), false]
return trie;
}
var arr = trie[letter];
var link = arr[0].split('');
var linkTrie = arr[1];
function commonPrefix(wa, wb) {
var len = Math.min(wa.length, wb.length);
var i = -1;
while(++i < len)
if (wa[i] !== wb[i])
break;
return wa.slice(0, i)
}
var prefix = commonPrefix(link, letters);
var suffixLetters = letters.slice(prefix.length);
var suffixLink = link.slice(prefix.length);
var newTrie = {};
if (!suffixLink.length)
var newTrie = linkTrie;
if (!suffixLetters.length)
var newTrie = false;
if (newTrie) {
newTrie = populateSimpleTrie( newTrie, suffixLetters );
newTrie = populateSimpleTrie( newTrie, suffixLink );
}
trie[letter] = [prefix.join(''), newTrie];
return trie;
}
var simpleTrie = {};
for(var host of hosts)
populateSimpleTrie(simpleTrie, host.split('').reverse());
function ifProxyBySimpleTrie(host, simpleTrie) {
var letters = host.split('').reverse();
while(letters.length) {
var letter = letters.shift();
var arr = simpleTrie[letter];
var link = arr[0];
if (link.length > letters.length)
return false;
for( var i=0; i < link.length; ++i )
if ( letters[i] !== link.charAt(i) )
return false;
letters = letters.slice(link.length);
simpleTrie = arr[1];
if (!simpleTrie)
return true;
}
}
return generatePac( ifProxyBySimpleTrie, 'host', simpleTrie );
}

View File

@ -0,0 +1,3 @@
'use strict';
module.exports = (hosts, ips, generator, generatePac) => generatePac( require('./ifBinaryFound'), 'host', hosts );

View File

@ -0,0 +1,12 @@
'use strict';
module.exports = (hosts, ips, generator, generatePac) => {
var hostsHash = {'': true};
hosts.forEach( host => hostsHash[host] = true );
function ifProxyByHash(host, hostsHash) {
while(!hostsHash[host])
host = (host+'.').replace(/^\w*\./g);
return host.length !== 0;
}
return generatePac( ifProxyByHash, 'host', hostsHash )
};

View File

@ -0,0 +1,27 @@
'use strict';
module.exports = (hosts, ips, generator, generatePac) => {
function ifProxyByPlainSwitch(host) {
function ifBlocked(host) {
switch( host ) {
//CASES
}
return false;
}
var doms = host.split('.');
for( var endi = doms.length-1; endi >= 0; --endi )
if (ifBlocked( doms.slice( endi ).join('.') ))
return true;
return false;
}
var cases = hosts.map( host => 'case "'+host+'":' ).join('\n') +'\nreturn true;';
var ifProxyString = ifProxyByPlainSwitch.toString().replace('//CASES', cases);
return generatePac( ifProxyString, 'host' );
}

View File

@ -0,0 +1,25 @@
'use strict';
module.exports = (hosts, ips, generator, generatePac) => {
var reverse = str => str.split('').reverse().join('');
var reversedHosts = hosts.map( reverse ).sort();
function ifReversedBinaryFound(host, sortedArray) {
target = host.split('').reverse().join('');
var istart = 0;
var iend = sortedArray.length - 1;
while (istart < iend) {
var imid = istart + Math.floor( (iend - istart)*0.5 );
if (target > sortedArray[imid])
istart = imid + 1;
else
iend = imid;
}
return dnsDomainIs( host, sortedArray[iend].split('').reverse().join('') );
}
return generatePac( ifReversedBinaryFound, 'host', reversedHosts );
}

View File

@ -0,0 +1,79 @@
'use strict';
module.exports = (hosts, ips, generator, generatePac) => {
function populateTrie(trie, doms) {
var dom = doms.pop();
if (!doms.length || doms.length === 1 && doms[0] === 'www') {
trie[''] = trie[''] || [];
trie[''].push( dom )
return trie;
}
if (trie[''] && trie[''].indexOf(dom) !== -1) // Subdomain of a blocked domain.
return trie;
trie[dom] = trie[dom] || {};
populateTrie( trie[dom], doms );
return trie;
}
var trie = {};
for(var host of hosts) {
var doms = host.split('.');
populateTrie(trie, doms);
}
function trieToSwitch(trie, indent) {
var _indent = indent || '';
var indent = _indent + ' ';
var keys = Object.keys(trie).sort();
if (!trie[''] && keys.length === 1) {
var key = keys[0];
return _indent + 'if (doms.pop() === "'+key+'")\n'+ trieToSwitch(trie[key], indent);
}
var cases = '';
if (trie['']) {
var values = trie[''].sort();
if (values.length === 1 && keys.length === 1)
return _indent + 'return doms.pop() === "'+values[0]+'";\n';
cases =
values.filter( v => v ).map( val => indent +'case "'+val+'":\n' ).join('') + indent +' return true;\n';
delete trie[''];
keys = Object.keys(trie).sort();
}
cases += keys.filter( k => k ).map(
key => {
var tmp = trieToSwitch( trie[key], indent+' ');
if (!/^\s*return/.test(tmp))
tmp += indent+' break;\n';
return indent +'case "'+key+'":\n' +tmp;
}
).join('');
return ''
+ _indent +'switch( doms.pop() ) {\n'
+ cases
+ _indent +'}\n';
}
function ifProxyByTrie(host) {
var doms = host.split('.');
//SWITCH
return false;
}
var ifProxyByTrieStr = ifProxyByTrie.toString().replace('//SWITCH', trieToSwitch(trie, ' '));
return generatePac( ifProxyByTrieStr, 'host' );
}

View File

@ -0,0 +1,3 @@
'use strict';
module.exports = (hosts, ips, generator, generatePac) => generatePac( require('./ifBinaryFound'), 'dnsResolve(host)', ips );

View File

@ -0,0 +1,20 @@
'use strict';
module.exports = (hosts, ips, generator, generatePac) => {
function ifProxyByIp(host, blockedIpsArray) {
// Internet Explorer
if (!Array.prototype.indexOf)
Array.prototype.indexOf = function(obj, start) {
for (var i = (start || 0), j = this.length; i < j; i++)
if (this[i] === obj) return i;
return -1;
}
return blockedIpsArray.indexOf( dnsResolve(host) ) !== -1
}
return generatePac( ifProxyByIp, 'host', ips );
}

View File

@ -0,0 +1,17 @@
'use strict';
module.exports = (hosts, ips, generator, generatePac) => {
function ifProxyBySwitch(host) {
switch( dnsResolve(host) ) {
//CASES
}
return false;
}
var cases = ips.map( ip => 'case "'+ip+'":' ).join('\n') +'\nreturn true;';
var ifProxySwitchStr = ifProxyBySwitch.toString().replace('//CASES', cases);
return generatePac( ifProxySwitchStr, 'host' );
}

View File

@ -0,0 +1,18 @@
'use strict';
function ifBinaryFound(target, sortedArray) {
var istart = 0;
var iend = sortedArray.length - 1;
while (istart < iend) {
var imid = istart + Math.floor( (iend - istart)*0.5 );
if (target > sortedArray[imid])
istart = imid + 1;
else
iend = imid;
}
return target === sortedArray[iend];
}
module.exports = ifBinaryFound;

View File

@ -4,13 +4,11 @@
"description": "",
"main": "index.js",
"scripts": {
"generate": "node generate-PACs.js",
"generate": "cd pac-generator && npm start",
"prestart": "npm run generate",
"preserve": "npm run kill",
"serve": "START /B http-server generated-PACs",
"bench": "cd Benchmark && dnx run ../generated-PACs",
"start": "npm run bench",
"kill": "taskkill /F /IM node.exe"
"start": "npm run bench",
"bench": "cd Benchmark && dnx run ../pac-generator/generated-PACs",
"test": "rm -r pac-generator/generated-PACs"
},
"author": "ilyaigpetrov",
"license": "ISC",

File diff suppressed because one or more lines are too long