refactor: pac转移配置

pull/88/head
xiaojunnuo 2021-08-11 11:21:53 +08:00
parent 09b2e65adb
commit 8b0f2d0f5d
8 changed files with 3391 additions and 23161 deletions

View File

@ -39,23 +39,23 @@ module.exports = {
'/.*/.*/releases/download/': { '/.*/.*/releases/download/': {
redirect: 'download.fastgit.org', redirect: 'download.fastgit.org',
desc: 'release文件加速下载跳转地址', desc: 'release文件加速下载跳转地址',
sni: 'no.sni' sni: 'baidu.com'
}, },
'/.*/.*/archive/': { '/.*/.*/archive/': {
redirect: 'download.fastgit.org', redirect: 'download.fastgit.org',
sni: 'no.sni' sni: 'baidu.com'
}, },
'/.*/.*/blame/': { '/.*/.*/blame/': {
redirect: 'hub.fastgit.org', redirect: 'hub.fastgit.org',
sni: 'no.sni' sni: 'baidu.com'
}, },
'^/[^/]+/[^/]+(/releases(/.*)?)?$': { '^/[^/]+/[^/]+(/releases(/.*)?)?$': {
script: [ script: [
'github' 'github'
], ],
desc: 'clone加速复制链接脚本', desc: 'clone加速复制链接脚本',
sni: 'no.sni' sni: 'baidu.com'
}, },
'/.*': { '/.*': {
proxy: 'github.com', proxy: 'github.com',

View File

@ -16,8 +16,9 @@ module.exports = {
}, },
pac: { pac: {
enabled: true, enabled: true,
update: [ // update: [
'https://gitlab.com/gfwlist/gfwlist/raw/master/gfwlist.txt' // 'https://gitlab.com/gfwlist/gfwlist/raw/master/gfwlist.txt'
] // ],
customPacFilePath: './extra/pac/pac.txt'
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,14 @@
const url = require('url') const url = require('url')
const pac = require('./source/pac') const pac = require('./source/pac')
const matchUtil = require('../../../utils/util.match') const matchUtil = require('../../../utils/util.match')
let pacClient = null
function matched (hostname, regexpMap) { function matched (hostname, regexpMap) {
const ret1 = matchUtil.matchHostname(regexpMap, hostname) const ret1 = matchUtil.matchHostname(regexpMap, hostname)
if (ret1) { if (ret1) {
return true return true
} }
const ret = pac.FindProxyForURL('https://' + hostname, hostname) const ret = pacClient.FindProxyForURL('https://' + hostname, hostname)
if (ret && ret.indexOf('PROXY ') === 0) { if (ret && ret.indexOf('PROXY ') === 0) {
return true return true
} }
@ -18,6 +19,11 @@ module.exports = function createOverWallIntercept (overWallConfig) {
if (!overWallConfig || overWallConfig.enabled !== true) { if (!overWallConfig || overWallConfig.enabled !== true) {
return null return null
} }
if (overWallConfig.pac) {
// 初始化pac
pacClient = pac.createPacClient(overWallConfig.pac.customPacFilePath)
}
let server = overWallConfig.server let server = overWallConfig.server
let keys = Object.keys(server) let keys = Object.keys(server)
if (keys.length === 0) { if (keys.length === 0) {

View File

@ -1,8 +1,27 @@
var __PROXY__ = 'PROXY 127.0.0.1:1080;' const fs = require('fs')
var __USERRULES__ = [] const path = require('path')
const getRules = function () { const log = require('../../../../utils/util.log')
let text = require('./pac.txt.js')
function createPacClient (pacFilePath) {
var __PROXY__ = 'PROXY 127.0.0.1:1080;'
var __USERRULES__ = []
function readFile (location) {
try {
const filePath = path.resolve(location)
log.debug('read pac path:', filePath)
return fs.readFileSync(location).toString()
} catch (e) {
log.error('读取pac失败')
return ''
}
}
const getRules = function (pacFilePath) {
let text = readFile(pacFilePath)
if (text.indexOf('!---------------------EOF') === -1) {
text = Buffer.from(text, 'base64').toString() text = Buffer.from(text, 'base64').toString()
}
const rules = [] const rules = []
const arr = text.split('\n') const arr = text.split('\n')
for (const line of arr) { for (const line of arr) {
@ -13,63 +32,64 @@ const getRules = function () {
rules.push(row) rules.push(row)
} }
return rules return rules
} }
var __RULES__ = getRules() var __RULES__ = getRules(pacFilePath)
/* eslint-disable */
/* eslint-disable */
// Was generated by gfwlist2pac in precise mode // Was generated by gfwlist2pac in precise mode
// https://github.com/clowwindy/gfwlist2pac // https://github.com/clowwindy/gfwlist2pac
// 2019-10-06: More 'javascript' way to interaction with main program // 2019-10-06: More 'javascript' way to interaction with main program
// 2019-02-08: Updated to support shadowsocks-windows user rules. // 2019-02-08: Updated to support shadowsocks-windows user rules.
var proxy = __PROXY__; var proxy = __PROXY__;
var userrules = []; var userrules = [];
var rules = []; var rules = [];
// convert to abp grammar // convert to abp grammar
for (var i = 0; i < __RULES__.length; i++) { for (var i = 0; i < __RULES__.length; i++) {
var s = __RULES__[i]; var s = __RULES__[i];
if (s.substring(0, 2) == "||") s += "^"; if (s.substring(0, 2) == "||") s += "^";
rules.push(s); rules.push(s);
} }
for (var i = 0; i < __USERRULES__.length; i++) { for (var i = 0; i < __USERRULES__.length; i++) {
var s = __USERRULES__[i]; var s = __USERRULES__[i];
if (s.substring(0, 2) == "||") s += "^"; if (s.substring(0, 2) == "||") s += "^";
userrules.push(s); userrules.push(s);
} }
/* /*
* This file is part of Adblock Plus <http://adblockplus.org/>, * This file is part of Adblock Plus <http://adblockplus.org/>,
* Copyright (C) 2006-2014 Eyeo GmbH * Copyright (C) 2006-2014 Eyeo GmbH
* *
* Adblock Plus is free software: you can redistribute it and/or modify * Adblock Plus is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as * it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* Adblock Plus is distributed in the hope that it will be useful, * Adblock Plus is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
*/ */
function createDict() { function createDict() {
var result = {}; var result = {};
result.__proto__ = null; result.__proto__ = null;
return result; return result;
} }
function getOwnPropertyDescriptor(obj, key) { function getOwnPropertyDescriptor(obj, key) {
if (obj.hasOwnProperty(key)) { if (obj.hasOwnProperty(key)) {
return obj[key]; return obj[key];
} }
return null; return null;
} }
function extend(subclass, superclass, definition) { function extend(subclass, superclass, definition) {
if (Object.__proto__) { if (Object.__proto__) {
definition.__proto__ = superclass.prototype; definition.__proto__ = superclass.prototype;
subclass.prototype = definition; subclass.prototype = definition;
@ -85,25 +105,25 @@ function extend(subclass, superclass, definition) {
} }
} }
} }
} }
function Filter(text) { function Filter(text) {
this.text = text; this.text = text;
this.subscriptions = []; this.subscriptions = [];
} }
Filter.prototype = { Filter.prototype = {
text: null, text: null,
subscriptions: null, subscriptions: null,
toString: function () { toString: function () {
return this.text; return this.text;
} }
}; };
Filter.knownFilters = createDict(); Filter.knownFilters = createDict();
Filter.elemhideRegExp = /^([^\/\*\|\@"!]*?)#(\@)?(?:([\w\-]+|\*)((?:\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\))*)|#([^{}]+))$/; Filter.elemhideRegExp = /^([^\/\*\|\@"!]*?)#(\@)?(?:([\w\-]+|\*)((?:\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\))*)|#([^{}]+))$/;
Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)?$/; Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)?$/;
Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/; Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/;
Filter.fromText = function (text) { Filter.fromText = function (text) {
if (text in Filter.knownFilters) { if (text in Filter.knownFilters) {
return Filter.knownFilters[text]; return Filter.knownFilters[text];
} }
@ -115,29 +135,29 @@ Filter.fromText = function (text) {
} }
Filter.knownFilters[ret.text] = ret; Filter.knownFilters[ret.text] = ret;
return ret; return ret;
}; };
function InvalidFilter(text, reason) { function InvalidFilter(text, reason) {
Filter.call(this, text); Filter.call(this, text);
this.reason = reason; this.reason = reason;
} }
extend(InvalidFilter, Filter, { extend(InvalidFilter, Filter, {
reason: null reason: null
}); });
function CommentFilter(text) { function CommentFilter(text) {
Filter.call(this, text); Filter.call(this, text);
} }
extend(CommentFilter, Filter, {}); extend(CommentFilter, Filter, {});
function ActiveFilter(text, domains) { function ActiveFilter(text, domains) {
Filter.call(this, text); Filter.call(this, text);
this.domainSource = domains; this.domainSource = domains;
} }
extend(ActiveFilter, Filter, { extend(ActiveFilter, Filter, {
domainSource: null, domainSource: null,
domainSeparator: null, domainSeparator: null,
ignoreTrailingDot: true, ignoreTrailingDot: true,
@ -232,9 +252,9 @@ extend(ActiveFilter, Filter, {
} }
return true; return true;
} }
}); });
function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) { function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) {
ActiveFilter.call(this, text, domains, sitekeys); ActiveFilter.call(this, text, domains, sitekeys);
if (contentType != null) { if (contentType != null) {
this.contentType = contentType; this.contentType = contentType;
@ -254,9 +274,9 @@ function RegExpFilter(text, regexpSource, contentType, matchCase, domains, third
} else { } else {
this.regexpSource = regexpSource; this.regexpSource = regexpSource;
} }
} }
extend(RegExpFilter, ActiveFilter, { extend(RegExpFilter, ActiveFilter, {
domainSourceIsUpperCase: true, domainSourceIsUpperCase: true,
length: 1, length: 1,
domainSeparator: "|", domainSeparator: "|",
@ -294,9 +314,9 @@ extend(RegExpFilter, ActiveFilter, {
} }
return false; return false;
} }
}); });
RegExpFilter.prototype["0"] = "#this"; RegExpFilter.prototype["0"] = "#this";
RegExpFilter.fromText = function (text) { RegExpFilter.fromText = function (text) {
var blocking = true; var blocking = true;
var origText = text; var origText = text;
if (text.indexOf("@@") == 0) { if (text.indexOf("@@") == 0) {
@ -369,8 +389,8 @@ RegExpFilter.fromText = function (text) {
} catch (e) { } catch (e) {
return new InvalidFilter(origText, e); return new InvalidFilter(origText, e);
} }
}; };
RegExpFilter.typeMap = { RegExpFilter.typeMap = {
OTHER: 1, OTHER: 1,
SCRIPT: 2, SCRIPT: 2,
IMAGE: 4, IMAGE: 4,
@ -388,29 +408,29 @@ RegExpFilter.typeMap = {
BACKGROUND: 4, BACKGROUND: 4,
POPUP: 268435456, POPUP: 268435456,
ELEMHIDE: 1073741824 ELEMHIDE: 1073741824
}; };
RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFilter.typeMap.POPUP); RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFilter.typeMap.POPUP);
function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys, collapse) { function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys, collapse) {
RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys); RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys);
this.collapse = collapse; this.collapse = collapse;
} }
extend(BlockingFilter, RegExpFilter, { extend(BlockingFilter, RegExpFilter, {
collapse: null collapse: null
}); });
function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) { function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) {
RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys); RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys);
} }
extend(WhitelistFilter, RegExpFilter, {}); extend(WhitelistFilter, RegExpFilter, {});
function Matcher() { function Matcher() {
this.clear(); this.clear();
} }
Matcher.prototype = { Matcher.prototype = {
filterByKeyword: null, filterByKeyword: null,
keywordByFilter: null, keywordByFilter: null,
clear: function () { clear: function () {
@ -522,16 +542,16 @@ Matcher.prototype = {
} }
return null; return null;
} }
}; };
function CombinedMatcher() { function CombinedMatcher() {
this.blacklist = new Matcher(); this.blacklist = new Matcher();
this.whitelist = new Matcher(); this.whitelist = new Matcher();
this.resultCache = createDict(); this.resultCache = createDict();
} }
CombinedMatcher.maxCacheEntries = 1000; CombinedMatcher.maxCacheEntries = 1000;
CombinedMatcher.prototype = { CombinedMatcher.prototype = {
blacklist: null, blacklist: null,
whitelist: null, whitelist: null,
resultCache: null, resultCache: null,
@ -628,22 +648,22 @@ CombinedMatcher.prototype = {
this.cacheEntries++; this.cacheEntries++;
return result; return result;
} }
}; };
var userrulesMatcher = new CombinedMatcher(); var userrulesMatcher = new CombinedMatcher();
var defaultMatcher = new CombinedMatcher(); var defaultMatcher = new CombinedMatcher();
var direct = 'DIRECT;'; var direct = 'DIRECT;';
for (var i = 0; i < userrules.length; i++) { for (var i = 0; i < userrules.length; i++) {
userrulesMatcher.add(Filter.fromText(userrules[i])); userrulesMatcher.add(Filter.fromText(userrules[i]));
} }
for (var i = 0; i < rules.length; i++) { for (var i = 0; i < rules.length; i++) {
defaultMatcher.add(Filter.fromText(rules[i])); defaultMatcher.add(Filter.fromText(rules[i]));
} }
function FindProxyForURL(url, host) { function FindProxyForURL(url, host) {
if (userrulesMatcher.matchesAny(url, host) instanceof BlockingFilter) { if (userrulesMatcher.matchesAny(url, host) instanceof BlockingFilter) {
return proxy; return proxy;
} }
@ -658,8 +678,14 @@ function FindProxyForURL(url, host) {
return proxy; return proxy;
} }
return direct; return direct;
}
return {
FindProxyForURL,
}
} }
module.exports = { module.exports = {
FindProxyForURL createPacClient
} }

File diff suppressed because one or more lines are too long