After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 756 B |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 851 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 695 B |
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 349 B After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 373 B |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 1021 B |
After Width: | Height: | Size: 738 B |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 796 B |
Before Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 689 B |
Before Width: | Height: | Size: 1.5 KiB |
@ -1,864 +0,0 @@
|
||||
'use strict'
|
||||
;(function () {
|
||||
const MIN_FF_MAJOR_VERSION = 51
|
||||
|
||||
let areListenersRegistered = false
|
||||
const secBefore = 2000
|
||||
const secAfter = 5000
|
||||
const secBetweenDupAssets = 10e3
|
||||
const minVidSize = 500e3
|
||||
const maxVidSize = 25e6
|
||||
const maxContentRange = 25e6
|
||||
const videoExtensions = [
|
||||
'af',
|
||||
'3gp',
|
||||
'asf',
|
||||
'avchd',
|
||||
'avi',
|
||||
'cam',
|
||||
'dsh',
|
||||
'flv',
|
||||
'm1v',
|
||||
'm2v',
|
||||
'fla',
|
||||
'flr',
|
||||
'sol',
|
||||
'm4v',
|
||||
'mkv',
|
||||
'wrap',
|
||||
'mng',
|
||||
'mov',
|
||||
'mpeg',
|
||||
'mpg',
|
||||
'mpe',
|
||||
'mp4',
|
||||
'mxf',
|
||||
'nsv',
|
||||
'ogg',
|
||||
'rm',
|
||||
'svi',
|
||||
'smi',
|
||||
'wmv',
|
||||
'webm',
|
||||
]
|
||||
const extensionsReg = new RegExp('\\.' + videoExtensions.join('$|\\.') + '$')
|
||||
const videoContentTypesPrefixes = [
|
||||
'binary/octet-stream',
|
||||
'video/',
|
||||
'flv-application/',
|
||||
'media',
|
||||
]
|
||||
|
||||
const bannedContentTypes = ['video/mp2t', 'video/f4m', 'video/f4f']
|
||||
const bannedFiletypes = ['ts']
|
||||
const bannedFiletypesReg = new RegExp(
|
||||
'\\.' + bannedFiletypes.join('$|\\.') + '$'
|
||||
)
|
||||
const whitelistReqTypes = ['object', 'xmlhttprequest', 'other']
|
||||
|
||||
const topVideoAssetDomains = [
|
||||
'2mdn.net',
|
||||
'adap.tv',
|
||||
'adnxs.com',
|
||||
'adsrvr.org',
|
||||
'btrll.com',
|
||||
'celtra.com',
|
||||
'flashtalking.com',
|
||||
'flite.com',
|
||||
'innovid.com',
|
||||
'jivox.com',
|
||||
'mixpo.com',
|
||||
'nytimes.com',
|
||||
'playwire.com',
|
||||
'selectmedia.asia',
|
||||
'serving-sys.com',
|
||||
'solvemedia.com',
|
||||
'spotible.com',
|
||||
'teads.tv',
|
||||
'tribalfusion.com',
|
||||
'tubemogul.com',
|
||||
'videologygroup.com',
|
||||
'washingtonpost.com',
|
||||
]
|
||||
|
||||
const robotsTxtAllows = Driver.checkRobots
|
||||
if (!String.prototype.endsWith) {
|
||||
String.prototype.endsWith = function (searchString, position) {
|
||||
const subjectString = this.toString()
|
||||
if (
|
||||
typeof position !== 'number' ||
|
||||
!isFinite(position) ||
|
||||
Math.floor(position) !== position ||
|
||||
position > subjectString.length
|
||||
) {
|
||||
position = subjectString.length
|
||||
}
|
||||
position -= searchString.length
|
||||
const lastIndex = subjectString.indexOf(searchString, position)
|
||||
return lastIndex !== -1 && lastIndex === position
|
||||
}
|
||||
}
|
||||
|
||||
function getFrame(getFrameDetails, callback) {
|
||||
chrome.webNavigation.getFrame(getFrameDetails, callback)
|
||||
}
|
||||
|
||||
function ifTrackingEnabled(details, ifCallback, elseCallback) {
|
||||
const fullIfCallback = function () {
|
||||
allowedByRobotsTxt(details, ifCallback, elseCallback)
|
||||
}
|
||||
|
||||
Utils.getOption('tracking', true).then(function (tracking) {
|
||||
if (tracking) {
|
||||
fullIfCallback()
|
||||
} else {
|
||||
elseCallback()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function allowedByRobotsTxt(details, ifCallback, elseCallback) {
|
||||
if (details.url && !details.url.startsWith('chrome://')) {
|
||||
Driver.checkRobots(details.url, details.url.startsWith('https:'))
|
||||
.then(ifCallback)
|
||||
.catch(elseCallback)
|
||||
} else {
|
||||
elseCallback()
|
||||
}
|
||||
}
|
||||
|
||||
function isPixelRequest(request) {
|
||||
return (
|
||||
(request.type === 'image' || request.responseStatus === 204) &&
|
||||
request.size <= 1000
|
||||
)
|
||||
}
|
||||
|
||||
function isVpaidOrVastRequest(request) {
|
||||
const lowerCaseUrl = request.url.toLowerCase()
|
||||
return lowerCaseUrl.includes('vpaid') || lowerCaseUrl.includes('vast')
|
||||
}
|
||||
|
||||
function hasValidRequestType(request) {
|
||||
return whitelistReqTypes.includes(request.type)
|
||||
}
|
||||
|
||||
function stripQueryParams(url) {
|
||||
return url.split('?', 1)[0]
|
||||
}
|
||||
|
||||
function parseHostnameFromUrl(url) {
|
||||
try {
|
||||
const { hostname } = new URL(url)
|
||||
|
||||
return hostname
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function hasDomain(url, domain) {
|
||||
return parseHostnameFromUrl(url).endsWith(domain)
|
||||
}
|
||||
|
||||
function findHeader(headers, key) {
|
||||
let header
|
||||
for (let i = 0; i < headers.length; i += 1) {
|
||||
header = headers[i]
|
||||
if (header.name.toLowerCase() === key) {
|
||||
return header
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function validVideoType(vtype) {
|
||||
const goodType = videoContentTypesPrefixes.some(function (prefix) {
|
||||
return vtype.indexOf(prefix) === 0
|
||||
})
|
||||
return goodType
|
||||
}
|
||||
|
||||
function assetMsgKey(assetReq) {
|
||||
const url = stripQueryParams(assetReq.url)
|
||||
const key = assetReq.frameId + '-' + url
|
||||
return key
|
||||
}
|
||||
|
||||
const PageNetworkTrafficCollector = function (tabId) {
|
||||
this.tabId = tabId
|
||||
this.displayAdFound = false
|
||||
this.requests = {}
|
||||
this.msgsBeingSent = {}
|
||||
this.assetsSeen = {}
|
||||
this.allRedirects = {}
|
||||
}
|
||||
|
||||
var globalPageContainer = {
|
||||
collectors: {},
|
||||
dyingCollectors: {},
|
||||
|
||||
cleanupCollector(tabId) {
|
||||
if (tabId in this.collectors) {
|
||||
delete globalPageContainer.collectors[tabId]
|
||||
}
|
||||
},
|
||||
|
||||
onNewNavigation(details) {
|
||||
const tabId = details.tabId
|
||||
this.cleanupCollector(tabId)
|
||||
|
||||
ifTrackingEnabled(
|
||||
details,
|
||||
function () {
|
||||
if (!areListenersRegistered) {
|
||||
registerListeners()
|
||||
}
|
||||
this.collectors[tabId] = new PageNetworkTrafficCollector(tabId)
|
||||
}.bind(this),
|
||||
function () {
|
||||
if (areListenersRegistered) {
|
||||
unregisterListeners()
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
onNavigationCommitted(details) {},
|
||||
|
||||
onNavigationCompleted(details) {},
|
||||
|
||||
onTabClose(tabId, closeInfo) {
|
||||
this.cleanupCollector(tabId)
|
||||
delete this.collectors[tabId]
|
||||
},
|
||||
|
||||
onDisplayAdFound(tabId) {
|
||||
this.collectors[tabId].displayAdFound = true
|
||||
},
|
||||
|
||||
getRandId() {
|
||||
return String(Math.floor(Math.random() * 1e9))
|
||||
},
|
||||
|
||||
getCollector(tabId) {
|
||||
if (this.collectors.hasOwnProperty(tabId)) {
|
||||
return this.collectors[tabId]
|
||||
}
|
||||
return null
|
||||
},
|
||||
|
||||
forwardCall(details, collectorMemberFunction) {
|
||||
const collector = this.getCollector(details.tabId)
|
||||
if (collector !== null) {
|
||||
collectorMemberFunction.apply(collector, [details])
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.sendLogMessageToTabConsole = function () {
|
||||
const logMessage = Array.from(arguments).join(' ')
|
||||
const message = { message: logMessage, event: 'console-log-message' }
|
||||
chrome.tabs.sendMessage(this.tabId, message)
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.sendToTab = function (
|
||||
assetReq,
|
||||
reqs,
|
||||
curPageUrl,
|
||||
adTrackingEvent
|
||||
) {
|
||||
const msg = {}
|
||||
msg.assets = []
|
||||
msg.requests = []
|
||||
msg.event_data = {}
|
||||
msg.event = adTrackingEvent
|
||||
if (adTrackingEvent === 'new-video-ad') {
|
||||
msg.requests = reqs
|
||||
msg.requests.sort(function (reqA, reqB) {
|
||||
return reqA.requestTimestamp - reqB.requestTimestamp
|
||||
})
|
||||
if (assetReq) {
|
||||
msg.assets = [assetReq]
|
||||
}
|
||||
} else if (adTrackingEvent === 'new-invalid-video-ad') {
|
||||
msg.requests = reqs.map(function (request) {
|
||||
return parseHostnameFromUrl(request.url)
|
||||
})
|
||||
msg.assets = [
|
||||
{
|
||||
url: parseHostnameFromUrl(assetReq.url),
|
||||
|
||||
contentType: assetReq.contentType,
|
||||
size: assetReq.size,
|
||||
},
|
||||
]
|
||||
}
|
||||
msg.origUrl = curPageUrl
|
||||
msg.displayAdFound = this.displayAdFound
|
||||
|
||||
chrome.tabs.sendMessage(this.tabId, msg)
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.getRedirKey = function (url, frameId) {
|
||||
return url + ':' + frameId
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.seenBefore = function (request) {
|
||||
const oldTime = this.assetsSeen[assetMsgKey(request)]
|
||||
if (oldTime && request.requestTimestamp - oldTime < secBetweenDupAssets) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.recordSeenAsset = function (request) {
|
||||
this.assetsSeen[assetMsgKey(request)] = request.requestTimestamp
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.onBeforeRequest = function (details) {
|
||||
const req = {
|
||||
url: details.url,
|
||||
type: details.type,
|
||||
httpMethod: details.method,
|
||||
frameId: details.frameId,
|
||||
parentFrameId: details.parentFrameId,
|
||||
requestTimestamp: details.timeStamp,
|
||||
}
|
||||
this.requests[details.requestId] = req
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.onSendHeaders = function (details) {
|
||||
let request, header
|
||||
request = this.requests[details.requestId]
|
||||
header = request && findHeader(details.requestHeaders, 'x-requested-with')
|
||||
if (header && header.value.toLowerCase().includes('flash')) {
|
||||
request.from_flash = true
|
||||
}
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.onHeadersReceived = function (details) {
|
||||
const getFrameDetails = {
|
||||
tabId: details.tabId,
|
||||
processId: null,
|
||||
frameId: details.frameId,
|
||||
}
|
||||
const pageNetworkTrafficController = this
|
||||
getFrame(getFrameDetails, function (frameDetails) {
|
||||
if (frameDetails && frameDetails.url) {
|
||||
pageNetworkTrafficController._onHeadersReceived(details, frameDetails)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype._onHeadersReceived = function (
|
||||
details,
|
||||
frameDetails
|
||||
) {
|
||||
let contentSize, contentRange
|
||||
|
||||
const request = this.requests[details.requestId]
|
||||
if (request) {
|
||||
const redirParent = this.allRedirects[
|
||||
this.getRedirKey(details.url, details.frameId)
|
||||
]
|
||||
let header =
|
||||
request && findHeader(details.responseHeaders, 'content-type')
|
||||
const contentType = header && header.value.toLowerCase()
|
||||
|
||||
if (contentType) {
|
||||
request.contentType = contentType
|
||||
}
|
||||
header = request && findHeader(details.responseHeaders, 'content-length')
|
||||
contentSize = header && header.value
|
||||
if (contentSize) {
|
||||
request.size = request.size || 0
|
||||
request.size += parseInt(contentSize)
|
||||
}
|
||||
header = request && findHeader(details.responseHeaders, 'content-range')
|
||||
contentRange = header && header.value
|
||||
if (contentRange) {
|
||||
request.contentRange = parseInt(contentRange.split('/')[1])
|
||||
}
|
||||
|
||||
let frameUrl = null
|
||||
if (frameDetails && frameDetails.url) {
|
||||
frameUrl = frameDetails.url
|
||||
}
|
||||
if (
|
||||
!this.bannedRequest(request) &&
|
||||
(this.isVideoReq(frameUrl, request) ||
|
||||
(redirParent && redirParent.isVideo))
|
||||
) {
|
||||
request.isVideo = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.onBeforeRedirect = function (details) {
|
||||
const request = this.requests[details.requestId]
|
||||
if (request) {
|
||||
if (request.redirects) {
|
||||
request.redirects.push(details.redirectUrl)
|
||||
} else {
|
||||
request.redirects = [details.redirectUrl]
|
||||
}
|
||||
this.allRedirects[
|
||||
this.getRedirKey(details.redirectUrl, details.frameId)
|
||||
] = request
|
||||
}
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.isYoutubeMastheadRequest = function (
|
||||
url
|
||||
) {
|
||||
const re = /video_masthead/
|
||||
return this.hasYoutubeDomain(url) && re.test(url)
|
||||
}
|
||||
PageNetworkTrafficCollector.prototype.isYoutubeVideoRequest = function (
|
||||
srcUrl,
|
||||
destUrl
|
||||
) {
|
||||
if (!this.hasYoutubeDomain(srcUrl)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const re = /https?:\/\/r.*?\.googlevideo\.com\/videoplayback\?/
|
||||
return re.test(destUrl)
|
||||
}
|
||||
PageNetworkTrafficCollector.prototype.processResponse = function (
|
||||
requestDetails,
|
||||
frameDetails
|
||||
) {
|
||||
let request
|
||||
if (requestDetails) {
|
||||
request = this.requests[requestDetails.requestId]
|
||||
if (request) {
|
||||
request.responseStatus = requestDetails.statusCode
|
||||
request.responseTimestamp = requestDetails.timeStamp
|
||||
|
||||
let frameUrl = null
|
||||
if (frameDetails && frameDetails.url) {
|
||||
frameUrl = frameDetails.url
|
||||
}
|
||||
|
||||
let requestUrl = null
|
||||
if (request.url) {
|
||||
requestUrl = request.url
|
||||
}
|
||||
|
||||
if (this.isYoutubeAdReq(frameUrl, requestUrl)) {
|
||||
const destVideoId = this.parseYoutubeVideoIdFromUrl(requestUrl)
|
||||
const srcVideoId = this.parseYoutubeVideoIdFromUrl(frameUrl)
|
||||
if (srcVideoId && destVideoId) {
|
||||
request.isYoutubeAd = true
|
||||
request.isVideo = true
|
||||
request.rawSrcUrl = frameUrl
|
||||
request.rawDestUrl = requestUrl
|
||||
request.url =
|
||||
'https://www.youtube.com/watch?v=' +
|
||||
this.parseYoutubeVideoIdFromUrl(requestUrl)
|
||||
}
|
||||
} else if (
|
||||
!this.bannedRequest(request) &&
|
||||
(this.isVideo || this.isVideoReq(frameUrl, request))
|
||||
) {
|
||||
request.isVideo = true
|
||||
}
|
||||
|
||||
if (request.isVideo) {
|
||||
const msgKey = assetMsgKey(request)
|
||||
this.msgsBeingSent[msgKey] = request
|
||||
if (!this.seenBefore(request)) {
|
||||
this.sendMsgWhenQuiet(msgKey)
|
||||
}
|
||||
this.recordSeenAsset(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.onResponseStarted = function (
|
||||
responseDetails
|
||||
) {
|
||||
if (responseDetails.frameId < 0) {
|
||||
responseDetails.frameId = 99999
|
||||
}
|
||||
const getFrameDetails = {
|
||||
tabId: responseDetails.tabId,
|
||||
processId: null,
|
||||
frameId: responseDetails.frameId,
|
||||
}
|
||||
const pageNetworkTrafficController = this
|
||||
getFrame(getFrameDetails, function (frameDetails) {
|
||||
if (frameDetails && frameDetails.url) {
|
||||
pageNetworkTrafficController.processResponse(
|
||||
responseDetails,
|
||||
frameDetails
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.hasBannedFiletype = function (request) {
|
||||
const url = stripQueryParams(request.url)
|
||||
if (bannedFiletypesReg.exec(url)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.checkContentHeaders = function (
|
||||
request
|
||||
) {
|
||||
if (request.contentType && validVideoType(request.contentType)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.checkUrlExtension = function (request) {
|
||||
const url = stripQueryParams(request.url)
|
||||
if (extensionsReg.exec(url)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.isVideoReq = function (
|
||||
srcUrl,
|
||||
request
|
||||
) {
|
||||
if (this.isYoutubeVideoRequest(srcUrl, request.url)) {
|
||||
return false
|
||||
}
|
||||
return this.checkUrlExtension(request) || this.checkContentHeaders(request)
|
||||
}
|
||||
PageNetworkTrafficCollector.prototype.hasYoutubeDomain = function (url) {
|
||||
const hostname = parseHostnameFromUrl(url)
|
||||
if (hostname === 'www.youtube.com') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
PageNetworkTrafficCollector.prototype.parseYoutubeVideoIdFromUrl = function (
|
||||
url
|
||||
) {
|
||||
let re = /^https?:\/\/www\.youtube\.com\/get_video_info.*(?:\?|&)video_id=(.*?)(?:$|&)/
|
||||
let match = re.exec(url)
|
||||
if (match && match.length > 1) {
|
||||
return match[1]
|
||||
}
|
||||
|
||||
re = /^https?:\/\/www\.youtube\.com\/embed\/(.*?)(?:$|\?)/
|
||||
match = re.exec(url)
|
||||
if (match && match.length > 1) {
|
||||
return match[1]
|
||||
}
|
||||
|
||||
re = /^https?:\/\/www\.youtube\.com\/watch.*(\?|&)v=([^&]*)/
|
||||
match = re.exec(url)
|
||||
if (match && match.length > 1) {
|
||||
return match[1]
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.isYoutubeGetVideoInfoReq = function (
|
||||
url
|
||||
) {
|
||||
const re = /^https?:\/\/www\.youtube\.com\/get_video_info\?/
|
||||
return re.test(url)
|
||||
}
|
||||
PageNetworkTrafficCollector.prototype.isYoutubeAdReq = function (
|
||||
srcUrl,
|
||||
destUrl
|
||||
) {
|
||||
if (
|
||||
!this.hasYoutubeDomain(srcUrl) ||
|
||||
!this.isYoutubeGetVideoInfoReq(destUrl)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
if (
|
||||
this.parseYoutubeVideoIdFromUrl(srcUrl) ===
|
||||
this.parseYoutubeVideoIdFromUrl(destUrl) &&
|
||||
!this.isYoutubeMastheadRequest(destUrl)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.bannedRequest = function (request) {
|
||||
return (
|
||||
this.bannedVideoType(request) ||
|
||||
this.hasBannedFiletype(request) ||
|
||||
this.bannedVideoSize(request)
|
||||
)
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.bannedVideoType = function (request) {
|
||||
let badType = false
|
||||
if (request.contentType) {
|
||||
badType = bannedContentTypes.some(function (prefix) {
|
||||
return request.contentType.includes(prefix)
|
||||
})
|
||||
}
|
||||
return badType
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.bannedVideoSize = function (request) {
|
||||
if (request.size !== null) {
|
||||
if (
|
||||
request.size < minVidSize ||
|
||||
request.size > maxVidSize ||
|
||||
request.contentRange > maxContentRange
|
||||
) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.grabTagReqs = function (
|
||||
tabRequests,
|
||||
assetRequest
|
||||
) {
|
||||
let minTimestamp, maxTimestamp
|
||||
minTimestamp = assetRequest.requestTimestamp - secBefore
|
||||
maxTimestamp = assetRequest.requestTimestamp + secAfter
|
||||
|
||||
const filteredRequests = tabRequests.filter(function (request) {
|
||||
return (
|
||||
request.requestTimestamp > minTimestamp &&
|
||||
request.requestTimestamp < maxTimestamp &&
|
||||
request.frameId === assetRequest.frameId &&
|
||||
request.url !== assetRequest.url &&
|
||||
(hasValidRequestType(request) || isPixelRequest(request))
|
||||
)
|
||||
})
|
||||
|
||||
return filteredRequests
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.isValidVideoAd = function (
|
||||
assetRequest,
|
||||
tagRequests
|
||||
) {
|
||||
const hasVpaidOrVastRequest = tagRequests.some(function (tagRequest) {
|
||||
return isVpaidOrVastRequest(tagRequest)
|
||||
})
|
||||
|
||||
if (assetRequest.isYoutubeAd) {
|
||||
return true
|
||||
}
|
||||
if (hasVpaidOrVastRequest) {
|
||||
return true
|
||||
}
|
||||
const hasTopVideoAssetDomain = topVideoAssetDomains.some(function (
|
||||
assetDomain
|
||||
) {
|
||||
return hasDomain(assetRequest.url, assetDomain)
|
||||
})
|
||||
|
||||
return hasTopVideoAssetDomain
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.sendMsgWhenQuiet = function (msgKey) {
|
||||
const _this = this
|
||||
let origPageUrl
|
||||
let msgAssetReq
|
||||
msgAssetReq = this.msgsBeingSent[msgKey]
|
||||
chrome.tabs.get(this.tabId, function (tab) {
|
||||
origPageUrl = tab.url
|
||||
})
|
||||
|
||||
setTimeout(function () {
|
||||
const rawRequests = []
|
||||
if (globalPageContainer.collectors[_this.tabId] === _this) {
|
||||
for (const reqId in _this.requests) {
|
||||
rawRequests.push(_this.requests[reqId])
|
||||
}
|
||||
const tagReqs = _this.grabTagReqs(rawRequests, msgAssetReq)
|
||||
|
||||
if (_this.isValidVideoAd(msgAssetReq, tagReqs)) {
|
||||
_this.sendToTab(msgAssetReq, tagReqs, origPageUrl, 'new-video-ad')
|
||||
} else {
|
||||
_this.sendToTab(
|
||||
msgAssetReq,
|
||||
tagReqs,
|
||||
origPageUrl,
|
||||
'new-invalid-video-ad'
|
||||
)
|
||||
}
|
||||
} else {
|
||||
}
|
||||
delete _this.msgsBeingSent[msgKey]
|
||||
}, secAfter + secBefore)
|
||||
}
|
||||
|
||||
PageNetworkTrafficCollector.prototype.existingMessage = function (
|
||||
candidateRequest
|
||||
) {
|
||||
const frameMsg = this.msgsBeingSent[candidateRequest.frameId]
|
||||
if (frameMsg) {
|
||||
return frameMsg
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function onBeforeRequestListener(details) {
|
||||
globalPageContainer.forwardCall(
|
||||
details,
|
||||
PageNetworkTrafficCollector.prototype.onBeforeRequest
|
||||
)
|
||||
}
|
||||
|
||||
function onSendHeadersListener(details) {
|
||||
globalPageContainer.forwardCall(
|
||||
details,
|
||||
PageNetworkTrafficCollector.prototype.onSendHeaders
|
||||
)
|
||||
}
|
||||
|
||||
function onHeadersReceivedListener(details) {
|
||||
globalPageContainer.forwardCall(
|
||||
details,
|
||||
PageNetworkTrafficCollector.prototype.onHeadersReceived
|
||||
)
|
||||
}
|
||||
|
||||
function onBeforeRedirectListener(details) {
|
||||
globalPageContainer.forwardCall(
|
||||
details,
|
||||
PageNetworkTrafficCollector.prototype.onBeforeRedirect
|
||||
)
|
||||
}
|
||||
|
||||
function onResponseStartedListener(details) {
|
||||
globalPageContainer.forwardCall(
|
||||
details,
|
||||
PageNetworkTrafficCollector.prototype.onResponseStarted
|
||||
)
|
||||
}
|
||||
|
||||
function onCommittedListener(details) {
|
||||
if (details.frameId === 0) {
|
||||
globalPageContainer.onNavigationCommitted(details)
|
||||
}
|
||||
}
|
||||
|
||||
function onCompletedListener(details) {
|
||||
if (details.frameId === 0) {
|
||||
globalPageContainer.onNavigationCompleted(details)
|
||||
}
|
||||
}
|
||||
|
||||
function onRemovedListener(tabId, closeInfo) {
|
||||
globalPageContainer.onTabClose(tabId, closeInfo)
|
||||
}
|
||||
|
||||
function onMessageListener(message, sender, sendResponse) {
|
||||
if (message.event === 'new-ad' && message.data.event === 'ad') {
|
||||
const tabId = sender.tab.id
|
||||
if (tabId) {
|
||||
globalPageContainer.onDisplayAdFound(tabId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerListeners() {
|
||||
chrome.webRequest.onBeforeRequest.addListener(
|
||||
onBeforeRequestListener,
|
||||
{ urls: ['http://*/*', 'https://*/*'] },
|
||||
[]
|
||||
)
|
||||
|
||||
chrome.webRequest.onSendHeaders.addListener(
|
||||
onSendHeadersListener,
|
||||
{ urls: ['http://*/*', 'https://*/*'] },
|
||||
['requestHeaders']
|
||||
)
|
||||
|
||||
chrome.webRequest.onHeadersReceived.addListener(
|
||||
onHeadersReceivedListener,
|
||||
{ urls: ['http://*/*', 'https://*/*'] },
|
||||
['responseHeaders']
|
||||
)
|
||||
|
||||
chrome.webRequest.onBeforeRedirect.addListener(
|
||||
onBeforeRedirectListener,
|
||||
{ urls: ['http://*/*', 'https://*/*'] },
|
||||
[]
|
||||
)
|
||||
|
||||
chrome.webRequest.onResponseStarted.addListener(
|
||||
onResponseStartedListener,
|
||||
{ urls: ['http://*/*', 'https://*/*'] },
|
||||
['responseHeaders']
|
||||
)
|
||||
|
||||
chrome.webNavigation.onCommitted.addListener(onCommittedListener)
|
||||
chrome.webNavigation.onCompleted.addListener(onCompletedListener)
|
||||
chrome.tabs.onRemoved.addListener(onRemovedListener)
|
||||
chrome.runtime.onMessage.addListener(onMessageListener)
|
||||
|
||||
areListenersRegistered = true
|
||||
}
|
||||
|
||||
function unregisterListeners() {
|
||||
chrome.webRequest.onBeforeRequest.removeListener(onBeforeRequestListener)
|
||||
|
||||
chrome.webRequest.onSendHeaders.removeListener(onSendHeadersListener)
|
||||
|
||||
chrome.webRequest.onHeadersReceived.removeListener(
|
||||
onHeadersReceivedListener
|
||||
)
|
||||
|
||||
chrome.webRequest.onBeforeRedirect.removeListener(onBeforeRedirectListener)
|
||||
|
||||
chrome.webRequest.onResponseStarted.removeListener(
|
||||
onResponseStartedListener
|
||||
)
|
||||
|
||||
chrome.webNavigation.onCommitted.removeListener(onCommittedListener)
|
||||
chrome.webNavigation.onCompleted.removeListener(onCompletedListener)
|
||||
chrome.tabs.onRemoved.removeListener(onRemovedListener)
|
||||
chrome.runtime.onMessage.removeListener(onMessageListener)
|
||||
areListenersRegistered = false
|
||||
}
|
||||
|
||||
chrome.webNavigation.onBeforeNavigate.addListener(
|
||||
function (details) {
|
||||
if (details.frameId === 0) {
|
||||
globalPageContainer.onNewNavigation(details)
|
||||
}
|
||||
},
|
||||
{
|
||||
url: [{ urlMatches: 'http://*/*' }, { urlMatches: 'https://*/*' }],
|
||||
}
|
||||
)
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, callback) => {
|
||||
if (message === 'is_tracking_enabled') {
|
||||
ifTrackingEnabled(
|
||||
sender.tab,
|
||||
function () {
|
||||
try {
|
||||
callback({ tracking_enabled: true })
|
||||
} catch (err) {}
|
||||
},
|
||||
function () {
|
||||
try {
|
||||
callback({ tracking_enabled: false })
|
||||
} catch (err) {}
|
||||
}
|
||||
)
|
||||
}
|
||||
return true
|
||||
})
|
||||
})()
|