zoukankan      html  css  js  c++  java
  • Pac代理文件

    用于将本地特定规则的请求转发到某个ip port代理

    var proxy = "PROXY 127.0.0.1:xxxx; DIRECT;";
    
    var rules = [
      "||xxx.xxx.com",
    ];
    
    /*
    * This file is part of Adblock Plus <http://adblockplus.org/>,
    * Copyright (C) 2006-2014 Eyeo GmbH
    *
    * 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
    * published by the Free Software Foundation.
    *
    * Adblock Plus is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    * GNU General Public License for more details.
    *
    * You should have received a copy of the GNU General Public License
    * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
    */
    
    function createDict()
    {
        var result = {};
        result.__proto__ = null;
        return result;
    }
    
    function getOwnPropertyDescriptor(obj, key)
    {
        if (obj.hasOwnProperty(key))
        {
            return obj[key];
        }
        return null;
    }
    
    function extend(subclass, superclass, definition)
    {
        if (Object.__proto__)
        {
            definition.__proto__ = superclass.prototype;
            subclass.prototype = definition;
        }
        else
        {
            var tmpclass = function(){}, ret;
            tmpclass.prototype = superclass.prototype;
            subclass.prototype = new tmpclass();
            subclass.prototype.constructor = superclass;
            for (var i in definition)
            {
                if (definition.hasOwnProperty(i))
                {
                    subclass.prototype[i] = definition[i];
                }
            }
        }
    }
    
    function Filter(text)
    {
        this.text = text;
        this.subscriptions = [];
    }
    Filter.prototype = {
        text: null,
        subscriptions: null,
        toString: function()
        {
            return this.text;
        }
    };
    Filter.knownFilters = createDict();
    Filter.elemhideRegExp = /^([^/*|@"!]*?)#(@)?(?:([w-]+|*)((?:([w-]+(?:[$^*]?=[^()"]*)?))*)|#([^{}]+))$/;
    Filter.regexpRegExp = /^(@@)?/.*/(?:$~?[w-]+(?:=[^,s]+)?(?:,~?[w-]+(?:=[^,s]+)?)*)?$/;
    Filter.optionsRegExp = /$(~?[w-]+(?:=[^,s]+)?(?:,~?[w-]+(?:=[^,s]+)?)*)$/;
    Filter.fromText = function(text)
    {
        if (text in Filter.knownFilters)
        {
            return Filter.knownFilters[text];
        }
        var ret;
        if (text[0] == "!")
        {
            ret = new CommentFilter(text);
        }
        else
        {
            ret = RegExpFilter.fromText(text);
        }
        Filter.knownFilters[ret.text] = ret;
        return ret;
    };
    
    function InvalidFilter(text, reason)
    {
        Filter.call(this, text);
        this.reason = reason;
    }
    extend(InvalidFilter, Filter, {
        reason: null
    });
    
    function CommentFilter(text)
    {
        Filter.call(this, text);
    }
    extend(CommentFilter, Filter, {
    });
    
    function ActiveFilter(text, domains)
    {
        Filter.call(this, text);
        this.domainSource = domains;
    }
    extend(ActiveFilter, Filter, {
        domainSource: null,
        domainSeparator: null,
        ignoreTrailingDot: true,
        domainSourceIsUpperCase: false,
        getDomains: function()
        {
            var prop = getOwnPropertyDescriptor(this, "domains");
            if (prop)
            {
                return prop;
            }
            var domains = null;
            if (this.domainSource)
            {
                var source = this.domainSource;
                if (!this.domainSourceIsUpperCase)
                {
                    source = source.toUpperCase();
                }
                var list = source.split(this.domainSeparator);
                if (list.length == 1 && list[0][0] != "~")
                {
                    domains = createDict();
                    domains[""] = false;
                    if (this.ignoreTrailingDot)
                    {
                        list[0] = list[0].replace(/.+$/, "");
                    }
                    domains[list[0]] = true;
                }
                else
                {
                    var hasIncludes = false;
                    for (var i = 0; i < list.length; i++)
                    {
                        var domain = list[i];
                        if (this.ignoreTrailingDot)
                        {
                            domain = domain.replace(/.+$/, "");
                        }
                        if (domain == "")
                        {
                            continue;
                        }
                        var include;
                        if (domain[0] == "~")
                        {
                            include = false;
                            domain = domain.substr(1);
                        }
                        else
                        {
                            include = true;
                            hasIncludes = true;
                        }
                        if (!domains)
                        {
                            domains = createDict();
                        }
                        domains[domain] = include;
                    }
                    domains[""] = !hasIncludes;
                }
                this.domainSource = null;
            }
            return this.domains;
        },
        sitekeys: null,
        isActiveOnDomain: function(docDomain, sitekey)
        {
            if (this.getSitekeys() && (!sitekey || this.getSitekeys().indexOf(sitekey.toUpperCase()) < 0))
            {
                return false;
            }
            if (!this.getDomains())
            {
                return true;
            }
            if (!docDomain)
            {
                return this.getDomains()[""];
            }
            if (this.ignoreTrailingDot)
            {
                docDomain = docDomain.replace(/.+$/, "");
            }
            docDomain = docDomain.toUpperCase();
            while (true)
            {
                if (docDomain in this.getDomains())
                {
                    return this.domains[docDomain];
                }
                var nextDot = docDomain.indexOf(".");
                if (nextDot < 0)
                {
                    break;
                }
                docDomain = docDomain.substr(nextDot + 1);
            }
            return this.domains[""];
        },
        isActiveOnlyOnDomain: function(docDomain)
        {
            if (!docDomain || !this.getDomains() || this.getDomains()[""])
            {
                return false;
            }
            if (this.ignoreTrailingDot)
            {
                docDomain = docDomain.replace(/.+$/, "");
            }
            docDomain = docDomain.toUpperCase();
            for (var domain in this.getDomains())
            {
                if (this.domains[domain] && domain != docDomain && (domain.length <= docDomain.length || domain.indexOf("." + docDomain) != domain.length - docDomain.length - 1))
                {
                    return false;
                }
            }
            return true;
        }
    });
    
    function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys)
    {
        ActiveFilter.call(this, text, domains, sitekeys);
        if (contentType != null)
        {
            this.contentType = contentType;
        }
        if (matchCase)
        {
            this.matchCase = matchCase;
        }
        if (thirdParty != null)
        {
            this.thirdParty = thirdParty;
        }
        if (sitekeys != null)
        {
            this.sitekeySource = sitekeys;
        }
        if (regexpSource.length >= 2 && regexpSource[0] == "/" && regexpSource[regexpSource.length - 1] == "/")
        {
            var regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), this.matchCase ? "" : "i");
            this.regexp = regexp;
        }
        else
        {
            this.regexpSource = regexpSource;
        }
    }
    extend(RegExpFilter, ActiveFilter, {
        domainSourceIsUpperCase: true,
        length: 1,
        domainSeparator: "|",
        regexpSource: null,
        getRegexp: function()
        {
            var prop = getOwnPropertyDescriptor(this, "regexp");
            if (prop)
            {
                return prop;
            }
            var source = this.regexpSource.replace(/*+/g, "*").replace(/^|$/, "^").replace(/W/g, "\$&").replace(/\*/g, ".*").replace(/\^/g, "(?:[\x00-\x24\x26-\x2C\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x7F]|$)").replace(/^\|\|/, "^[\w\-]+:\/+(?!\/)(?:[^\/]+\.)?").replace(/^\|/, "^").replace(/\|$/, "$").replace(/^(.*)/, "").replace(/(.*)$/, "");
            var regexp = new RegExp(source, this.matchCase ? "" : "i");
            this.regexp = regexp;
            return regexp;
        },
        contentType: 2147483647,
        matchCase: false,
        thirdParty: null,
        sitekeySource: null,
        getSitekeys: function()
        {
            var prop = getOwnPropertyDescriptor(this, "sitekeys");
            if (prop)
            {
                return prop;
            }
            var sitekeys = null;
            if (this.sitekeySource)
            {
                sitekeys = this.sitekeySource.split("|");
                this.sitekeySource = null;
            }
            this.sitekeys = sitekeys;
            return this.sitekeys;
        },
        matches: function(location, contentType, docDomain, thirdParty, sitekey)
        {
            if (this.getRegexp().test(location) && this.isActiveOnDomain(docDomain, sitekey))
            {
                return true;
            }
            return false;
        }
    });
    RegExpFilter.prototype["0"] = "#this";
    RegExpFilter.fromText = function(text)
    {
        var blocking = true;
        var origText = text;
        if (text.indexOf("@@") == 0)
        {
            blocking = false;
            text = text.substr(2);
        }
        var contentType = null;
        var matchCase = null;
        var domains = null;
        var sitekeys = null;
        var thirdParty = null;
        var collapse = null;
        var options;
        var match = text.indexOf("$") >= 0 ? Filter.optionsRegExp.exec(text) : null;
        if (match)
        {
            options = match[1].toUpperCase().split(",");
            text = match.input.substr(0, match.index);
            for (var _loopIndex6 = 0; _loopIndex6 < options.length; ++_loopIndex6)
            {
                var option = options[_loopIndex6];
                var value = null;
                var separatorIndex = option.indexOf("=");
                if (separatorIndex >= 0)
                {
                    value = option.substr(separatorIndex + 1);
                    option = option.substr(0, separatorIndex);
                }
                option = option.replace(/-/, "_");
                if (option in RegExpFilter.typeMap)
                {
                    if (contentType == null)
                    {
                        contentType = 0;
                    }
                    contentType |= RegExpFilter.typeMap[option];
                }
                else if (option[0] == "~" && option.substr(1) in RegExpFilter.typeMap)
                {
                    if (contentType == null)
                    {
                        contentType = RegExpFilter.prototype.contentType;
                    }
                    contentType &= ~RegExpFilter.typeMap[option.substr(1)];
                }
                else if (option == "MATCH_CASE")
                {
                    matchCase = true;
                }
                else if (option == "~MATCH_CASE")
                {
                    matchCase = false;
                }
                else if (option == "DOMAIN" && typeof value != "undefined")
                {
                    domains = value;
                }
                else if (option == "THIRD_PARTY")
                {
                    thirdParty = true;
                }
                else if (option == "~THIRD_PARTY")
                {
                    thirdParty = false;
                }
                else if (option == "COLLAPSE")
                {
                    collapse = true;
                }
                else if (option == "~COLLAPSE")
                {
                    collapse = false;
                }
                else if (option == "SITEKEY" && typeof value != "undefined")
                {
                    sitekeys = value;
                }
                else
                {
                    return new InvalidFilter(origText, "Unknown option " + option.toLowerCase());
                }
            }
        }
        if (!blocking && (contentType == null || contentType & RegExpFilter.typeMap.DOCUMENT) && (!options || options.indexOf("DOCUMENT") < 0) && !/^|?[w-]+:/.test(text))
        {
            if (contentType == null)
            {
                contentType = RegExpFilter.prototype.contentType;
            }
            contentType &= ~RegExpFilter.typeMap.DOCUMENT;
        }
        try
        {
            if (blocking)
            {
                return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys, collapse);
            }
            else
            {
                return new WhitelistFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys);
            }
        }
        catch (e)
        {
            return new InvalidFilter(origText, e);
        }
    };
    RegExpFilter.typeMap = {
        OTHER: 1,
        SCRIPT: 2,
        IMAGE: 4,
        STYLESHEET: 8,
        OBJECT: 16,
        SUBDOCUMENT: 32,
        DOCUMENT: 64,
        XBL: 1,
        PING: 1,
        XMLHTTPREQUEST: 2048,
        OBJECT_SUBREQUEST: 4096,
        DTD: 1,
        MEDIA: 16384,
        FONT: 32768,
        BACKGROUND: 4,
        POPUP: 268435456,
        ELEMHIDE: 1073741824
    };
    RegExpFilter.prototype.contentType &= ~ (RegExpFilter.typeMap.ELEMHIDE | RegExpFilter.typeMap.POPUP);
    
    function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys, collapse)
    {
        RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys);
        this.collapse = collapse;
    }
    extend(BlockingFilter, RegExpFilter, {
        collapse: null
    });
    
    function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys)
    {
        RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys);
    }
    extend(WhitelistFilter, RegExpFilter, {
    });
    
    function Matcher()
    {
        this.clear();
    }
    Matcher.prototype = {
        filterByKeyword: null,
        keywordByFilter: null,
        clear: function()
        {
            this.filterByKeyword = createDict();
            this.keywordByFilter = createDict();
        },
        add: function(filter)
        {
            if (filter.text in this.keywordByFilter)
            {
                return;
            }
            var keyword = this.findKeyword(filter);
            var oldEntry = this.filterByKeyword[keyword];
            if (typeof oldEntry == "undefined")
            {
                this.filterByKeyword[keyword] = filter;
            }
            else if (oldEntry.length == 1)
            {
                this.filterByKeyword[keyword] = [oldEntry, filter];
            }
            else
            {
                oldEntry.push(filter);
            }
            this.keywordByFilter[filter.text] = keyword;
        },
        remove: function(filter)
        {
            if (!(filter.text in this.keywordByFilter))
            {
                return;
            }
            var keyword = this.keywordByFilter[filter.text];
            var list = this.filterByKeyword[keyword];
            if (list.length <= 1)
            {
                delete this.filterByKeyword[keyword];
            }
            else
            {
                var index = list.indexOf(filter);
                if (index >= 0)
                {
                    list.splice(index, 1);
                    if (list.length == 1)
                    {
                        this.filterByKeyword[keyword] = list[0];
                    }
                }
            }
            delete this.keywordByFilter[filter.text];
        },
        findKeyword: function(filter)
        {
            var result = "";
            var text = filter.text;
            if (Filter.regexpRegExp.test(text))
            {
                return result;
            }
            var match = Filter.optionsRegExp.exec(text);
            if (match)
            {
                text = match.input.substr(0, match.index);
            }
            if (text.substr(0, 2) == "@@")
            {
                text = text.substr(2);
            }
            var candidates = text.toLowerCase().match(/[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g);
            if (!candidates)
            {
                return result;
            }
            var hash = this.filterByKeyword;
            var resultCount = 16777215;
            var resultLength = 0;
            for (var i = 0, l = candidates.length; i < l; i++)
            {
                var candidate = candidates[i].substr(1);
                var count = candidate in hash ? hash[candidate].length : 0;
                if (count < resultCount || count == resultCount && candidate.length > resultLength)
                {
                    result = candidate;
                    resultCount = count;
                    resultLength = candidate.length;
                }
            }
            return result;
        },
        hasFilter: function(filter)
        {
            return filter.text in this.keywordByFilter;
        },
        getKeywordForFilter: function(filter)
        {
            if (filter.text in this.keywordByFilter)
            {
                return this.keywordByFilter[filter.text];
            }
            else
            {
                return null;
            }
        },
        _checkEntryMatch: function(keyword, location, contentType, docDomain, thirdParty, sitekey)
        {
            var list = this.filterByKeyword[keyword];
            for (var i = 0; i < list.length; i++)
            {
                var filter = list[i];
                if (filter == "#this")
                {
                    filter = list;
                }
                if (filter.matches(location, contentType, docDomain, thirdParty, sitekey))
                {
                    return filter;
                }
            }
            return null;
        },
        matchesAny: function(location, contentType, docDomain, thirdParty, sitekey)
        {
            var candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
            if (candidates === null)
            {
                candidates = [];
            }
            candidates.push("");
            for (var i = 0, l = candidates.length; i < l; i++)
            {
                var substr = candidates[i];
                if (substr in this.filterByKeyword)
                {
                    var result = this._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey);
                    if (result)
                    {
                        return result;
                    }
                }
            }
            return null;
        }
    };
    
    function CombinedMatcher()
    {
        this.blacklist = new Matcher();
        this.whitelist = new Matcher();
        this.resultCache = createDict();
    }
    CombinedMatcher.maxCacheEntries = 1000;
    CombinedMatcher.prototype = {
        blacklist: null,
        whitelist: null,
        resultCache: null,
        cacheEntries: 0,
        clear: function()
        {
            this.blacklist.clear();
            this.whitelist.clear();
            this.resultCache = createDict();
            this.cacheEntries = 0;
        },
        add: function(filter)
        {
            if (filter instanceof WhitelistFilter)
            {
                this.whitelist.add(filter);
            }
            else
            {
                this.blacklist.add(filter);
            }
            if (this.cacheEntries > 0)
            {
                this.resultCache = createDict();
                this.cacheEntries = 0;
            }
        },
        remove: function(filter)
        {
            if (filter instanceof WhitelistFilter)
            {
                this.whitelist.remove(filter);
            }
            else
            {
                this.blacklist.remove(filter);
            }
            if (this.cacheEntries > 0)
            {
                this.resultCache = createDict();
                this.cacheEntries = 0;
            }
        },
        findKeyword: function(filter)
        {
            if (filter instanceof WhitelistFilter)
            {
                return this.whitelist.findKeyword(filter);
            }
            else
            {
                return this.blacklist.findKeyword(filter);
            }
        },
        hasFilter: function(filter)
        {
            if (filter instanceof WhitelistFilter)
            {
                return this.whitelist.hasFilter(filter);
            }
            else
            {
                return this.blacklist.hasFilter(filter);
            }
        },
        getKeywordForFilter: function(filter)
        {
            if (filter instanceof WhitelistFilter)
            {
                return this.whitelist.getKeywordForFilter(filter);
            }
            else
            {
                return this.blacklist.getKeywordForFilter(filter);
            }
        },
        isSlowFilter: function(filter)
        {
            var matcher = filter instanceof WhitelistFilter ? this.whitelist : this.blacklist;
            if (matcher.hasFilter(filter))
            {
                return !matcher.getKeywordForFilter(filter);
            }
            else
            {
                return !matcher.findKeyword(filter);
            }
        },
        matchesAnyInternal: function(location, contentType, docDomain, thirdParty, sitekey)
        {
            var candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
            if (candidates === null)
            {
                candidates = [];
            }
            candidates.push("");
            var blacklistHit = null;
            for (var i = 0, l = candidates.length; i < l; i++)
            {
                var substr = candidates[i];
                if (substr in this.whitelist.filterByKeyword)
                {
                    var result = this.whitelist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey);
                    if (result)
                    {
                        return result;
                    }
                }
                if (substr in this.blacklist.filterByKeyword && blacklistHit === null)
                {
                    blacklistHit = this.blacklist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey);
                }
            }
            return blacklistHit;
        },
        matchesAny: function(location, docDomain)
        {
            var key = location + " " + docDomain + " ";
            if (key in this.resultCache)
            {
                return this.resultCache[key];
            }
            var result = this.matchesAnyInternal(location, 0, docDomain, null, null);
            if (this.cacheEntries >= CombinedMatcher.maxCacheEntries)
            {
                this.resultCache = createDict();
                this.cacheEntries = 0;
            }
            this.resultCache[key] = result;
            this.cacheEntries++;
            return result;
        }
    };
    var defaultMatcher = new CombinedMatcher();
    
    var direct = 'DIRECT;';
    
    for (var i = 0; i < rules.length; i++) {
        defaultMatcher.add(Filter.fromText(rules[i]));
    }
    
    function FindProxyForURL(url, host) {
        if (defaultMatcher.matchesAny(url, host) instanceof BlockingFilter) {
            return proxy;
        }
        return direct;
    }
    
  • 相关阅读:
    自学人工智能之数学篇,数学入门并不难
    2018-8-10-win10-uwp-使用资源在后台创建控件
    2019-9-2-win10-uwp-弹起键盘不隐藏界面元素
    2019-7-31-程序猿修养-日志应该如何写
    2018-11-19-WPF-在image控件用鼠标拖拽出矩形
    2019-8-31-C#-如何给-ValueTuple-返回值添加注释
    2019-11-12-浅谈-Windows-桌面端触摸架构演进
    2018-8-10-win10-uwp-打开文件管理器选择文件
    2018-8-10-win10-uwp-验证输入-自定义用户控件
    2019-8-31-dotnet-特性-DynamicallyInvokable-是用来做什么的
  • 原文地址:https://www.cnblogs.com/tonglin0325/p/13276977.html
Copyright © 2011-2022 走看看