Index: lib/whitelisting.js |
=================================================================== |
--- a/lib/whitelisting.js |
+++ b/lib/whitelisting.js |
@@ -27,7 +27,7 @@ |
let {port} = require("messaging"); |
let devtools = require("devtools"); |
-let pagesWithKey = new ext.PageMap(); |
+let sitekeys = new ext.PageMap(); |
function match(page, url, typeMask, docDomain, sitekey) |
{ |
@@ -84,6 +84,11 @@ |
return match(page, page.url, typeMask); |
}; |
+port.on("filters.isPageWhitelisted", (message, sender) => |
+{ |
+ return !!checkWhitelisted(sender.page); |
+}); |
+ |
function revalidateWhitelistingState(page) |
{ |
FilterNotifier.triggerListeners( |
@@ -92,32 +97,14 @@ |
); |
} |
-let revalidating = false; |
-FilterNotifier.addListener((action, arg) => |
+FilterNotifier.addListener(action => |
{ |
- switch (action) |
- { |
- case "subscription.added": |
- if (arg instanceof DownloadableSubscription && !arg.lastDownload) |
- break; |
- case "subscription.removed": |
- case "subscription.disabled": |
- case "subscription.updated": |
- case "filter.added": |
- case "filter.removed": |
- case "filter.disabled": |
- case "load": |
- if (!revalidating) |
- { |
- revalidating = true; |
- ext.pages.query({}, pages => |
- { |
- revalidating = false; |
- for (let page of pages) |
- revalidateWhitelistingState(page); |
- }); |
- } |
- } |
+ if (action == "filter.behaviorChanged") |
+ ext.pages.query({}, pages => |
+ { |
+ for (let page of pages) |
+ revalidateWhitelistingState(page); |
+ }); |
}); |
ext.pages.onLoading.addListener(revalidateWhitelistingState); |
@@ -133,13 +120,13 @@ |
*/ |
exports.getKey = function(page, frame) |
{ |
- let urlsWithKey = pagesWithKey.get(page); |
- if (!urlsWithKey) |
+ let keys = sitekeys.get(page); |
+ if (!keys) |
return null; |
for (; frame != null; frame = frame.parent) |
{ |
- let key = urlsWithKey[stringifyURL(frame.url)]; |
+ let key = keys[stringifyURL(frame.url)]; |
if (key) |
return key; |
} |
@@ -147,60 +134,49 @@ |
return null; |
}; |
-function verifyKey(key, signature, url) |
+function recordKey(token, page, url) |
{ |
- let params = [ |
- url.pathname + url.search, // REQUEST_URI |
- url.host, // HTTP_HOST |
- window.navigator.userAgent // HTTP_USER_AGENT |
- ]; |
- |
- return verifySignature(key, signature, params.join("\0")); |
-} |
- |
-function recordKey(page, url, key) |
-{ |
- let urlsWithKey = pagesWithKey.get(page); |
- |
- if (!urlsWithKey) |
- { |
- urlsWithKey = Object.create(null); |
- pagesWithKey.set(page, urlsWithKey); |
- } |
- |
- urlsWithKey[stringifyURL(url)] = key; |
-} |
- |
-let processKey = |
-/** |
- * Validates signatures given by the "X-Adblock-Key" response |
- * header or the "data-adblockkey" attribute of the document |
- * element. If the signature is valid, the public key will be |
- * recorded and considered for the $sitekey filter option. |
- * |
- * @param {string} token The base64-encoded public key and |
- * signature separated by an underscrore. |
- * @param {Page} page |
- * @param {Frame} frame |
- */ |
-exports.processKey = function(token, page, frame) |
-{ |
- if (token.indexOf("_") < 0) |
+ let parts = token.split("_"); |
+ if (parts.length < 2) |
return; |
- let [key, signature] = token.split("_", 2); |
- key = key.replace(/=/g, ""); |
+ let key = parts[0].replace(/=/g, ""); |
+ let signature = parts[1]; |
+ let data = url.pathname + url.search + "\0" + |
+ url.host + "\0" + |
+ window.navigator.userAgent; |
+ if (!verifySignature(key, signature, data)) |
+ return; |
- if (verifyKey(key, signature, frame.url)) |
- recordKey(page, frame.url, key); |
-}; |
+ let keys = sitekeys.get(page); |
+ if (!keys) |
+ { |
+ keys = Object.create(null); |
+ sitekeys.set(page, keys); |
+ } |
+ keys[stringifyURL(url)] = key; |
+} |
port.on("filters.addKey", (message, sender) => |
{ |
- processKey(message.token, sender.page, sender.frame); |
+ recordKey(message.token, sender.page, sender.frame.url); |
}); |
-port.on("filters.isPageWhitelisted", (message, sender) => |
+function onHeadersReceived(details) |
{ |
- return !!checkWhitelisted(sender.page); |
-}); |
+ let page = new ext.Page({id: details.tabId}); |
+ |
+ for (let header of details.responseHeaders) |
+ if (header.name.toLowerCase() == "x-adblock-key" && header.value) |
+ recordKey(header.value, page, new URL(details.url)); |
+} |
+ |
+if (typeof chrome == "object") |
+ chrome.webRequest.onHeadersReceived.addListener( |
+ onHeadersReceived, |
+ { |
+ urls: ["http://*/*", "https://*/*"], |
+ types: ["main_frame", "sub_frame"] |
+ }, |
+ ["responseHeaders"] |
+ ); |