<commit_before>private let _singleton = TrackingProtection()

class TrackingProtection {
    static let prefKeyTrackingProtectionOn = "braveTrackingProtection"
    static let dataVersion = "1"
    var isEnabled = true

    var parser: TrackingProtectionCpp = TrackingProtectionCpp()

    lazy var networkFileLoader: NetworkDataFileLoader = {
        let dataUrl = NSURL(string: "https://s3.amazonaws.com/tracking-protection-data/\(dataVersion)/TrackingProtection.dat")!
        let dataFile = "tp-data-\(dataVersion).dat"
        let loader = NetworkDataFileLoader(url: dataUrl, file: dataFile, localDirName: "tp-data")
        loader.delegate = self
        return loader
    }()

    class var singleton: TrackingProtection {
        return _singleton
    }

    private init() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(TrackingProtection.prefsChanged(_:)), name: NSUserDefaultsDidChangeNotification, object: nil)
        updateEnabledState()
    }

    func updateEnabledState() {
        isEnabled = BraveApp.getPrefs()?.boolForKey(TrackingProtection.prefKeyTrackingProtectionOn) ?? true
    }

    @objc func prefsChanged(info: NSNotification) {
        updateEnabledState()
    }


    func shouldBlock(request: NSURLRequest) -> Bool {
        // synchronize code from this point on.
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }

        if !isEnabled {
            return false
        }

        guard let url = request.URL,
            var mainDocDomain = request.mainDocumentURL?.host else {
                return false
        }

        if request.mainDocumentURL?.absoluteString.startsWith(WebServer.sharedInstance.base) ?? false {
            return false
        }

        // https://github.com/brave/browser-ios/issues/90
        if url.absoluteString.contains("connect.facebook.com") {
            return false
        }
        mainDocDomain = stripGenericSubdomainPrefixFromUrl(stripLocalhostWebServer(mainDocDomain))

        guard var host = url.host else { return false}
        if host.contains(mainDocDomain) {
            return false // ignore top level doc
        }

        host = stripGenericSubdomainPrefixFromUrl(stripLocalhostWebServer(host))

        let isBlocked = parser.checkHostIsBlocked(host, mainDocumentHost: mainDocDomain)

        //if isBlocked { print("blocked \(url.absoluteString)") }
        return isBlocked
    }
}

extension TrackingProtection: NetworkDataFileLoaderDelegate {
    func fileLoader(_: NetworkDataFileLoader, setDataFile data: NSData?) {
        parser.setDataFile(data)
    }

    func fileLoaderHasDataFile(_: NetworkDataFileLoader) -> Bool {
        return parser.hasDataFile()
    }
}
<commit_msg>fix #228: update TP whitelist<commit_after>private let _singleton = TrackingProtection()

class TrackingProtection {
    static let prefKeyTrackingProtectionOn = "braveTrackingProtection"
    static let dataVersion = "1"
    var isEnabled = true

    var parser: TrackingProtectionCpp = TrackingProtectionCpp()

    lazy var networkFileLoader: NetworkDataFileLoader = {
        let dataUrl = NSURL(string: "https://s3.amazonaws.com/tracking-protection-data/\(dataVersion)/TrackingProtection.dat")!
        let dataFile = "tp-data-\(dataVersion).dat"
        let loader = NetworkDataFileLoader(url: dataUrl, file: dataFile, localDirName: "tp-data")
        loader.delegate = self
        return loader
    }()

    class var singleton: TrackingProtection {
        return _singleton
    }

    private init() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(TrackingProtection.prefsChanged(_:)), name: NSUserDefaultsDidChangeNotification, object: nil)
        updateEnabledState()
    }

    func updateEnabledState() {
        isEnabled = BraveApp.getPrefs()?.boolForKey(TrackingProtection.prefKeyTrackingProtectionOn) ?? true
    }

    @objc func prefsChanged(info: NSNotification) {
        updateEnabledState()
    }


    func shouldBlock(request: NSURLRequest) -> Bool {
        // synchronize code from this point on.
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }

        if !isEnabled {
            return false
        }

        guard let url = request.URL,
            var mainDocDomain = request.mainDocumentURL?.host else {
                return false
        }
        guard var host = url.host else { return false}

        if request.mainDocumentURL?.absoluteString.startsWith(WebServer.sharedInstance.base) ?? false {
            return false
        }

        let whitelist = ["connect.facebook.net", "connect.facebook.com", "staticxx.facebook.com", "www.facebook.com", "scontent.xx.fbcdn.net", "pbs.twimg.com"]
        if whitelist.contains(host) {
            return false
        }

        mainDocDomain = stripGenericSubdomainPrefixFromUrl(stripLocalhostWebServer(mainDocDomain))

        if host.contains(mainDocDomain) {
            return false // ignore top level doc
        }

        host = stripGenericSubdomainPrefixFromUrl(stripLocalhostWebServer(host))

        let isBlocked = parser.checkHostIsBlocked(host, mainDocumentHost: mainDocDomain)

        //if isBlocked { print("blocked \(url.absoluteString)") }
        return isBlocked
    }
}

extension TrackingProtection: NetworkDataFileLoaderDelegate {
    func fileLoader(_: NetworkDataFileLoader, setDataFile data: NSData?) {
        parser.setDataFile(data)
    }

    func fileLoaderHasDataFile(_: NetworkDataFileLoader) -> Bool {
        return parser.hasDataFile()
    }
}

{'fraction_non_alphanumeric': 0.09076204169662114, 'fraction_numerical': 0.0016175413371675054, 'mean_word_length': 2.916256157635468, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 3, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '361152', 'n_tokens_mistral': 1567, 'n_tokens_neox': 1519, 'n_words': 317}