forked from zhiyi7/gfw-pac
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pac-template
121 lines (102 loc) · 3.14 KB
/
pac-template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
var proxy = __PROXY__;
var direct = 'DIRECT;';
var cnips = __CN_IPS__;
var directDomains = __DIRECT_DOMAINS__;
var domainsUsingProxy = __DOMAINS__;
var localTlds = __LOCAL_TLDS__;
var hasOwnProperty = Object.hasOwnProperty;
var ipRegExp = new RegExp(/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/);
function convertAddress(ipchars) {
var bytes = ipchars.split('.');
var result = ((bytes[0] & 0xff) << 24) |
((bytes[1] & 0xff) << 16) |
((bytes[2] & 0xff) << 8) |
(bytes[3] & 0xff);
return result;
}
function match(ip) {
var left = 0, right = cnips.length;
do {
var mid = Math.floor((left + right) / 2),
ipf = (ip & cnips[mid][1]) >>> 0,
m = (cnips[mid][0] & cnips[mid][1]) >>> 0;
if (ipf == m) {
return true;
} else if (ipf > m) {
left = mid + 1;
} else {
right = mid;
}
} while (left + 1 <= right)
return false;
}
function testDomain(target, domains, cnRootIncluded) {
var idxA = target.lastIndexOf('.');
var idxB = target.lastIndexOf('.', idxA - 1);
var hasOwnProperty = Object.hasOwnProperty;
var suffix = cnRootIncluded ? target.substring(idxA + 1) : '';
if (suffix === 'cn') {
return true;
}
while (true) {
if (idxB === -1) {
if (hasOwnProperty.call(domains, target)) {
return true;
} else {
return false;
}
}
suffix = target.substring(idxB + 1);
if (hasOwnProperty.call(domains, suffix)) {
return true;
}
idxB = target.lastIndexOf('.', idxB - 1);
}
}
function isLocalTestDomain(domain) {
// Chrome uses .test as testing gTLD.
var tld = domain.substring(domain.lastIndexOf('.'));
if (tld === domain) {
return false;
}
return Object.hasOwnProperty.call(localTlds, tld);
}
/* https://github.com/frenchbread/private-ip */
function isPrivateIp(ip) {
return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
/^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
/^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
/^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
/^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
/^f[cd][0-9a-f]{2}:/i.test(ip) ||
/^fe80:/i.test(ip) ||
/^::1$/.test(ip) ||
/^::$/.test(ip);
}
function FindProxyForURL(url, host) {
if (isPlainHostName(host)
|| isPrivateIp(host)
|| isLocalTestDomain(host)
|| host === 'localhost') {
return direct;
}
if (!ipRegExp.test(host)) {
if (testDomain(host, domainsUsingProxy)) {
return proxy;
}
if (testDomain(host, directDomains, true)) {
return direct
}
strIp = dnsResolve(host);
} else {
strIp = host
}
if (!strIp) {
return proxy;
}
intIp = convertAddress(strIp);
if (match(intIp)) {
return direct;
}
return proxy;
}