mirror of https://github.com/gorhill/uBlock.git
Add approximate reporting of tabless network requests
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/1204 Not much can be done beside reporting to tabless network requests to all tabs for which the context is a match. A short term local cache is used to avoid having to iterate through all existing tabs for each tabless network request just to find and report to the matching ones -- users reporting having a lot of opened tabs at once is not so uncommon.
This commit is contained in:
parent
cc86e373ec
commit
6df32675b1
|
@ -69,7 +69,7 @@ const initializeTabs = async function() {
|
|||
if ( tab.discarded === true ) { continue; }
|
||||
const { id, url } = tab;
|
||||
µb.tabContextManager.commit(id, url);
|
||||
µb.bindTabToPageStats(id);
|
||||
µb.bindTabToPageStore(id);
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/129
|
||||
// Find out whether content scripts need to be injected
|
||||
// programmatically. This may be necessary for web pages which
|
||||
|
|
|
@ -371,10 +371,10 @@
|
|||
|
||||
// It is a popup, block and remove the tab.
|
||||
if ( popupType === 'popup' ) {
|
||||
µb.unbindTabFromPageStats(targetTabId);
|
||||
µb.unbindTabFromPageStore(targetTabId);
|
||||
vAPI.tabs.remove(targetTabId, false);
|
||||
} else {
|
||||
µb.unbindTabFromPageStats(openerTabId);
|
||||
µb.unbindTabFromPageStore(openerTabId);
|
||||
vAPI.tabs.remove(openerTabId, true);
|
||||
}
|
||||
|
||||
|
@ -850,7 +850,7 @@ vAPI.Tabs = class extends vAPI.Tabs {
|
|||
onClosed(tabId) {
|
||||
super.onClosed(tabId);
|
||||
if ( vAPI.isBehindTheSceneTabId(tabId) ) { return; }
|
||||
µBlock.unbindTabFromPageStats(tabId);
|
||||
µBlock.unbindTabFromPageStore(tabId);
|
||||
µBlock.contextMenu.update();
|
||||
}
|
||||
|
||||
|
@ -874,7 +874,7 @@ vAPI.Tabs = class extends vAPI.Tabs {
|
|||
const µb = µBlock;
|
||||
if ( details.frameId === 0 ) {
|
||||
µb.tabContextManager.commit(details.tabId, details.url);
|
||||
let pageStore = µb.bindTabToPageStats(details.tabId, 'tabCommitted');
|
||||
let pageStore = µb.bindTabToPageStore(details.tabId, 'tabCommitted');
|
||||
if ( pageStore ) {
|
||||
pageStore.journalAddRootFrame('committed', details.url);
|
||||
}
|
||||
|
@ -896,7 +896,7 @@ vAPI.Tabs = class extends vAPI.Tabs {
|
|||
if ( !tab.url || tab.url === '' ) { return; }
|
||||
if ( !changeInfo.url ) { return; }
|
||||
µBlock.tabContextManager.commit(tabId, changeInfo.url);
|
||||
µBlock.bindTabToPageStats(tabId, 'tabUpdated');
|
||||
µBlock.bindTabToPageStore(tabId, 'tabUpdated');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -907,12 +907,12 @@ vAPI.tabs = new vAPI.Tabs();
|
|||
|
||||
// Create an entry for the tab if it doesn't exist.
|
||||
|
||||
µBlock.bindTabToPageStats = function(tabId, context) {
|
||||
µBlock.bindTabToPageStore = function(tabId, context) {
|
||||
this.updateToolbarIcon(tabId, 0b111);
|
||||
|
||||
// Do not create a page store for URLs which are of no interests
|
||||
if ( this.tabContextManager.exists(tabId) === false ) {
|
||||
this.unbindTabFromPageStats(tabId);
|
||||
this.unbindTabFromPageStore(tabId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -954,8 +954,7 @@ vAPI.tabs = new vAPI.Tabs();
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.unbindTabFromPageStats = function(tabId) {
|
||||
//console.debug('µBlock> unbindTabFromPageStats(%d)', tabId);
|
||||
µBlock.unbindTabFromPageStore = function(tabId) {
|
||||
const pageStore = this.pageStores.get(tabId);
|
||||
if ( pageStore === undefined ) { return; }
|
||||
pageStore.dispose();
|
||||
|
@ -1143,7 +1142,7 @@ vAPI.tabs = new vAPI.Tabs();
|
|||
const checkTab = async tabId => {
|
||||
const tab = await vAPI.tabs.get(tabId);
|
||||
if ( tab instanceof Object && tab.discarded !== true ) { return; }
|
||||
µBlock.unbindTabFromPageStats(tabId);
|
||||
µBlock.unbindTabFromPageStore(tabId);
|
||||
};
|
||||
|
||||
const pageStoreJanitor = function() {
|
||||
|
|
|
@ -205,7 +205,7 @@ const onBeforeRootFrameRequest = function(fctxt) {
|
|||
fctxt.type = 'main_frame';
|
||||
}
|
||||
|
||||
const pageStore = µb.bindTabToPageStats(fctxt.tabId, 'beforeRequest');
|
||||
const pageStore = µb.bindTabToPageStore(fctxt.tabId, 'beforeRequest');
|
||||
if ( pageStore !== null ) {
|
||||
pageStore.journalAddRootFrame('uncommitted', requestURL);
|
||||
pageStore.journalAddRequest(requestHostname, result);
|
||||
|
@ -294,35 +294,15 @@ const toBlockDocResult = function(url, hostname, logData) {
|
|||
|
||||
// Intercept and filter behind-the-scene requests.
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/870
|
||||
// Finally, Chromium 49+ gained the ability to report network request of type
|
||||
// `beacon`, so now we can block them according to the state of the
|
||||
// "Disable hyperlink auditing/beacon" setting.
|
||||
|
||||
const onBeforeBehindTheSceneRequest = function(fctxt) {
|
||||
const µb = µBlock;
|
||||
const pageStore = µb.pageStoreFromTabId(fctxt.tabId);
|
||||
if ( pageStore === null ) { return; }
|
||||
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=637577#c15
|
||||
// Do not filter behind-the-scene network request of type `beacon`: there
|
||||
// is no point. In any case, this will become a non-issue once
|
||||
// <https://bugs.chromium.org/p/chromium/issues/detail?id=522129> is
|
||||
// fixed.
|
||||
|
||||
// Blocking behind-the-scene requests can break a lot of stuff: prevent
|
||||
// browser updates, prevent extension updates, prevent extensions from
|
||||
// working properly, etc.
|
||||
// So we filter if and only if the "advanced user" mode is selected.
|
||||
// https://github.com/gorhill/uBlock/issues/3150
|
||||
// Ability to globally block CSP reports MUST also apply to
|
||||
// behind-the-scene network requests.
|
||||
|
||||
// 2018-03-30:
|
||||
// Filter all behind-the-scene network requests like any other network
|
||||
// requests. Hopefully this will not break stuff as it used to be the
|
||||
// case.
|
||||
|
||||
let result = 0;
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/339
|
||||
|
@ -341,8 +321,8 @@ const onBeforeBehindTheSceneRequest = function(fctxt) {
|
|||
|
||||
// The "any-tab" scope is not whitelist-able, and in such case we must
|
||||
// use the origin URL as the scope. Most such requests aren't going to
|
||||
// be blocked, so we further test for whitelisting and modify the
|
||||
// result only when the request is being blocked.
|
||||
// be blocked, so we test for whitelisting and modify the result only
|
||||
// when the request is being blocked.
|
||||
if (
|
||||
result === 1 &&
|
||||
µb.getNetFilteringSwitch(fctxt.tabOrigin) === false
|
||||
|
@ -352,6 +332,9 @@ const onBeforeBehindTheSceneRequest = function(fctxt) {
|
|||
}
|
||||
}
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/1204
|
||||
onBeforeBehindTheSceneRequest.journalAddRequest(fctxt, result);
|
||||
|
||||
if ( µb.logger.enabled ) {
|
||||
fctxt.setRealm('network').toLogger();
|
||||
}
|
||||
|
@ -369,6 +352,54 @@ const onBeforeBehindTheSceneRequest = function(fctxt) {
|
|||
}
|
||||
};
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/1204
|
||||
// Report the tabless network requests to all page stores matching the
|
||||
// document origin. This is an approximation, there is unfortunately no
|
||||
// way to know for sure which exact page triggered a tabless network
|
||||
// request.
|
||||
|
||||
onBeforeBehindTheSceneRequest.journalAddRequest = (( ) => {
|
||||
let hostname = '';
|
||||
let pageStores = new Set();
|
||||
let pageStoresToken = 0;
|
||||
let gcTimer;
|
||||
|
||||
const reset = function() {
|
||||
hostname = '';
|
||||
pageStores = new Set();
|
||||
pageStoresToken = 0;
|
||||
};
|
||||
|
||||
const gc = ( ) => {
|
||||
gcTimer = undefined;
|
||||
if ( pageStoresToken !== µBlock.pageStoresToken ) { return reset(); }
|
||||
gcTimer = vAPI.setTimeout(gc, 30011);
|
||||
};
|
||||
|
||||
return function(fctxt, result) {
|
||||
const { docHostname } = fctxt;
|
||||
if (
|
||||
docHostname !== hostname ||
|
||||
pageStoresToken !== µBlock.pageStoresToken
|
||||
) {
|
||||
hostname = docHostname;
|
||||
pageStores = new Set();
|
||||
for ( const pageStore of µBlock.pageStores.values() ) {
|
||||
if ( pageStore.tabHostname !== docHostname ) { continue; }
|
||||
pageStores.add(pageStore);
|
||||
}
|
||||
pageStoresToken = µBlock.pageStoresToken;
|
||||
if ( gcTimer !== undefined ) {
|
||||
clearTimeout(gcTimer);
|
||||
}
|
||||
gcTimer = vAPI.setTimeout(gc, 30011);
|
||||
}
|
||||
for ( const pageStore of pageStores ) {
|
||||
pageStore.journalAddRequest(fctxt.hostname, result);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// To handle:
|
||||
|
@ -394,7 +425,7 @@ const onHeadersReceived = function(details) {
|
|||
let pageStore = µb.pageStoreFromTabId(fctxt.tabId);
|
||||
if ( pageStore === null ) {
|
||||
if ( isRootDoc === false ) { return; }
|
||||
pageStore = µb.bindTabToPageStats(fctxt.tabId, 'beforeRequest');
|
||||
pageStore = µb.bindTabToPageStore(fctxt.tabId, 'beforeRequest');
|
||||
}
|
||||
if ( pageStore.getNetFilteringSwitch(fctxt) === false ) { return; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue