Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/requestBlocker.js

Issue 29739594: Issue 6543 - Match requests without tabId/frameId in their originating context (Closed)
Patch Set: Created April 2, 2018, 2:55 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/popupBlocker.js ('k') | lib/url.js » ('j') | lib/whitelisting.js » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/requestBlocker.js
===================================================================
--- a/lib/requestBlocker.js
+++ b/lib/requestBlocker.js
@@ -73,20 +73,54 @@
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);
+ // Firefox >=48 provides "originUrl" indicating the URL of the tab
+ // that caused this request. In case of Service/Shared Worker,
+ // this is URL of the tab that caused the worker to be spawned.
+ if (details.originUrl)
kzar 2018/04/03 12:49:30 Nit: Please use braces since the body spans multip
Sebastian Noack 2018/04/04 01:04:45 No longer relevant (the block has only one line no
+ return browser.tabs.query({url: details.originUrl}).then(
+ tabs => tabs.map(tab => tab.id)
+ );
- devtools.logRequest(
- tabIds, url, type, docDomain,
- thirdParty, sitekey,
- specificOnly, filter
- );
+ // Chromium >=63 provides "intiator" which is equivalent to "originUrl" on
+ // Firefox except that its not a full URL but just an origin (proto + host).
+ // So we have to find each tab with an URL of the same origin.
+ if (details.initiator)
+ return browser.tabs.query({}).then(tabs =>
kzar 2018/04/03 12:49:30 Couldn't we pass something like `details.initiator
Sebastian Noack 2018/04/04 01:04:45 In fact we can. I wasn't aware that tab.query() ac
kzar 2018/04/05 10:31:51 Cool, I assumed I was wrong somehow :p. This looks
+ {
+ let tabIds = [];
+ for (let tab of tabs)
+ {
+ if (new URL(tab.url).origin == details.initiator)
+ tabIds.push(tab.id);
kzar 2018/04/03 12:49:30 Wouldn't this mean we sometimes log a request for
Sebastian Noack 2018/04/04 01:04:45 This usually means that the request was sent by a
kzar 2018/04/05 10:31:51 Acknowledged.
+ }
+ return tabIds;
+ });
+
+ return Promise.resolve([]);
+}
+
+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 +139,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 +206,7 @@
let blocked = false;
let specificOnly = checkWhitelisted(
- sender.page, sender.frame,
+ sender.page, sender.frame, null,
RegExpFilter.typeMap.GENERICBLOCK
);
« no previous file with comments | « lib/popupBlocker.js ('k') | lib/url.js » ('j') | lib/whitelisting.js » ('J')

Powered by Google App Engine
This is Rietveld