mirror of
https://github.com/gorhill/uBlock.git
synced 2024-10-06 09:37:12 +02:00
this fixes #211
This commit is contained in:
parent
087cd4e645
commit
d41408ebbc
@ -53,6 +53,7 @@ const contentObserver = {
|
|||||||
contractID: '@' + hostName + '/content-policy;1',
|
contractID: '@' + hostName + '/content-policy;1',
|
||||||
ACCEPT: Ci.nsIContentPolicy.ACCEPT,
|
ACCEPT: Ci.nsIContentPolicy.ACCEPT,
|
||||||
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
|
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
|
||||||
|
SUB_FRAME: Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
|
||||||
contentBaseURI: 'chrome://' + hostName + '/content/js/',
|
contentBaseURI: 'chrome://' + hostName + '/content/js/',
|
||||||
cpMessageName: hostName + ':shouldLoad',
|
cpMessageName: hostName + ':shouldLoad',
|
||||||
ignoredPopups: new WeakMap(),
|
ignoredPopups: new WeakMap(),
|
||||||
@ -132,12 +133,14 @@ const contentObserver = {
|
|||||||
|
|
||||||
if ( type === this.MAIN_FRAME ) {
|
if ( type === this.MAIN_FRAME ) {
|
||||||
context = context.contentWindow || context;
|
context = context.contentWindow || context;
|
||||||
|
if (
|
||||||
if ( context.opener && context.opener !== context
|
context.opener &&
|
||||||
&& this.ignoredPopups.has(context) === false ) {
|
context.opener !== context &&
|
||||||
|
this.ignoredPopups.has(context) === false
|
||||||
|
) {
|
||||||
openerURL = context.opener.location.href;
|
openerURL = context.opener.location.href;
|
||||||
}
|
}
|
||||||
} else if ( type === 7 ) { // SUB_DOCUMENT
|
} else if ( type === this.SUB_FRAME ) {
|
||||||
context = context.contentWindow;
|
context = context.contentWindow;
|
||||||
} else {
|
} else {
|
||||||
context = (context.ownerDocument || context).defaultView;
|
context = (context.ownerDocument || context).defaultView;
|
||||||
@ -151,7 +154,6 @@ const contentObserver = {
|
|||||||
|
|
||||||
let isTopLevel = context === context.top;
|
let isTopLevel = context === context.top;
|
||||||
let parentFrameId;
|
let parentFrameId;
|
||||||
|
|
||||||
if ( isTopLevel ) {
|
if ( isTopLevel ) {
|
||||||
parentFrameId = -1;
|
parentFrameId = -1;
|
||||||
} else if ( context.parent === context.top ) {
|
} else if ( context.parent === context.top ) {
|
||||||
@ -165,7 +167,7 @@ const contentObserver = {
|
|||||||
frameId: isTopLevel ? 0 : this.getFrameId(context),
|
frameId: isTopLevel ? 0 : this.getFrameId(context),
|
||||||
openerURL: openerURL,
|
openerURL: openerURL,
|
||||||
parentFrameId: parentFrameId,
|
parentFrameId: parentFrameId,
|
||||||
type: type,
|
rawtype: type,
|
||||||
url: location.spec
|
url: location.spec
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -962,7 +962,8 @@ var httpObserver = {
|
|||||||
REQDATAKEY: location.host + 'reqdata',
|
REQDATAKEY: location.host + 'reqdata',
|
||||||
ABORT: Components.results.NS_BINDING_ABORTED,
|
ABORT: Components.results.NS_BINDING_ABORTED,
|
||||||
ACCEPT: Components.results.NS_SUCCEEDED,
|
ACCEPT: Components.results.NS_SUCCEEDED,
|
||||||
// Request types: https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIContentPolicy#Constants
|
// Request types:
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIContentPolicy#Constants
|
||||||
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
|
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
|
||||||
VALID_CSP_TARGETS: 1 << Ci.nsIContentPolicy.TYPE_DOCUMENT |
|
VALID_CSP_TARGETS: 1 << Ci.nsIContentPolicy.TYPE_DOCUMENT |
|
||||||
1 << Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
|
1 << Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
|
||||||
@ -979,7 +980,6 @@ var httpObserver = {
|
|||||||
14: 'font',
|
14: 'font',
|
||||||
21: 'image'
|
21: 'image'
|
||||||
},
|
},
|
||||||
lastRequest: [{}, {}],
|
|
||||||
|
|
||||||
get componentRegistrar() {
|
get componentRegistrar() {
|
||||||
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||||
@ -1010,6 +1010,8 @@ var httpObserver = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
register: function() {
|
register: function() {
|
||||||
|
this.pendingRingBufferInit();
|
||||||
|
|
||||||
Services.obs.addObserver(this, 'http-on-opening-request', true);
|
Services.obs.addObserver(this, 'http-on-opening-request', true);
|
||||||
Services.obs.addObserver(this, 'http-on-examine-response', true);
|
Services.obs.addObserver(this, 'http-on-examine-response', true);
|
||||||
|
|
||||||
@ -1049,6 +1051,79 @@ var httpObserver = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
PendingRequest: function() {
|
||||||
|
this.frameId = 0;
|
||||||
|
this.parentFrameId = 0;
|
||||||
|
this.rawtype = 0;
|
||||||
|
this.sourceTabId = null;
|
||||||
|
this.tabId = 0;
|
||||||
|
this._key = ''; // key is url, from URI.spec
|
||||||
|
},
|
||||||
|
// If all work fine, this map should not grow indefinitely. It can have
|
||||||
|
// stale items in it, but these will be taken care of when entries in
|
||||||
|
// the ring buffer are overwritten.
|
||||||
|
pendingURLToIndex: new Map(),
|
||||||
|
pendingWritePointer: 0,
|
||||||
|
pendingRingBuffer: new Array(32),
|
||||||
|
pendingRingBufferInit: function() {
|
||||||
|
// Use and reuse pre-allocated PendingRequest objects = less memory
|
||||||
|
// churning.
|
||||||
|
var i = this.pendingRingBuffer.length;
|
||||||
|
while ( i-- ) {
|
||||||
|
this.pendingRingBuffer[i] = new this.PendingRequest();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createPendingRequest: function(url) {
|
||||||
|
var bucket;
|
||||||
|
var i = this.pendingWritePointer;
|
||||||
|
this.pendingWritePointer = i + 1 & 31;
|
||||||
|
var preq = this.pendingRingBuffer[i];
|
||||||
|
// Cleanup unserviced pending request
|
||||||
|
if ( preq._key !== '' ) {
|
||||||
|
bucket = this.pendingURLToIndex.get(preq._key);
|
||||||
|
if ( Array.isArray(bucket) ) {
|
||||||
|
// Assuming i in array
|
||||||
|
var pos = bucket.indexOf(i);
|
||||||
|
bucket.splice(pos, 1);
|
||||||
|
if ( bucket.length === 1 ) {
|
||||||
|
this.pendingURLToIndex.set(preq._key, bucket[0]);
|
||||||
|
}
|
||||||
|
} else if ( typeof bucket === 'number' ) {
|
||||||
|
// Assuming bucket === i
|
||||||
|
this.pendingURLToIndex.delete(preq._key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Would be much simpler if a url could not appear more than once.
|
||||||
|
bucket = this.pendingURLToIndex.get(url);
|
||||||
|
if ( bucket === undefined ) {
|
||||||
|
this.pendingURLToIndex.set(url, i);
|
||||||
|
} else if ( Array.isArray(bucket) ) {
|
||||||
|
bucket = bucket.push(i);
|
||||||
|
} else {
|
||||||
|
bucket = [bucket, i];
|
||||||
|
}
|
||||||
|
preq._key = url;
|
||||||
|
return preq;
|
||||||
|
},
|
||||||
|
lookupPendingRequest: function(url) {
|
||||||
|
var i = this.pendingURLToIndex.get(url);
|
||||||
|
if ( i === undefined ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ( Array.isArray(i) ) {
|
||||||
|
var bucket = i;
|
||||||
|
i = bucket.shift();
|
||||||
|
if ( bucket.length === 1 ) {
|
||||||
|
this.pendingURLToIndex.set(url, bucket[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.pendingURLToIndex.delete(url);
|
||||||
|
}
|
||||||
|
var preq = this.pendingRingBuffer[i];
|
||||||
|
preq._key = ''; // mark as "serviced"
|
||||||
|
return preq;
|
||||||
|
},
|
||||||
|
|
||||||
handlePopup: function(URI, tabId, sourceTabId) {
|
handlePopup: function(URI, tabId, sourceTabId) {
|
||||||
if ( !sourceTabId ) {
|
if ( !sourceTabId ) {
|
||||||
return false;
|
return false;
|
||||||
@ -1069,7 +1144,7 @@ var httpObserver = {
|
|||||||
|
|
||||||
handleRequest: function(channel, URI, details) {
|
handleRequest: function(channel, URI, details) {
|
||||||
var onBeforeRequest = vAPI.net.onBeforeRequest;
|
var onBeforeRequest = vAPI.net.onBeforeRequest;
|
||||||
var type = this.typeMap[details.type] || 'other';
|
var type = this.typeMap[details.rawtype] || 'other';
|
||||||
|
|
||||||
if ( onBeforeRequest.types && onBeforeRequest.types.has(type) === false ) {
|
if ( onBeforeRequest.types && onBeforeRequest.types.has(type) === false ) {
|
||||||
return false;
|
return false;
|
||||||
@ -1093,14 +1168,6 @@ var httpObserver = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if ( result.redirectUrl ) {
|
|
||||||
channel.redirectionLimit = 1;
|
|
||||||
channel.redirectTo(
|
|
||||||
Services.io.newURI(result.redirectUrl, null, null)
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1160,55 +1227,37 @@ var httpObserver = {
|
|||||||
|
|
||||||
// http-on-opening-request
|
// http-on-opening-request
|
||||||
|
|
||||||
var lastRequest = this.lastRequest[0];
|
//console.log('http-on-opening-request:', URI.spec);
|
||||||
|
|
||||||
if ( lastRequest.url !== URI.spec ) {
|
var pendingRequest = this.lookupPendingRequest(URI.spec);
|
||||||
if ( this.lastRequest[1].url === URI.spec ) {
|
|
||||||
lastRequest = this.lastRequest[1];
|
|
||||||
} else {
|
|
||||||
lastRequest.url = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( lastRequest.url === null ) {
|
// Behind-the-scene request
|
||||||
lastRequest.type = channel.loadInfo && channel.loadInfo.contentPolicyType || 1;
|
if ( pendingRequest === null ) {
|
||||||
result = this.handleRequest(channel, URI, {
|
var rawtype = channel.loadInfo && channel.loadInfo.contentPolicyType || 1;
|
||||||
tabId: vAPI.noTabId,
|
if ( this.handleRequest(channel, URI, { tabId: vAPI.noTabId, rawtype: rawtype }) ) {
|
||||||
type: lastRequest.type
|
|
||||||
});
|
|
||||||
|
|
||||||
if ( result === true ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( channel instanceof Ci.nsIWritablePropertyBag === false ) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carry data for behind-the-scene redirects
|
// Carry data for behind-the-scene redirects
|
||||||
channel.setProperty(
|
if ( channel instanceof Ci.nsIWritablePropertyBag ) {
|
||||||
this.REQDATAKEY,
|
channel.setProperty( this.REQDATAKEY, [0, -1, null, vAPI.noTabId, rawtype]);
|
||||||
[lastRequest.type, vAPI.noTabId, null, 0, -1]
|
}
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Important! When loading file via XHR for mirroring,
|
if ( this.handleRequest(channel, URI, pendingRequest) ) {
|
||||||
// the URL will be the same, so it could fall into an infinite loop
|
|
||||||
lastRequest.url = null;
|
|
||||||
|
|
||||||
if ( this.handleRequest(channel, URI, lastRequest) ) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If request is not handled we may use the data in on-modify-request
|
// If request is not handled we may use the data in on-modify-request
|
||||||
if ( channel instanceof Ci.nsIWritablePropertyBag ) {
|
if ( channel instanceof Ci.nsIWritablePropertyBag ) {
|
||||||
channel.setProperty(this.REQDATAKEY, [
|
channel.setProperty(this.REQDATAKEY, [
|
||||||
lastRequest.frameId,
|
pendingRequest.frameId,
|
||||||
lastRequest.parentFrameId,
|
pendingRequest.parentFrameId,
|
||||||
lastRequest.sourceTabId,
|
pendingRequest.sourceTabId,
|
||||||
lastRequest.tabId,
|
pendingRequest.tabId,
|
||||||
lastRequest.type
|
pendingRequest.rawtype
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1240,7 +1289,7 @@ var httpObserver = {
|
|||||||
frameId: channelData[0],
|
frameId: channelData[0],
|
||||||
parentFrameId: channelData[1],
|
parentFrameId: channelData[1],
|
||||||
tabId: channelData[3],
|
tabId: channelData[3],
|
||||||
type: channelData[4]
|
rawtype: channelData[4]
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( this.handleRequest(newChannel, URI, details) ) {
|
if ( this.handleRequest(newChannel, URI, details) ) {
|
||||||
@ -1276,6 +1325,10 @@ vAPI.net.registerListeners = function() {
|
|||||||
|
|
||||||
var shouldLoadListenerMessageName = location.host + ':shouldLoad';
|
var shouldLoadListenerMessageName = location.host + ':shouldLoad';
|
||||||
var shouldLoadListener = function(e) {
|
var shouldLoadListener = function(e) {
|
||||||
|
// Non blocking: it is assumed that the http observer is fired after
|
||||||
|
// shouldLoad recorded the pending requests. If this is not the case,
|
||||||
|
// a request would end up being categorized as a behind-the-scene
|
||||||
|
// requests.
|
||||||
var details = e.data;
|
var details = e.data;
|
||||||
var tabId = vAPI.tabs.getTabId(e.target);
|
var tabId = vAPI.tabs.getTabId(e.target);
|
||||||
var sourceTabId = null;
|
var sourceTabId = null;
|
||||||
@ -1307,16 +1360,14 @@ vAPI.net.registerListeners = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastRequest = httpObserver.lastRequest;
|
//console.log('shouldLoadListener:', details.url);
|
||||||
lastRequest[1] = lastRequest[0];
|
|
||||||
lastRequest[0] = {
|
var pendingReq = httpObserver.createPendingRequest(details.url);
|
||||||
frameId: details.frameId,
|
pendingReq.frameId = details.frameId;
|
||||||
parentFrameId: details.parentFrameId,
|
pendingReq.parentFrameId = details.parentFrameId;
|
||||||
sourceTabId: sourceTabId,
|
pendingReq.rawtype = details.rawtype;
|
||||||
tabId: tabId,
|
pendingReq.sourceTabId = sourceTabId;
|
||||||
type: details.type,
|
pendingReq.tabId = tabId;
|
||||||
url: details.url
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
vAPI.messaging.globalMessageManager.addMessageListener(
|
vAPI.messaging.globalMessageManager.addMessageListener(
|
||||||
|
@ -195,7 +195,7 @@ window.addEventListener('pageshow', vAPI.messaging.toggleListener, true);
|
|||||||
// we are not a top window (because element picker can still
|
// we are not a top window (because element picker can still
|
||||||
// be injected in top window).
|
// be injected in top window).
|
||||||
if ( window !== window.top ) {
|
if ( window !== window.top ) {
|
||||||
// Can anything be done?
|
// Can anything be done?
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
Loading…
Reference in New Issue
Block a user