mirror of
https://github.com/iBug/pac.git
synced 2025-07-14 05:12:17 +08:00
Add domain checking and pattern matching
This commit is contained in:
parent
12304fe245
commit
cf08e0d840
17
build.py
17
build.py
@ -6,6 +6,8 @@ import ipaddress
|
|||||||
import requests
|
import requests
|
||||||
from requests.exceptions import RequestException, HTTPError
|
from requests.exceptions import RequestException, HTTPError
|
||||||
|
|
||||||
|
import gfwlist
|
||||||
|
|
||||||
|
|
||||||
SOURCES = {
|
SOURCES = {
|
||||||
'ipdeny.com': 'http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone',
|
'ipdeny.com': 'http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone',
|
||||||
@ -13,6 +15,9 @@ SOURCES = {
|
|||||||
}
|
}
|
||||||
OUT_DIR = "dist"
|
OUT_DIR = "dist"
|
||||||
|
|
||||||
|
# Stub content to disable GFWList check
|
||||||
|
GFWLIST_STUB = "var DOMAINS = {};\nvar BLACKPAT = [];\nvar WHITEPAT = [];\n"
|
||||||
|
|
||||||
|
|
||||||
def fetch_and_convert(src):
|
def fetch_and_convert(src):
|
||||||
response = requests.get(src)
|
response = requests.get(src)
|
||||||
@ -36,6 +41,9 @@ def main():
|
|||||||
code = f.read()
|
code = f.read()
|
||||||
code = code.replace("@@TIME@@", now.isoformat()[:-7])
|
code = code.replace("@@TIME@@", now.isoformat()[:-7])
|
||||||
|
|
||||||
|
gfwlist_part = gfwlist.generate_pac_partial()
|
||||||
|
gfwlist_stub = GFWLIST_STUB
|
||||||
|
|
||||||
os.makedirs(OUT_DIR, mode=0o755, exist_ok=True)
|
os.makedirs(OUT_DIR, mode=0o755, exist_ok=True)
|
||||||
for key in SOURCES:
|
for key in SOURCES:
|
||||||
print(f"Generating PAC script from source {key}")
|
print(f"Generating PAC script from source {key}")
|
||||||
@ -45,10 +53,19 @@ def main():
|
|||||||
continue
|
continue
|
||||||
except HTTPError:
|
except HTTPError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
filename = f"pac-{key}.txt"
|
filename = f"pac-{key}.txt"
|
||||||
|
filename_gfwlist = f"pac-gfwlist-{key}.txt"
|
||||||
with open(os.path.join(OUT_DIR, filename), "w") as f:
|
with open(os.path.join(OUT_DIR, filename), "w") as f:
|
||||||
f.write(code)
|
f.write(code)
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
f.write("\n")
|
||||||
|
f.write(gfwlist_stub)
|
||||||
|
with open(os.path.join(OUT_DIR, filename), "w") as f:
|
||||||
|
f.write(code)
|
||||||
|
f.write(data)
|
||||||
|
f.write("\n")
|
||||||
|
f.write(gfwlist_part)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
52
code.js
52
code.js
@ -1,6 +1,9 @@
|
|||||||
// Author: iBug <ibugone.com>
|
// Author: iBug <ibugone.com>
|
||||||
// Time: @@TIME@@
|
// Time: @@TIME@@
|
||||||
|
|
||||||
|
var proxy = __PROXY__;
|
||||||
|
var direct = "DIRECT";
|
||||||
|
|
||||||
function belongsToSubnet(host, list) {
|
function belongsToSubnet(host, list) {
|
||||||
var ip = host.split(".").map(Number);
|
var ip = host.split(".").map(Number);
|
||||||
ip = 0x1000000 * ip[0] + 0x10000 * ip[1] + 0x100 * ip[2] + ip[3];
|
ip = 0x1000000 * ip[0] + 0x10000 * ip[1] + 0x100 * ip[2] + ip[3];
|
||||||
@ -23,6 +26,38 @@ function belongsToSubnet(host, list) {
|
|||||||
return (masked ^ list[x][0]) == 0;
|
return (masked ^ list[x][0]) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasMatchedPattern(text, patterns) {
|
||||||
|
for (var i = 0; i < patterns.length; i++) {
|
||||||
|
if (shExpMatch(text, patterns[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkDomainType(host) {
|
||||||
|
// Check if a domain is blacklisted or whitelisted
|
||||||
|
var segments = host.split(".").reverse();
|
||||||
|
var ptr = DOMAINS;
|
||||||
|
var type = DOMAINS["@"];
|
||||||
|
for (var i = 0; i < segments.length; i++) {
|
||||||
|
var segment = segments[i];
|
||||||
|
ptr = ptr[segment];
|
||||||
|
if (ptr === undefined)
|
||||||
|
break;
|
||||||
|
if (ptr["@"] !== undefined)
|
||||||
|
type = ptr["@"];
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasWhitelistedPattern(url) {
|
||||||
|
return hasMatchedPattern(url, WHITEPAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasBlacklistedPattern(url) {
|
||||||
|
return hasMatchedPattern(url, BLACKPAT);
|
||||||
|
}
|
||||||
|
|
||||||
function isChina(host) {
|
function isChina(host) {
|
||||||
return belongsToSubnet(host, CHINA);
|
return belongsToSubnet(host, CHINA);
|
||||||
}
|
}
|
||||||
@ -31,10 +66,21 @@ function isLan(host) {
|
|||||||
return belongsToSubnet(host, LAN);
|
return belongsToSubnet(host, LAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
var proxy = "__PROXY__";
|
|
||||||
var direct = "DIRECT";
|
|
||||||
|
|
||||||
function FindProxyForURL(url, host) {
|
function FindProxyForURL(url, host) {
|
||||||
|
if (hasWhitelistedPattern(url)) {
|
||||||
|
return direct;
|
||||||
|
}
|
||||||
|
if (hasBlacklistedPattern(url)) {
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
var domainType = checkDomainType(host);
|
||||||
|
if (domainType === 0) {
|
||||||
|
return proxy;
|
||||||
|
} else if (domainType === 1) {
|
||||||
|
return direct;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to IP whitelist
|
||||||
var remote = dnsResolve(host);
|
var remote = dnsResolve(host);
|
||||||
if (!remote || remote.indexOf(":") !== -1) {
|
if (!remote || remote.indexOf(":") !== -1) {
|
||||||
// resolution failed or is IPv6 addr
|
// resolution failed or is IPv6 addr
|
||||||
|
Loading…
Reference in New Issue
Block a user