mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 01:02:08 +01:00
fix #1884
This commit is contained in:
parent
da163bbe4b
commit
cbefeb923c
5 changed files with 81 additions and 104 deletions
|
@ -858,7 +858,8 @@ vAPI.net.registerListeners = function() {
|
|||
// https://bugs.chromium.org/p/chromium/issues/detail?id=410382
|
||||
// Between Chromium 38-48, plug-ins' network requests were reported as
|
||||
// type "other" instead of "object".
|
||||
var is_v38_48 = /\bChrom[a-z]+\/(?:3[89]|4[0-8])\.[\d.]+\b/.test(navigator.userAgent);
|
||||
var is_v38_48 = /\bChrom[a-z]+\/(?:3[89]|4[0-8])\.[\d.]+\b/.test(navigator.userAgent),
|
||||
is_v49_55 = /\bChrom[a-z]+\/(?:49|5[012345])\b/.test(navigator.userAgent);
|
||||
|
||||
// Chromium-based browsers understand only these network request types.
|
||||
var validTypes = {
|
||||
|
@ -1003,9 +1004,20 @@ vAPI.net.registerListeners = function() {
|
|||
return onBeforeRequestClient(details);
|
||||
};
|
||||
|
||||
var onHeadersReceivedClient = this.onHeadersReceived.callback;
|
||||
var onHeadersReceivedClientTypes = this.onHeadersReceived.types.slice(0);
|
||||
var onHeadersReceivedTypes = denormalizeTypes(onHeadersReceivedClientTypes);
|
||||
// This is needed for Chromium 49-55.
|
||||
var onBeforeSendHeaders = function(details) {
|
||||
if ( details.type !== 'ping' || details.method !== 'POST' ) { return; }
|
||||
var type = headerValue(details.requestHeaders, 'content-type');
|
||||
if ( type === '' ) { return; }
|
||||
if ( type.endsWith('/csp-report') ) {
|
||||
details.type = 'csp_report';
|
||||
return onBeforeRequestClient(details);
|
||||
}
|
||||
};
|
||||
|
||||
var onHeadersReceivedClient = this.onHeadersReceived.callback,
|
||||
onHeadersReceivedClientTypes = this.onHeadersReceived.types.slice(0),
|
||||
onHeadersReceivedTypes = denormalizeTypes(onHeadersReceivedClientTypes);
|
||||
var onHeadersReceived = function(details) {
|
||||
normalizeRequestDetails(details);
|
||||
// Hack to work around Chromium API limitations, where requests of
|
||||
|
@ -1033,19 +1045,17 @@ vAPI.net.registerListeners = function() {
|
|||
};
|
||||
|
||||
var installListeners = (function() {
|
||||
var listener;
|
||||
var crapi = chrome.webRequest;
|
||||
|
||||
listener = onBeforeRequest;
|
||||
//listener = function(details) {
|
||||
// quickProfiler.start('onBeforeRequest');
|
||||
// var r = onBeforeRequest(details);
|
||||
// quickProfiler.stop();
|
||||
// return r;
|
||||
//};
|
||||
if ( crapi.onBeforeRequest.hasListener(listener) === false ) {
|
||||
if ( crapi.onBeforeRequest.hasListener(onBeforeRequest) === false ) {
|
||||
crapi.onBeforeRequest.addListener(
|
||||
listener,
|
||||
onBeforeRequest,
|
||||
{
|
||||
'urls': this.onBeforeRequest.urls || ['<all_urls>'],
|
||||
'types': this.onBeforeRequest.types || undefined
|
||||
|
@ -1054,10 +1064,22 @@ vAPI.net.registerListeners = function() {
|
|||
);
|
||||
}
|
||||
|
||||
listener = onHeadersReceived;
|
||||
if ( crapi.onHeadersReceived.hasListener(listener) === false ) {
|
||||
// Chromium 48 and lower does not support `ping` type.
|
||||
// Chromium 56 and higher does support `csp_report` stype.
|
||||
if ( is_v49_55 && crapi.onBeforeSendHeaders.hasListener(onBeforeSendHeaders) === false ) {
|
||||
crapi.onBeforeSendHeaders.addListener(
|
||||
onBeforeSendHeaders,
|
||||
{
|
||||
'urls': [ '<all_urls>' ],
|
||||
'types': [ 'ping' ]
|
||||
},
|
||||
[ 'blocking', 'requestHeaders' ]
|
||||
);
|
||||
}
|
||||
|
||||
if ( crapi.onHeadersReceived.hasListener(onHeadersReceived) === false ) {
|
||||
crapi.onHeadersReceived.addListener(
|
||||
listener,
|
||||
onHeadersReceived,
|
||||
{
|
||||
'urls': this.onHeadersReceived.urls || ['<all_urls>'],
|
||||
'types': onHeadersReceivedTypes
|
||||
|
|
|
@ -260,15 +260,12 @@ vAPI.browserSettings = {
|
|||
|
||||
case 'hyperlinkAuditing':
|
||||
this.rememberOriginalValue('browser', 'send_pings');
|
||||
this.rememberOriginalValue('beacon', 'enabled');
|
||||
// https://github.com/gorhill/uBlock/issues/292
|
||||
// "true" means "do not disable", i.e. leave entry alone
|
||||
if ( settingVal ) {
|
||||
this.clear('browser', 'send_pings');
|
||||
this.clear('beacon', 'enabled');
|
||||
} else {
|
||||
this.setValue('browser', 'send_pings', false);
|
||||
this.setValue('beacon', 'enabled', false);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1892,6 +1889,7 @@ var httpObserver = {
|
|||
14: 'font',
|
||||
15: 'media',
|
||||
16: 'websocket',
|
||||
17: 'csp_report',
|
||||
19: 'beacon',
|
||||
21: 'image'
|
||||
},
|
||||
|
@ -2156,8 +2154,8 @@ var httpObserver = {
|
|||
|
||||
// 'Content-Security-Policy' MUST come last in the array. Need to
|
||||
// revised this eventually.
|
||||
var responseHeaders = [];
|
||||
var value = channel.contentLength;
|
||||
var responseHeaders = [],
|
||||
value = channel.contentLength;
|
||||
if ( value !== -1 ) {
|
||||
responseHeaders.push({ name: 'Content-Length', value: value });
|
||||
}
|
||||
|
@ -2339,9 +2337,6 @@ vAPI.net = {};
|
|||
/******************************************************************************/
|
||||
|
||||
vAPI.net.registerListeners = function() {
|
||||
// Since it's not used
|
||||
this.onBeforeSendHeaders = null;
|
||||
|
||||
if ( typeof this.onBeforeRequest.callback === 'function' ) {
|
||||
httpObserver.onBeforeRequest = this.onBeforeRequest.callback;
|
||||
httpObserver.onBeforeRequestTypes = this.onBeforeRequest.types ?
|
||||
|
|
|
@ -212,7 +212,7 @@
|
|||
"description":"English: "
|
||||
},
|
||||
"settingsHyperlinkAuditingDisabledPrompt":{
|
||||
"message":"Disable hyperlink auditing/beacon",
|
||||
"message":"Disable hyperlink auditing",
|
||||
"description":"English: "
|
||||
},
|
||||
"settingsWebRTCIPAddressHiddenPrompt":{
|
||||
|
|
|
@ -313,6 +313,7 @@ PageStore.prototype.init = function(tabId) {
|
|||
this.largeMediaCount = 0;
|
||||
this.largeMediaTimer = null;
|
||||
this.netFilteringCache = NetFilteringResultCache.factory();
|
||||
this.internalRedirectionCount = 0;
|
||||
|
||||
this.noCosmeticFiltering = µb.hnSwitches.evaluateZ('no-cosmetic-filtering', tabContext.rootHostname) === true;
|
||||
if ( µb.logger.isEnabled() && this.noCosmeticFiltering ) {
|
||||
|
@ -614,10 +615,15 @@ PageStore.prototype.journalProcess = function(fromTimer) {
|
|||
PageStore.prototype.filterRequest = function(context) {
|
||||
var requestType = context.requestType;
|
||||
|
||||
// We want to short-term cache filtering results of collapsible types,
|
||||
// because they are likely to be reused, from network request handler and
|
||||
// from content script handler.
|
||||
if ( 'image sub_frame object'.indexOf(requestType) === -1 ) {
|
||||
return this.filterRequestNoCache(context);
|
||||
}
|
||||
|
||||
if ( this.getNetFilteringSwitch() === false ) {
|
||||
if ( collapsibleRequestTypes.indexOf(requestType) !== -1 ) {
|
||||
this.netFilteringCache.add(context, '');
|
||||
}
|
||||
this.netFilteringCache.add(context, '');
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -629,23 +635,13 @@ PageStore.prototype.filterRequest = function(context) {
|
|||
|
||||
var result = '';
|
||||
|
||||
if ( requestType === 'font' ) {
|
||||
if ( µb.hnSwitches.evaluateZ('no-remote-fonts', context.rootHostname) !== false ) {
|
||||
result = µb.hnSwitches.toResultString();
|
||||
}
|
||||
this.remoteFontCount += 1;
|
||||
}
|
||||
|
||||
// Dynamic URL filtering.
|
||||
if ( result === '' ) {
|
||||
µb.sessionURLFiltering.evaluateZ(context.rootHostname, context.requestURL, requestType);
|
||||
result = µb.sessionURLFiltering.toFilterString();
|
||||
}
|
||||
|
||||
// Given that:
|
||||
// - Dynamic filtering override static filtering
|
||||
// - Evaluating dynamic filtering is much faster than static filtering
|
||||
// We evaluate dynamic filtering first, and hopefully we can skip
|
||||
// evaluation of static filtering.
|
||||
// Dynamic hostname/type filtering.
|
||||
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
|
||||
µb.sessionFirewall.evaluateCellZY( context.rootHostname, context.requestHostname, requestType);
|
||||
if ( µb.sessionFirewall.mustBlockOrAllow() ) {
|
||||
|
@ -653,7 +649,7 @@ PageStore.prototype.filterRequest = function(context) {
|
|||
}
|
||||
}
|
||||
|
||||
// Static filtering never override dynamic filtering
|
||||
// Static filtering has lowest precedence.
|
||||
if ( result === '' || result.charAt(1) === 'n' ) {
|
||||
if ( µb.staticNetFilteringEngine.matchString(context) !== undefined ) {
|
||||
result = µb.staticNetFilteringEngine.toResultString(µb.logger.isEnabled());
|
||||
|
@ -661,18 +657,11 @@ PageStore.prototype.filterRequest = function(context) {
|
|||
}
|
||||
|
||||
//console.debug('cache MISS: PageStore.filterRequest("%s")', context.requestURL);
|
||||
if ( collapsibleRequestTypes.indexOf(requestType) !== -1 ) {
|
||||
this.netFilteringCache.add(context, result);
|
||||
}
|
||||
|
||||
// console.debug('[%s, %s] = "%s"', context.requestHostname, requestType, result);
|
||||
this.netFilteringCache.add(context, result);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// http://jsperf.com/string-indexof-vs-object
|
||||
var collapsibleRequestTypes = 'image sub_frame object';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
PageStore.prototype.filterRequestNoCache = function(context) {
|
||||
|
@ -680,26 +669,27 @@ PageStore.prototype.filterRequestNoCache = function(context) {
|
|||
return '';
|
||||
}
|
||||
|
||||
var requestType = context.requestType;
|
||||
var result = '';
|
||||
var requestType = context.requestType,
|
||||
result = '';
|
||||
|
||||
if ( requestType === 'font' ) {
|
||||
if ( requestType === 'csp_report' ) {
|
||||
if ( this.internalRedirectionCount !== 0 ) {
|
||||
result = 'gb:no-spurious-csp-report';
|
||||
}
|
||||
} else if ( requestType === 'font' ) {
|
||||
if ( µb.hnSwitches.evaluateZ('no-remote-fonts', context.rootHostname) !== false ) {
|
||||
result = µb.hnSwitches.toResultString();
|
||||
}
|
||||
this.remoteFontCount += 1;
|
||||
}
|
||||
|
||||
// Dynamic URL filtering.
|
||||
if ( result === '' ) {
|
||||
µb.sessionURLFiltering.evaluateZ(context.rootHostname, context.requestURL, requestType);
|
||||
result = µb.sessionURLFiltering.toFilterString();
|
||||
}
|
||||
|
||||
// Given that:
|
||||
// - Dynamic filtering override static filtering
|
||||
// - Evaluating dynamic filtering is much faster than static filtering
|
||||
// We evaluate dynamic filtering first, and hopefully we can skip
|
||||
// evaluation of static filtering.
|
||||
// Dynamic hostname/type filtering.
|
||||
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
|
||||
µb.sessionFirewall.evaluateCellZY(context.rootHostname, context.requestHostname, requestType);
|
||||
if ( µb.sessionFirewall.mustBlockOrAllow() ) {
|
||||
|
@ -707,7 +697,7 @@ PageStore.prototype.filterRequestNoCache = function(context) {
|
|||
}
|
||||
}
|
||||
|
||||
// Static filtering never override dynamic filtering
|
||||
// Static filtering has lowest precedence.
|
||||
if ( result === '' || result.charAt(1) === 'n' ) {
|
||||
if ( µb.staticNetFilteringEngine.matchString(context) !== undefined ) {
|
||||
result = µb.staticNetFilteringEngine.toResultString(µb.logger.isEnabled());
|
||||
|
|
|
@ -45,12 +45,6 @@ var onBeforeRequest = function(details) {
|
|||
return onBeforeRootFrameRequest(details);
|
||||
}
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/870
|
||||
// This work for Chromium 49+.
|
||||
if ( requestType === 'beacon' ) {
|
||||
return onBeforeBeacon(details);
|
||||
}
|
||||
|
||||
// Special treatment: behind-the-scene requests
|
||||
var tabId = details.tabId;
|
||||
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
||||
|
@ -58,8 +52,8 @@ var onBeforeRequest = function(details) {
|
|||
}
|
||||
|
||||
// Lookup the page store associated with this tab id.
|
||||
var µb = µBlock;
|
||||
var pageStore = µb.pageStoreFromTabId(tabId);
|
||||
var µb = µBlock,
|
||||
pageStore = µb.pageStoreFromTabId(tabId);
|
||||
if ( !pageStore ) {
|
||||
var tabContext = µb.tabContextManager.mustLookup(tabId);
|
||||
if ( vAPI.isBehindTheSceneTabId(tabContext.tabId) ) {
|
||||
|
@ -119,6 +113,7 @@ var onBeforeRequest = function(details) {
|
|||
// Redirect blocked request?
|
||||
var url = µb.redirectEngine.toURL(requestContext);
|
||||
if ( url !== undefined ) {
|
||||
pageStore.internalRedirectionCount += 1;
|
||||
if ( µb.logger.isEnabled() ) {
|
||||
µb.logger.writeOne(
|
||||
tabId,
|
||||
|
@ -277,62 +272,37 @@ var toBlockDocResult = function(url, hostname, result) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
// 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.
|
||||
|
||||
var onBeforeBeacon = function(details) {
|
||||
var µb = µBlock;
|
||||
var tabId = details.tabId;
|
||||
var pageStore = µb.mustPageStoreFromTabId(tabId);
|
||||
var context = pageStore.createContextFromPage();
|
||||
context.requestURL = details.url;
|
||||
context.requestHostname = µb.URI.hostnameFromURI(details.url);
|
||||
context.requestType = details.type;
|
||||
// "g" in "gb:" stands for "global setting"
|
||||
var result = µb.userSettings.hyperlinkAuditingDisabled ? 'gb:' : '';
|
||||
pageStore.journalAddRequest(context.requestHostname, result);
|
||||
if ( µb.logger.isEnabled() ) {
|
||||
µb.logger.writeOne(
|
||||
tabId,
|
||||
'net',
|
||||
result,
|
||||
details.type,
|
||||
details.url,
|
||||
context.rootHostname,
|
||||
context.rootHostname
|
||||
);
|
||||
}
|
||||
context.dispose();
|
||||
if ( result !== '' ) {
|
||||
return { cancel: true };
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Intercept and filter behind-the-scene requests.
|
||||
|
||||
var onBeforeBehindTheSceneRequest = function(details) {
|
||||
var µb = µBlock;
|
||||
var pageStore = µb.pageStoreFromTabId(vAPI.noTabId);
|
||||
if ( !pageStore ) {
|
||||
return;
|
||||
}
|
||||
var µb = µBlock,
|
||||
pageStore = µb.pageStoreFromTabId(vAPI.noTabId);
|
||||
if ( !pageStore ) { return; }
|
||||
|
||||
var result = '',
|
||||
context = pageStore.createContextFromPage(),
|
||||
requestType = details.type,
|
||||
requestURL = details.url;
|
||||
|
||||
var context = pageStore.createContextFromPage();
|
||||
var requestURL = details.url;
|
||||
context.requestURL = requestURL;
|
||||
context.requestHostname = µb.URI.hostnameFromURI(requestURL);
|
||||
context.requestType = details.type;
|
||||
context.requestType = requestType;
|
||||
|
||||
// "g" in "gb:" stands for "global setting"
|
||||
if ( requestType === 'beacon' && µb.userSettings.hyperlinkAuditingDisabled ) {
|
||||
result = 'gb:no-hyperlink-auditing';
|
||||
}
|
||||
|
||||
// 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
|
||||
var result = '';
|
||||
if ( µb.userSettings.advancedUserEnabled ) {
|
||||
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
|
||||
result = pageStore.filterRequestNoCache(context);
|
||||
}
|
||||
|
||||
|
@ -343,7 +313,7 @@ var onBeforeBehindTheSceneRequest = function(details) {
|
|||
vAPI.noTabId,
|
||||
'net',
|
||||
result,
|
||||
details.type,
|
||||
requestType,
|
||||
requestURL,
|
||||
context.rootHostname,
|
||||
context.rootHostname
|
||||
|
|
Loading…
Reference in a new issue