OLD | NEW |
1 /* | 1 /* |
2 * This Source Code is subject to the terms of the Mozilla Public License | 2 * This Source Code is subject to the terms of the Mozilla Public License |
3 * version 2.0 (the "License"). You can obtain a copy of the License at | 3 * version 2.0 (the "License"). You can obtain a copy of the License at |
4 * http://mozilla.org/MPL/2.0/. | 4 * http://mozilla.org/MPL/2.0/. |
5 */ | 5 */ |
6 | 6 |
7 chrome.webRequest.onBeforeRequest.addListener(onBeforeRequest, {urls: ["http://*
/*", "https://*/*"]}, ["blocking"]); | 7 chrome.webRequest.onBeforeRequest.addListener(onBeforeRequest, {urls: ["http://*
/*", "https://*/*"]}, ["blocking"]); |
8 chrome.webRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, {urls: ["
http://*/*", "https://*/*"]}, ["requestHeaders", "blocking"]); | 8 chrome.webRequest.onHeadersReceived.addListener(onHeadersReceived, {urls: ["http
://*/*", "https://*/*"]}, ["responseHeaders"]); |
9 chrome.tabs.onRemoved.addListener(forgetTab); | 9 chrome.tabs.onRemoved.addListener(forgetTab); |
10 | 10 |
11 var frames = {}; | 11 var frames = {}; |
12 | 12 |
13 function onBeforeRequest(details) | 13 function onBeforeRequest(details) |
14 { | 14 { |
15 if (details.tabId == -1) | 15 if (details.tabId == -1) |
16 return {}; | 16 return {}; |
17 | 17 |
18 var type = details.type; | 18 var type = details.type; |
(...skipping 20 matching lines...) Expand all Loading... |
39 return {redirectUrl: "about:blank"}; | 39 return {redirectUrl: "about:blank"}; |
40 else if (collapse && type == "IMAGE") | 40 else if (collapse && type == "IMAGE") |
41 return {redirectUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAA
ABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=="}; | 41 return {redirectUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAA
ABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=="}; |
42 else | 42 else |
43 return {cancel: true}; | 43 return {cancel: true}; |
44 } | 44 } |
45 else | 45 else |
46 return {}; | 46 return {}; |
47 } | 47 } |
48 | 48 |
49 function onBeforeSendHeaders(details) | 49 function onHeadersReceived(details) |
50 { | 50 { |
51 var match = defaultMatcher.matchesAny(details.url, "DONOTTRACK", null, false); | 51 if (details.tabId == -1) |
52 if (match && match instanceof BlockingFilter) | 52 return; |
| 53 |
| 54 var type = details.type; |
| 55 if (type != "main_frame" && type != "sub_frame") |
| 56 return; |
| 57 |
| 58 var url = getFrameUrl(details.tabId, details.frameId); |
| 59 if (url != details.url) |
| 60 return; |
| 61 |
| 62 var key = null; |
| 63 var signature = null; |
| 64 for (var i = 0; i < details.responseHeaders.length; i++) |
53 { | 65 { |
54 var headers = details.requestHeaders || []; | 66 var header = details.responseHeaders[i]; |
55 if (!headers.some(function(header) { header.name == "DNT";})) | 67 if (header.name.toLowerCase() == "x-adblock-key" && header.value) |
56 { | 68 { |
57 headers.push({name: "DNT", value: "1"}); | 69 var index = header.value.indexOf("_"); |
58 return {requestHeaders: headers}; | 70 if (index >= 0) |
| 71 { |
| 72 var key = header.value.substr(0, index); |
| 73 var signature = header.value.substr(index + 1); |
| 74 break; |
| 75 } |
59 } | 76 } |
60 } | 77 } |
61 return null; | 78 if (!key) |
| 79 return; |
| 80 |
| 81 var parentUrl = null; |
| 82 if (type == "sub_frame") |
| 83 parentUrl = getFrameUrl(details.tabId, details.parentFrameId); |
| 84 if (!parentUrl) |
| 85 parentUrl = url; |
| 86 var docDomain = extractHostFromURL(parentUrl); |
| 87 var keyMatch = defaultMatcher.matchesByKey(url, key.replace(/=/g, ""), docDoma
in); |
| 88 if (keyMatch) |
| 89 { |
| 90 // Website specifies a key that we know but is the signature valid? |
| 91 var uri = new URI(url); |
| 92 var host = uri.asciiHost; |
| 93 if (uri.port > 0) |
| 94 host += ":" + uri.port; |
| 95 |
| 96 var params = [ |
| 97 uri.path.replace(/#.*/, ""), // REQUEST_URI |
| 98 host, // HTTP_HOST |
| 99 window.navigator.userAgent // HTTP_USER_AGENT |
| 100 ]; |
| 101 if (verifySignature(key, signature, params.join("\0"))) |
| 102 frames[details.tabId][details.frameId].keyException = true; |
| 103 } |
62 } | 104 } |
63 | 105 |
64 function recordFrame(tabId, frameId, parentFrameId, frameUrl) | 106 function recordFrame(tabId, frameId, parentFrameId, frameUrl) |
65 { | 107 { |
66 if (!(tabId in frames)) | 108 if (!(tabId in frames)) |
67 frames[tabId] = {}; | 109 frames[tabId] = {}; |
68 frames[tabId][frameId] = {url: frameUrl, parent: parentFrameId}; | 110 frames[tabId][frameId] = {url: frameUrl, parent: parentFrameId}; |
69 } | 111 } |
70 | 112 |
71 function getFrameUrl(tabId, frameId) | 113 function getFrameUrl(tabId, frameId) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 } | 145 } |
104 | 146 |
105 function isFrameWhitelisted(tabId, frameId, type) | 147 function isFrameWhitelisted(tabId, frameId, type) |
106 { | 148 { |
107 var parent = frameId; | 149 var parent = frameId; |
108 while (parent != -1) | 150 while (parent != -1) |
109 { | 151 { |
110 var parentUrl = getFrameUrl(tabId, parent); | 152 var parentUrl = getFrameUrl(tabId, parent); |
111 if (parentUrl && isWhitelisted(parentUrl, type)) | 153 if (parentUrl && isWhitelisted(parentUrl, type)) |
112 return true; | 154 return true; |
| 155 if (parentUrl && "keyException" in frames[tabId][frameId]) |
| 156 return true; |
113 parent = getFrameParent(tabId, parent); | 157 parent = getFrameParent(tabId, parent); |
114 } | 158 } |
115 return false; | 159 return false; |
116 } | 160 } |
OLD | NEW |