Skip to content

Commit

Permalink
Fix brave/brave-ios#8562: Update Tracking Protection Stats (brave/bra…
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon-T authored Jan 10, 2024
1 parent 24aac02 commit 3d4aa5b
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extension ContentBlockerHelper: TabContentScript {
}

let securityToken: String
let data: ContentblockerDTOData
let data: [ContentblockerDTOData]
}

static let scriptName = "TrackingProtectionStats"
Expand Down Expand Up @@ -62,71 +62,73 @@ extension ContentBlockerHelper: TabContentScript {

do {
let data = try JSONSerialization.data(withJSONObject: message.body)
let dto = try JSONDecoder().decode(ContentBlockerDTO.self, from: data)

Task { @MainActor in
let isPrivateBrowsing = self.tab?.isPrivate == true
let domain = Domain.getOrCreate(forUrl: currentTabURL, persistent: !isPrivateBrowsing)
if domain.areAllShieldsOff {
// if domain is "all_off", can just skip
return
}

if dto.data.resourceType == .script && domain.isShieldExpected(.NoScript, considerAllShieldsOption: true) {
self.stats = self.stats.adding(scriptCount: 1)
BraveGlobalShieldStats.shared.scripts += 1
return
}

// Because javascript urls allow some characters that `URL` does not,
// we use `NSURL(idnString: String)` to parse them
guard let requestURL = NSURL(idnString: dto.data.resourceURL) as URL? else { return }
guard let sourceURL = NSURL(idnString: dto.data.sourceURL) as URL? else { return }
guard let domainURLString = domain.url else { return }
let genericTypes = ContentBlockerManager.shared.validGenericTypes(for: domain)

let blockedType = await TPStatsBlocklistChecker.shared.blockedTypes(
requestURL: requestURL,
sourceURL: sourceURL,
enabledRuleTypes: genericTypes,
resourceType: dto.data.resourceType,
isAggressiveMode: domain.blockAdsAndTrackingLevel.isAggressive
)

guard let blockedType = blockedType else { return }

assertIsMainThread("Result should happen on the main thread")

// Ensure we check that the stats we're tracking is still for the same page
// Some web pages (like youtube) like to rewrite their main frame urls
// so we check the source etld+1 agains the tab url etld+1
// For subframes which may use different etld+1 than the main frame (example `reddit.com` and `redditmedia.com`)
// We simply check the known subframeURLs on this page.
guard self.tab?.url?.baseDomain == sourceURL.baseDomain ||
self.tab?.currentPageData?.allSubframeURLs.contains(sourceURL) == true else {
return
}

if blockedType == .ad, Preferences.PrivacyReports.captureShieldsData.value,
let domainURL = URL(string: domainURLString),
let blockedResourceHost = requestURL.baseDomain,
tab?.isPrivate != true {
PrivacyReportsManager.pendingBlockedRequests.append((blockedResourceHost, domainURL, Date()))
}

// First check to make sure we're not counting the same repetitive requests multiple times
guard !self.blockedRequests.contains(requestURL) else { return }
self.blockedRequests.insert(requestURL)

// Increase global stats (here due to BlocklistName being in Client and BraveGlobalShieldStats being
// in BraveShared)
let stats = BraveGlobalShieldStats.shared
switch blockedType {
case .ad:
stats.adblock += 1
self.stats = self.stats.adding(adCount: 1)
case .image:
stats.images += 1
let dtos = try JSONDecoder().decode(ContentBlockerDTO.self, from: data).data

dtos.forEach { dto in
Task { @MainActor in
let isPrivateBrowsing = self.tab?.isPrivate == true
let domain = Domain.getOrCreate(forUrl: currentTabURL, persistent: !isPrivateBrowsing)
if domain.areAllShieldsOff {
// if domain is "all_off", can just skip
return
}

if dto.resourceType == .script && domain.isShieldExpected(.NoScript, considerAllShieldsOption: true) {
self.stats = self.stats.adding(scriptCount: 1)
BraveGlobalShieldStats.shared.scripts += 1
return
}

// Because javascript urls allow some characters that `URL` does not,
// we use `NSURL(idnString: String)` to parse them
guard let requestURL = NSURL(idnString: dto.resourceURL) as URL? else { return }
guard let sourceURL = NSURL(idnString: dto.sourceURL) as URL? else { return }
guard let domainURLString = domain.url else { return }
let genericTypes = ContentBlockerManager.shared.validGenericTypes(for: domain)

let blockedType = await TPStatsBlocklistChecker.shared.blockedTypes(
requestURL: requestURL,
sourceURL: sourceURL,
enabledRuleTypes: genericTypes,
resourceType: dto.resourceType,
isAggressiveMode: domain.blockAdsAndTrackingLevel.isAggressive
)

guard let blockedType = blockedType else { return }

assertIsMainThread("Result should happen on the main thread")

// Ensure we check that the stats we're tracking is still for the same page
// Some web pages (like youtube) like to rewrite their main frame urls
// so we check the source etld+1 agains the tab url etld+1
// For subframes which may use different etld+1 than the main frame (example `reddit.com` and `redditmedia.com`)
// We simply check the known subframeURLs on this page.
guard self.tab?.url?.baseDomain == sourceURL.baseDomain ||
self.tab?.currentPageData?.allSubframeURLs.contains(sourceURL) == true else {
return
}

if blockedType == .ad, Preferences.PrivacyReports.captureShieldsData.value,
let domainURL = URL(string: domainURLString),
let blockedResourceHost = requestURL.baseDomain,
tab?.isPrivate != true {
PrivacyReportsManager.pendingBlockedRequests.append((blockedResourceHost, domainURL, Date()))
}

// First check to make sure we're not counting the same repetitive requests multiple times
guard !self.blockedRequests.contains(requestURL) else { return }
self.blockedRequests.insert(requestURL)

// Increase global stats (here due to BlocklistName being in Client and BraveGlobalShieldStats being
// in BraveShared)
let stats = BraveGlobalShieldStats.shared
switch blockedType {
case .ad:
stats.adblock += 1
self.stats = self.stats.adding(adCount: 1)
case .image:
stats.images += 1
}
}
}
} catch {
Expand Down
Loading

0 comments on commit 3d4aa5b

Please sign in to comment.