Index: lib/requestBlocker.js |
=================================================================== |
--- a/lib/requestBlocker.js |
+++ b/lib/requestBlocker.js |
@@ -73,20 +73,43 @@ |
yield "CSP"; |
}()); |
-function onBeforeRequestAsync(tabId, url, type, docDomain, |
- thirdParty, sitekey, |
- specificOnly, filter) |
+function getRelatedTabIds(details) |
{ |
- let tabIds = tabId != -1 ? [tabId] : []; |
+ // This is the common case, the request is associated with a single tab. |
+ // If tabId is -1, its not (e.g. the request was sent by |
+ // a Service/Shared Worker) and we have to identify the related tabs. |
+ if (details.tabId != -1) |
+ return Promise.resolve([details.tabId]); |
- if (filter) |
- FilterNotifier.emit("filter.hitCount", filter, 0, 0, tabIds); |
+ let url; // Firefox provides "originUrl" indicating the |
+ if (details.originUrl) // URL of the tab that caused this request. |
+ url = details.originUrl; // In case of Service/Shared Worker, this is the |
+ // URL of the tab that caused the worker to spawn. |
- devtools.logRequest( |
- tabIds, url, type, docDomain, |
- thirdParty, sitekey, |
- specificOnly, filter |
- ); |
+ else if (details.initiator) // Chromium >=63 provides "intiator" which |
+ url = details.initiator + "/*"; // is equivalent to "originUrl" on Firefox |
+ // except that its not a full URL but just |
+ // an origin (proto + host). |
+ else |
+ return Promise.resolve([]); |
kzar
2018/04/05 10:31:51
I wonder if there is a situation where details.ini
Sebastian Noack
2018/04/05 16:56:33
There are two scenarios (I have seen in my testing
kzar
2018/04/09 14:39:18
Sounds reasonable to me, maybe add a note to the i
Sebastian Noack
2018/04/09 21:08:20
There you go: https://issues.adblockplus.org/ticke
|
+ |
+ return browser.tabs.query({url}).then(tabs => tabs.map(tab => tab.id)); |
+} |
+ |
+function logRequest(details, url, type, docDomain, thirdParty, |
+ sitekey, specificOnly, filter) |
+{ |
+ getRelatedTabIds(details).then(tabIds => |
+ { |
+ if (filter) |
+ FilterNotifier.emit("filter.hitCount", filter, 0, 0, tabIds); |
+ |
+ devtools.logRequest( |
+ tabIds, url, type, docDomain, |
+ thirdParty, sitekey, |
+ specificOnly, filter |
+ ); |
+ }); |
} |
browser.webRequest.onBeforeRequest.addListener(details => |
@@ -105,55 +128,57 @@ |
url.protocol != "ws:" && url.protocol != "wss:") |
return; |
- // Firefox (only) allows to intercept requests sent by the browser |
- // and other extensions. We don't want to block these. |
+ let originUrl = null; |
if (details.originUrl) |
{ |
- let originUrl = new URL(details.originUrl); |
+ originUrl = new URL(details.originUrl); |
+ |
+ // Firefox (only) allows to intercept requests sent by the browser |
+ // and other extensions. We don't want to block these. |
if (originUrl.protocol == "chrome:" || |
originUrl.protocol == "moz-extension:") |
return; |
} |
- |
- let frame = ext.getFrame( |
- details.tabId, |
- // We are looking for the frame that contains the element which |
- // has triggered this request. For most requests (e.g. images) we |
- // can just use the request's frame ID, but for subdocument requests |
- // (e.g. iframes) we must instead use the request's parent frame ID. |
- details.type == "sub_frame" ? details.parentFrameId : details.frameId |
- ); |
+ // Fallback to "initiator" on Chrome >=63. It doesn't include the |
+ // path (unlike "originUrl" on Firefox), but is still good enough |
+ // (in case the tab/frame is unknown) for the $domain filter option |
+ // and most document exception rules which only match the domain part. |
+ else if (details.initiator) |
+ originUrl = new URL(details.initiator); |
- let docDomain = null; |
- let sitekey = null; |
- let thirdParty = false; |
- let specificOnly = false; |
- |
- if (frame) |
+ let page = null; |
+ let frame = null; |
+ if (details.tabId != -1) |
{ |
- let page = new ext.Page({id: details.tabId}); |
+ page = new ext.Page({id: details.tabId}); |
+ frame = ext.getFrame( |
+ details.tabId, |
+ // We are looking for the frame that contains the element which |
+ // has triggered this request. For most requests (e.g. images) we |
+ // can just use the request's frame ID, but for subdocument requests |
+ // (e.g. iframes) we must instead use the request's parent frame ID. |
+ details.type == "sub_frame" ? details.parentFrameId : details.frameId |
+ ); |
+ } |
- if (checkWhitelisted(page, frame)) |
- return; |
- |
- docDomain = extractHostFromFrame(frame); |
- sitekey = getKey(page, frame); |
- thirdParty = isThirdParty(url, docDomain); |
- specificOnly = !!checkWhitelisted(page, frame, |
- RegExpFilter.typeMap.GENERICBLOCK); |
- } |
+ if (checkWhitelisted(page, frame, originUrl)) |
+ return; |
let urlString = stringifyURL(url); |
let type = resourceTypes.get(details.type) || "OTHER"; |
+ let docDomain = extractHostFromFrame(frame, originUrl); |
+ let thirdParty = isThirdParty(url, docDomain); |
+ let sitekey = getKey(page, frame, originUrl); |
+ let specificOnly = !!checkWhitelisted(page, frame, originUrl, |
+ RegExpFilter.typeMap.GENERICBLOCK); |
+ |
let filter = defaultMatcher.matchesAny( |
urlString, RegExpFilter.typeMap[type], |
docDomain, thirdParty, sitekey, specificOnly |
); |
- setTimeout(onBeforeRequestAsync, 0, details.tabId, urlString, |
- type, docDomain, |
- thirdParty, sitekey, |
- specificOnly, filter); |
+ logRequest(details, urlString, type, docDomain, |
+ thirdParty, sitekey, specificOnly, filter); |
if (filter instanceof BlockingFilter) |
return {cancel: true}; |
@@ -170,7 +195,7 @@ |
let blocked = false; |
let specificOnly = checkWhitelisted( |
- sender.page, sender.frame, |
+ sender.page, sender.frame, null, |
RegExpFilter.typeMap.GENERICBLOCK |
); |