Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
69 // WEBRTC gets addressed through a workaround, even if the webRequest API is | 69 // WEBRTC gets addressed through a workaround, even if the webRequest API is |
70 // lacking support to block this kind of a request. | 70 // lacking support to block this kind of a request. |
71 yield "WEBRTC"; | 71 yield "WEBRTC"; |
72 | 72 |
73 // POPUP, CSP and ELEMHIDE filters aren't mapped to resource types. | 73 // POPUP, CSP and ELEMHIDE filters aren't mapped to resource types. |
74 yield "POPUP"; | 74 yield "POPUP"; |
75 yield "ELEMHIDE"; | 75 yield "ELEMHIDE"; |
76 yield "CSP"; | 76 yield "CSP"; |
77 }()); | 77 }()); |
78 | 78 |
79 function getDocumentInfo(page, frame, originUrl) | |
80 { | |
81 return [ | |
82 extractHostFromFrame(frame, originUrl), | |
83 getKey(page, frame, originUrl), | |
84 !!checkWhitelisted(page, frame, originUrl, | |
85 RegExpFilter.typeMap.GENERICBLOCK) | |
86 ]; | |
87 } | |
88 | |
89 function matchRequest(url, type, docDomain, sitekey, specificOnly) | |
90 { | |
91 let urlString = stringifyURL(url); | |
92 let thirdParty = isThirdParty(url, docDomain); | |
93 | |
94 return [ | |
95 defaultMatcher.matchesAny(urlString, RegExpFilter.typeMap[type], | |
96 docDomain, thirdParty, sitekey, specificOnly), | |
97 urlString, | |
98 thirdParty | |
99 ]; | |
100 } | |
101 | |
79 function getRelatedTabIds(details) | 102 function getRelatedTabIds(details) |
80 { | 103 { |
81 // This is the common case, the request is associated with a single tab. | 104 // This is the common case, the request is associated with a single tab. |
82 // If tabId is -1, its not (e.g. the request was sent by | 105 // If tabId is -1, its not (e.g. the request was sent by |
83 // a Service/Shared Worker) and we have to identify the related tabs. | 106 // a Service/Shared Worker) and we have to identify the related tabs. |
84 if (details.tabId != -1) | 107 if (details.tabId != -1) |
85 return Promise.resolve([details.tabId]); | 108 return Promise.resolve([details.tabId]); |
86 | 109 |
87 let url; // Firefox provides "originUrl" indicating the | 110 let url; // Firefox provides "originUrl" indicating the |
88 if (details.originUrl) // URL of the tab that caused this request. | 111 if (details.originUrl) // URL of the tab that caused this request. |
89 url = details.originUrl; // In case of Service/Shared Worker, this is the | 112 url = details.originUrl; // In case of Service/Shared Worker, this is the |
90 // URL of the tab that caused the worker to spawn. | 113 // URL of the tab that caused the worker to spawn. |
91 | 114 |
92 else if (details.initiator) // Chromium >=63 provides "intiator" which | 115 else if (details.initiator) // Chromium >=63 provides "intiator" which |
93 url = details.initiator + "/*"; // is equivalent to "originUrl" on Firefox | 116 url = details.initiator + "/*"; // is equivalent to "originUrl" on Firefox |
94 // except that its not a full URL but just | 117 // except that its not a full URL but just |
95 // an origin (proto + host). | 118 // an origin (proto + host). |
96 else | 119 else |
97 return Promise.resolve([]); | 120 return Promise.resolve([]); |
98 | 121 |
99 return browser.tabs.query({url}).then(tabs => tabs.map(tab => tab.id)); | 122 return browser.tabs.query({url}).then(tabs => tabs.map(tab => tab.id)); |
100 } | 123 } |
101 | 124 |
102 function logRequest(details, url, type, docDomain, thirdParty, | 125 function logRequest(tabIds, url, type, docDomain, thirdParty, |
103 sitekey, specificOnly, filter) | 126 sitekey, specificOnly, filter) |
104 { | 127 { |
105 getRelatedTabIds(details).then(tabIds => | 128 if (filter) |
106 { | 129 FilterNotifier.emit("filter.hitCount", filter, 0, 0, tabIds); |
107 if (filter) | |
108 FilterNotifier.emit("filter.hitCount", filter, 0, 0, tabIds); | |
109 | 130 |
110 devtools.logRequest( | 131 devtools.logRequest( |
111 tabIds, url, type, docDomain, | 132 tabIds, url, type, docDomain, |
112 thirdParty, sitekey, | 133 thirdParty, sitekey, |
113 specificOnly, filter | 134 specificOnly, filter |
114 ); | 135 ); |
115 }); | |
116 } | 136 } |
117 | 137 |
118 browser.webRequest.onBeforeRequest.addListener(details => | 138 browser.webRequest.onBeforeRequest.addListener(details => |
119 { | 139 { |
120 // Never block top-level documents. | 140 // Never block top-level documents. |
121 if (details.type == "main_frame") | 141 if (details.type == "main_frame") |
122 return; | 142 return; |
123 | 143 |
124 // Filter out requests from non web protocols. Ideally, we'd explicitly | 144 // Filter out requests from non web protocols. Ideally, we'd explicitly |
125 // specify the protocols we are interested in (i.e. http://, https://, | 145 // specify the protocols we are interested in (i.e. http://, https://, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 // has triggered this request. For most requests (e.g. images) we | 187 // has triggered this request. For most requests (e.g. images) we |
168 // can just use the request's frame ID, but for subdocument requests | 188 // can just use the request's frame ID, but for subdocument requests |
169 // (e.g. iframes) we must instead use the request's parent frame ID. | 189 // (e.g. iframes) we must instead use the request's parent frame ID. |
170 details.type == "sub_frame" ? details.parentFrameId : details.frameId | 190 details.type == "sub_frame" ? details.parentFrameId : details.frameId |
171 ); | 191 ); |
172 } | 192 } |
173 | 193 |
174 if (checkWhitelisted(page, frame, originUrl)) | 194 if (checkWhitelisted(page, frame, originUrl)) |
175 return; | 195 return; |
176 | 196 |
177 let urlString = stringifyURL(url); | |
178 let type = resourceTypes.get(details.type) || "OTHER"; | 197 let type = resourceTypes.get(details.type) || "OTHER"; |
179 let docDomain = extractHostFromFrame(frame, originUrl); | 198 let [docDomain, sitekey, specificOnly] = getDocumentInfo(page, frame, |
kzar
2018/04/17 12:46:39
Perhaps it would be a nicer abstraction to have a
Sebastian Noack
2018/04/17 12:56:47
FWIW, I'm not too happy with this abstraction (jus
kzar
2018/04/17 13:54:06
Yea, fair enough.
| |
180 let thirdParty = isThirdParty(url, docDomain); | 199 originUrl); |
181 let sitekey = getKey(page, frame, originUrl); | 200 let [filter, urlString, thirdParty] = matchRequest(url, type, docDomain, |
182 let specificOnly = !!checkWhitelisted(page, frame, originUrl, | 201 sitekey, specificOnly); |
183 RegExpFilter.typeMap.GENERICBLOCK); | |
184 | 202 |
185 let filter = defaultMatcher.matchesAny( | 203 getRelatedTabIds(details).then(tabIds => |
186 urlString, RegExpFilter.typeMap[type], | 204 { |
187 docDomain, thirdParty, sitekey, specificOnly | 205 logRequest(tabIds, urlString, type, docDomain, |
188 ); | 206 thirdParty, sitekey, specificOnly, filter); |
189 | 207 }); |
190 logRequest(details, urlString, type, docDomain, | |
191 thirdParty, sitekey, specificOnly, filter); | |
192 | 208 |
193 if (filter instanceof BlockingFilter) | 209 if (filter instanceof BlockingFilter) |
194 return {cancel: true}; | 210 return {cancel: true}; |
195 }, {urls: ["<all_urls>"]}, ["blocking"]); | 211 }, {urls: ["<all_urls>"]}, ["blocking"]); |
196 | 212 |
197 port.on("filters.collapse", (message, sender) => | 213 port.on("filters.collapse", (message, sender) => |
198 { | 214 { |
199 if (checkWhitelisted(sender.page, sender.frame)) | 215 let {page, frame} = sender; |
216 | |
217 if (checkWhitelisted(page, frame)) | |
200 return false; | 218 return false; |
201 | 219 |
202 let typeMask = RegExpFilter.typeMap[message.mediatype]; | |
203 let documentHost = extractHostFromFrame(sender.frame); | |
204 let sitekey = getKey(sender.page, sender.frame); | |
205 let blocked = false; | 220 let blocked = false; |
206 | 221 let [docDomain, sitekey, specificOnly] = getDocumentInfo(page, frame); |
207 let specificOnly = checkWhitelisted( | |
208 sender.page, sender.frame, null, | |
209 RegExpFilter.typeMap.GENERICBLOCK | |
210 ); | |
211 | 222 |
212 for (let url of message.urls) | 223 for (let url of message.urls) |
213 { | 224 { |
214 let urlObj = new URL(url, message.baseURL); | 225 let [filter] = matchRequest(new URL(url, message.baseURL), |
215 let filter = defaultMatcher.matchesAny( | 226 message.mediatype, docDomain, |
216 stringifyURL(urlObj), | 227 sitekey, specificOnly); |
217 typeMask, documentHost, | |
218 isThirdParty(urlObj, documentHost), | |
219 sitekey, specificOnly | |
220 ); | |
221 | 228 |
222 if (filter instanceof BlockingFilter) | 229 if (filter instanceof BlockingFilter) |
223 { | 230 { |
224 if (filter.collapse != null) | 231 if (filter.collapse != null) |
225 return filter.collapse; | 232 return filter.collapse; |
226 blocked = true; | 233 blocked = true; |
227 } | 234 } |
228 } | 235 } |
229 | 236 |
230 return blocked && Prefs.hidePlaceholders; | 237 return blocked && Prefs.hidePlaceholders; |
231 }); | 238 }); |
232 | 239 |
240 port.on("request.blockedByRTCWrapper", (msg, sender) => | |
241 { | |
242 let {page, frame} = sender; | |
243 | |
244 if (checkWhitelisted(page, frame)) | |
245 return false; | |
246 | |
247 let [docDomain, sitekey, specificOnly] = getDocumentInfo(page, frame); | |
248 let [filter, url, thirdParty] = matchRequest(new URL(msg.url), | |
249 "WEBRTC", docDomain, | |
250 sitekey, specificOnly); | |
251 | |
252 logRequest([sender.page.id], url, "WEBRTC", docDomain, | |
253 thirdParty, sitekey, specificOnly, filter); | |
254 | |
255 return filter instanceof BlockingFilter; | |
256 }); | |
257 | |
233 let ignoreFilterNotifications = false; | 258 let ignoreFilterNotifications = false; |
234 | 259 |
235 function onFilterChange(arg, isDisabledAction) | 260 function onFilterChange(arg, isDisabledAction) |
236 { | 261 { |
237 // Avoid triggering filters.behaviorChanged multiple times | 262 // Avoid triggering filters.behaviorChanged multiple times |
238 // when multiple filter hanges happen at the same time. | 263 // when multiple filter hanges happen at the same time. |
239 if (ignoreFilterNotifications) | 264 if (ignoreFilterNotifications) |
240 return; | 265 return; |
241 | 266 |
242 // Ignore disabled subscriptions and filters, unless they just got | 267 // Ignore disabled subscriptions and filters, unless they just got |
(...skipping 21 matching lines...) Expand all Loading... | |
264 } | 289 } |
265 | 290 |
266 FilterNotifier.on("subscription.added", onFilterChange); | 291 FilterNotifier.on("subscription.added", onFilterChange); |
267 FilterNotifier.on("subscription.removed", onFilterChange); | 292 FilterNotifier.on("subscription.removed", onFilterChange); |
268 FilterNotifier.on("subscription.updated", onFilterChange); | 293 FilterNotifier.on("subscription.updated", onFilterChange); |
269 FilterNotifier.on("subscription.disabled", arg => onFilterChange(arg, true)); | 294 FilterNotifier.on("subscription.disabled", arg => onFilterChange(arg, true)); |
270 FilterNotifier.on("filter.added", onFilterChange); | 295 FilterNotifier.on("filter.added", onFilterChange); |
271 FilterNotifier.on("filter.removed", onFilterChange); | 296 FilterNotifier.on("filter.removed", onFilterChange); |
272 FilterNotifier.on("filter.disabled", arg => onFilterChange(arg, true)); | 297 FilterNotifier.on("filter.disabled", arg => onFilterChange(arg, true)); |
273 FilterNotifier.on("load", onFilterChange); | 298 FilterNotifier.on("load", onFilterChange); |
274 | |
275 port.on("request.blockedByRTCWrapper", (msg, sender) => | |
276 { | |
277 return ext.webRequest.onBeforeRequest._dispatch( | |
278 new URL(msg.url), | |
279 "webrtc", | |
280 sender.page, | |
281 sender.frame | |
282 ).includes(false); | |
283 }); | |
OLD | NEW |