Skip to content

Commit 7d4784d

Browse files
authored
update to use TDS (duckduckgo#533)
1 parent 528e4f2 commit 7d4784d

File tree

76 files changed

+18622
-2742
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+18622
-2742
lines changed

Core/AppUrls.swift

+14-26
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,24 @@ public struct AppUrls {
2828
}
2929

3030
static let base = ProcessInfo.processInfo.environment["BASE_URL", default: "https://duckduckgo.com"]
31+
static let staticBase = "https://staticcdn.duckduckgo.com"
32+
3133
static let autocomplete = "\(base)/ac/"
32-
static let disconnectMeBlockList = "\(base)/contentblocking.js?l=disconnect"
33-
static let easylistBlockList = "\(base)/contentblocking.js?l=easylist"
34-
static let easylistPrivacyBlockList = "\(base)/contentblocking.js?l=easyprivacy"
35-
static let trackersWhitelist = "\(base)/contentblocking/trackers-whitelist.txt"
34+
3635
static let surrogates = "\(base)/contentblocking.js?l=surrogates"
37-
static let entitylist = "\(base)/contentblocking.js?l=entitylist2"
36+
static let temporaryWhitelist = "\(base)/contentblocking/trackers-whitelist-temporary.txt"
37+
static let trackerDataSet = "\(staticBase)/trackerblocking/tds.json"
38+
3839
static let atb = "\(base)/atb.js\(devMode)"
3940
static let exti = "\(base)/exti/\(devMode)"
4041
static let feedback = "\(base)/feedback.js?type=app-feedback"
4142
static let faviconService = "\(base)/ip3/%@.ico"
4243

43-
static let staticBase = "https://staticcdn.duckduckgo.com"
4444
static let httpsBloomFilter = "\(staticBase)/https/https-mobile-bloom.bin?cache-version=1"
4545
static let httpsBloomFilterSpec = "\(staticBase)/https/https-mobile-bloom-spec.json?cache-version=1"
4646
static let httpsWhitelist = "\(staticBase)/https/https-mobile-whitelist.json?cache-version=1"
4747
static let httpsLookupService = "\(base)/smarter_encryption.js"
48-
48+
4949
static let pixelBase = ProcessInfo.processInfo.environment["PIXEL_BASE_URL", default: "https://improving.duckduckgo.com"]
5050
static let pixel = "\(pixelBase)/t/%@_ios_%@"
5151
}
@@ -78,28 +78,16 @@ public struct AppUrls {
7878
return URL(string: Url.autocomplete)!.addParam(name: Param.search, value: text)
7979
}
8080

81-
public var disconnectMeBlockList: URL {
82-
return URL(string: Url.disconnectMeBlockList)!
83-
}
84-
85-
public var easylistBlockList: URL {
86-
return URL(string: Url.easylistBlockList)!
87-
}
88-
89-
public var easylistPrivacyBlockList: URL {
90-
return URL(string: Url.easylistPrivacyBlockList)!
91-
}
92-
93-
public var trackersWhitelist: URL {
94-
return URL(string: Url.trackersWhitelist)!
95-
}
96-
9781
public var surrogates: URL {
9882
return URL(string: Url.surrogates)!
9983
}
100-
101-
public var entitylist: URL {
102-
return URL(string: Url.entitylist)!
84+
85+
public var trackerDataSet: URL {
86+
return URL(string: Url.trackerDataSet)!
87+
}
88+
89+
public var temporaryWhitelist: URL {
90+
return URL(string: Url.temporaryWhitelist)!
10391
}
10492

10593
public var feedback: URL {

Core/CohortRequest.swift

-66
This file was deleted.

Core/ContentBlockerLoader.swift

+10-30
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,23 @@ public class ContentBlockerLoader {
2626

2727
private let httpsUpgradeStore: HTTPSUpgradeStore = HTTPSUpgradePersistence()
2828
private let etagStorage: BlockerListETagStorage
29+
private let fileStore: FileStore
2930

3031
private var newData = DataDict()
3132
private var etags = EtagDict()
3233

33-
init(etagStorage: BlockerListETagStorage = UserDefaultsETagStorage()) {
34+
init(etagStorage: BlockerListETagStorage = UserDefaultsETagStorage(), fileStore: FileStore = FileStore()) {
3435
self.etagStorage = etagStorage
36+
self.fileStore = fileStore
3537
}
3638

37-
func checkForUpdates(with store: EtagOOSCheckStore,
38-
dataSource: ContentBlockerRemoteDataSource = ContentBlockerRequest()) -> Bool {
39+
func checkForUpdates(dataSource: ContentBlockerRemoteDataSource = ContentBlockerRequest()) -> Bool {
3940

40-
EasylistStore.removeLegacyLists()
41-
4241
self.newData.removeAll()
4342
self.etags.removeAll()
4443

4544
let semaphore = DispatchSemaphore(value: 0)
46-
let numberOfRequests = startRequests(with: semaphore, store: store, dataSource: dataSource)
45+
let numberOfRequests = startRequests(with: semaphore, dataSource: dataSource)
4746

4847
for _ in 0 ..< numberOfRequests {
4948
semaphore.wait()
@@ -57,8 +56,7 @@ public class ContentBlockerLoader {
5756
func applyUpdate(to cache: StorageCacheUpdating) {
5857

5958
for (config, info) in newData {
60-
if (cache.update(config, with: info)),
61-
let etag = etags[config] {
59+
if cache.update(config, with: info), let etag = etags[config] {
6260
etagStorage.set(etag: etag, for: config)
6361
} else {
6462
Logger.log(text: "Failed to apply update to \(config.rawValue)")
@@ -67,13 +65,11 @@ public class ContentBlockerLoader {
6765
}
6866

6967
private func startRequests(with semaphore: DispatchSemaphore,
70-
store: EtagOOSCheckStore,
7168
dataSource: ContentBlockerRemoteDataSource) -> Int {
72-
request(.entitylist, with: dataSource, store: store, semaphore)
73-
request(.disconnectMe, with: dataSource, store: store, semaphore)
74-
request(.trackersWhitelist, with: dataSource, store: store, semaphore)
75-
request(.surrogates, with: dataSource, store: store, semaphore)
7669

70+
request(.surrogates, with: dataSource, semaphore)
71+
request(.trackerDataSet, with: dataSource, semaphore)
72+
request(.temporaryWhitelist, with: dataSource, semaphore)
7773
requestHttpsUpgrade(dataSource, semaphore)
7874
requestHttpsWhitelist(dataSource, semaphore)
7975

@@ -82,7 +78,6 @@ public class ContentBlockerLoader {
8278

8379
fileprivate func request(_ configuration: ContentBlockerRequest.Configuration,
8480
with contentBlockerRequest: ContentBlockerRemoteDataSource,
85-
store: EtagOOSCheckStore,
8681
_ semaphore: DispatchSemaphore) {
8782
contentBlockerRequest.request(configuration) { response in
8883

@@ -94,22 +89,7 @@ public class ContentBlockerLoader {
9489
let isCached = etag != nil && self.etagStorage.etag(for: configuration) == etag
9590
self.etags[configuration] = etag
9691

97-
if isCached {
98-
switch configuration {
99-
case .disconnectMe:
100-
if !store.hasDisconnectMeData {
101-
self.newData[configuration] = data
102-
Pixel.fire(pixel: .etagStoreOOSWithDisconnectMeFix)
103-
}
104-
case .trackersWhitelist:
105-
if !store.hasEasylistData {
106-
self.newData[configuration] = data
107-
Pixel.fire(pixel: .etagStoreOOSWithEasylistFix)
108-
}
109-
default:
110-
break
111-
}
112-
} else {
92+
if !isCached || !self.fileStore.hasData(forConfiguration: configuration) {
11393
self.newData[configuration] = data
11494
}
11595

Core/ContentBlockerRequest.swift

+5-11
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,14 @@ class ContentBlockerRequest: ContentBlockerRemoteDataSource {
3232
case error
3333
case success(etag: String?, data: Data)
3434
}
35-
35+
3636
enum Configuration: String {
37-
case disconnectMe = "disconnectme"
38-
case easylist = "easylist"
39-
case easylistPrivacy = "easyprivacy"
40-
case trackersWhitelist
4137
case httpsBloomFilterSpec
4238
case httpsBloomFilter
4339
case httpsWhitelist
4440
case surrogates
45-
case entitylist = "entitylist2"
41+
case trackerDataSet
42+
case temporaryWhitelist
4643
}
4744

4845
var requestCount = 0
@@ -71,15 +68,12 @@ class ContentBlockerRequest: ContentBlockerRemoteDataSource {
7168
let appUrls = AppUrls()
7269

7370
switch list {
74-
case .disconnectMe: return appUrls.disconnectMeBlockList
75-
case .easylist: return appUrls.easylistBlockList
76-
case .easylistPrivacy: return appUrls.easylistPrivacyBlockList
7771
case .httpsBloomFilterSpec: return appUrls.httpsBloomFilterSpec
7872
case .httpsBloomFilter: return appUrls.httpsBloomFilter
7973
case .httpsWhitelist: return appUrls.httpsWhitelist
80-
case .trackersWhitelist: return appUrls.trackersWhitelist
8174
case .surrogates: return appUrls.surrogates
82-
case .entitylist: return appUrls.entitylist
75+
case .trackerDataSet: return appUrls.trackerDataSet
76+
case .temporaryWhitelist: return appUrls.temporaryWhitelist
8377
}
8478
}
8579
}

Core/ContentBlockerStringCache.swift

+3-42
Original file line numberDiff line numberDiff line change
@@ -21,50 +21,11 @@ import Foundation
2121

2222
public class ContentBlockerStringCache {
2323

24-
struct Constants {
25-
// bump the cache version if you know the cache should be invalidated on the next release
26-
static let cacheVersion = 5
27-
static let cacheVersionKey = "com.duckduckgo.contentblockerstringcache.version"
28-
}
29-
30-
private var cacheDir: URL {
24+
public static func removeLegacyData() {
25+
let fileManager = FileManager.default
3126
let groupName = ContentBlockerStoreConstants.groupName
32-
return fileManager.containerURL(forSecurityApplicationGroupIdentifier: groupName)!.appendingPathComponent("string-cache")
33-
}
34-
35-
private var fileManager: FileManager {
36-
return FileManager.default
37-
}
38-
39-
public init(userDefaults: UserDefaults = UserDefaults.standard) {
40-
let lastSeenVersion = userDefaults.integer(forKey: Constants.cacheVersionKey)
41-
if lastSeenVersion < Constants.cacheVersion {
42-
clearCache()
43-
userDefaults.set(Constants.cacheVersion, forKey: Constants.cacheVersionKey)
44-
}
45-
}
46-
47-
private func clearCache() {
27+
let cacheDir = fileManager.containerURL(forSecurityApplicationGroupIdentifier: groupName)!.appendingPathComponent("string-cache")
4828
try? fileManager.removeItem(atPath: cacheDir.path)
4929
}
5030

51-
public func get(named name: String) -> String? {
52-
return try? String(contentsOf: persistenceLocation(for: name), encoding: .utf8)
53-
}
54-
55-
public func put(name: String, value: String) {
56-
try? value.write(to: persistenceLocation(for: name), atomically: true, encoding: .utf8)
57-
}
58-
59-
public func remove(named name: String) {
60-
try? fileManager.removeItem(at: persistenceLocation(for: name))
61-
}
62-
63-
private func persistenceLocation(for name: String) -> URL {
64-
try? fileManager.createDirectory(at: cacheDir, withIntermediateDirectories: true, attributes: nil)
65-
let location = cacheDir.appendingPathComponent(name)
66-
Logger.log(text: "cache \(name) \(location)")
67-
return location
68-
}
69-
7031
}

Core/DetectedTracker.swift

+18-26
Original file line numberDiff line numberDiff line change
@@ -19,49 +19,41 @@
1919

2020
import Foundation
2121

22-
// Populated with relevant info at the point of detection. If networkName or category are nil, they are genuinely not known.
22+
// Populated with relevant info at the point of detection.
2323
public struct DetectedTracker {
2424

2525
public let url: String
26+
public let knownTracker: KnownTracker?
27+
public let entity: Entity?
2628
public let blocked: Bool
27-
public let networkName: String?
28-
public let category: String?
29-
30-
public init(url: String, networkName: String?, category: String?, blocked: Bool) {
29+
30+
public init(url: String, knownTracker: KnownTracker?, entity: Entity?, blocked: Bool) {
3131
self.url = url
32-
self.networkName = networkName
33-
self.category = category
32+
self.knownTracker = knownTracker
33+
self.entity = entity
3434
self.blocked = blocked
3535
}
3636

3737
public var domain: String? {
3838
return URL(string: url)?.host
3939
}
40-
41-
public var isIpTracker: Bool {
42-
return URL.isValidIpHost(domain ?? "")
43-
}
4440

4541
public var networkNameForDisplay: String {
46-
return networkName ?? domain ?? url
42+
return entity?.displayName ?? domain ?? url
4743
}
4844

4945
}
5046

51-
extension DetectedTracker: Hashable {
52-
53-
public func hash( into hasher: inout Hasher) {
54-
hasher.combine(url)
55-
hasher.combine(blocked)
56-
hasher.combine(networkName)
57-
hasher.combine(category)
58-
}
59-
47+
extension DetectedTracker: Hashable, Equatable {
48+
6049
public static func == (lhs: DetectedTracker, rhs: DetectedTracker) -> Bool {
61-
return lhs.url == rhs.url
62-
&& lhs.blocked == rhs.blocked
63-
&& lhs.networkName == rhs.networkName
64-
&& lhs.category == rhs.category
50+
return ((lhs.entity != nil || rhs.entity != nil) && lhs.entity?.displayName == rhs.entity?.displayName)
51+
&& lhs.domain ?? "" == rhs.domain ?? ""
6552
}
66-
53+
54+
public func hash(into hasher: inout Hasher) {
55+
hasher.combine(self.entity?.displayName)
56+
hasher.combine(self.domain)
57+
}
58+
6759
}

0 commit comments

Comments
 (0)