This commit is contained in:
gorhill 2015-01-20 19:39:13 -05:00
parent b8131943c9
commit 255c68baa4
8 changed files with 119 additions and 88 deletions

View file

@ -38,6 +38,8 @@ var manifest = chrome.runtime.getManifest();
vAPI.chrome = true;
var noopFunc = function(){};
/******************************************************************************/
vAPI.app = {
@ -280,7 +282,7 @@ vAPI.messaging = {
ports: {},
listeners: {},
defaultHandler: null,
NOOPFUNC: function(){},
NOOPFUNC: noopFunc,
UNHANDLED: 'vAPI.messaging.notHandled'
};
@ -382,25 +384,81 @@ vAPI.messaging.broadcast = function(message) {
/******************************************************************************/
vAPI.net = {
registerListeners: function() {
var listeners = [
'onBeforeRequest',
'onBeforeSendHeaders',
'onHeadersReceived'
];
vAPI.net = {};
for ( var i = 0; i < listeners.length; i++ ) {
chrome.webRequest[listeners[i]].addListener(
this[listeners[i]].callback,
{
'urls': this[listeners[i]].urls || ['<all_urls>'],
'types': this[listeners[i]].types || []
},
this[listeners[i]].extra
);
/******************************************************************************/
vAPI.net.registerListeners = function() {
var µb = µBlock;
var µburi = µb.URI;
var normalizeRequestDetails = function(details) {
µburi.set(details.url);
details.tabId = details.tabId.toString();
details.hostname = µburi.hostnameFromURI(details.url);
var type = details.type;
if ( type !== 'other' ) {
return;
}
}
var path = µburi.path;
var pos = path.lastIndexOf('.');
if ( pos === -1 ) {
return;
}
var ext = path.slice(pos) + '.';
if ( '.eot.ttf.otf.svg.woff.woff2.'.indexOf(ext) !== -1 ) {
details.type = 'font';
return;
}
if ( '.ico.'.indexOf(ext) !== -1 ) {
details.type = 'image';
return;
}
// https://code.google.com/p/chromium/issues/detail?id=410382
if ( type === 'other' ) {
details.type = 'object';
return;
}
};
var onBeforeRequestClient = this.onBeforeRequest.callback;
var onBeforeRequest = function(details) {
normalizeRequestDetails(details);
return onBeforeRequestClient(details);
};
chrome.webRequest.onBeforeRequest.addListener(
onBeforeRequest,
{
'urls': this.onBeforeRequest.urls || ['<all_urls>'],
'types': this.onBeforeRequest.types || []
},
this.onBeforeRequest.extra
);
chrome.webRequest.onBeforeSendHeaders.addListener(
this.onBeforeSendHeaders.callback,
{
'urls': this.onBeforeSendHeaders.urls || ['<all_urls>'],
'types': this.onBeforeSendHeaders.types || []
},
this.onBeforeSendHeaders.extra
);
var onHeadersReceivedClient = this.onHeadersReceived.callback;
var onHeadersReceived = function(details) {
normalizeRequestDetails(details);
return onHeadersReceivedClient(details);
};
chrome.webRequest.onHeadersReceived.addListener(
onHeadersReceived,
{
'urls': this.onHeadersReceived.urls || ['<all_urls>'],
'types': this.onHeadersReceived.types || []
},
this.onHeadersReceived.extra
);
};
/******************************************************************************/

View file

@ -785,6 +785,7 @@ var httpObserver = {
contractID: '@' + location.host + '/net-channel-event-sinks;1',
ABORT: Components.results.NS_BINDING_ABORTED,
ACCEPT: Components.results.NS_SUCCEEDED,
// Request types: https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIContentPolicy#Constants
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
VALID_CSP_TARGETS: 1 << Ci.nsIContentPolicy.TYPE_DOCUMENT |
1 << Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
@ -795,7 +796,9 @@ var httpObserver = {
5: 'object',
6: 'main_frame',
7: 'sub_frame',
11: 'xmlhttprequest'
11: 'xmlhttprequest',
12: 'object',
14: 'font'
},
lastRequest: {
url: null,
@ -892,11 +895,12 @@ var httpObserver = {
}
var result = onBeforeRequest.callback({
url: channel.URI.asciiSpec,
type: type,
tabId: details.tabId,
frameId: details.frameId,
parentFrameId: details.parentFrameId
hostname: channel.URI.asciiHost,
parentFrameId: details.parentFrameId,
tabId: details.tabId,
type: type,
url: channel.URI.asciiSpec
});
if ( !result || typeof result !== 'object' ) {
@ -906,7 +910,9 @@ var httpObserver = {
if ( result.cancel === true ) {
channel.cancel(this.ABORT);
return true;
} else if ( result.redirectUrl ) {
}
if ( result.redirectUrl ) {
channel.redirectionLimit = 1;
channel.redirectTo(
Services.io.newURI(result.redirectUrl, null, null)
@ -954,10 +960,11 @@ var httpObserver = {
}
result = vAPI.net.onHeadersReceived.callback({
url: URI.asciiSpec,
tabId: channelData[1],
hostname: URI.asciiHost,
parentFrameId: channelData[0] === this.MAIN_FRAME ? -1 : 0,
responseHeaders: result ? [{name: topic, value: result}] : []
responseHeaders: result ? [{name: topic, value: result}] : [],
tabId: channelData[1],
url: URI.asciiSpec
});
if ( result ) {
@ -1098,11 +1105,11 @@ vAPI.net.registerListeners = function() {
// data: and about:blank
if ( details.url.charAt(0) !== 'h' ) {
vAPI.net.onBeforeRequest.callback({
url: 'http://' + details.url.slice(0, details.url.indexOf(':')),
type: 'main_frame',
tabId: vAPI.tabs.getTabId(e.target),
frameId: details.frameId,
parentFrameId: details.parentFrameId
parentFrameId: details.parentFrameId,
tabId: vAPI.tabs.getTabId(e.target),
type: 'main_frame',
url: 'http://' + details.url.slice(0, details.url.indexOf(':'))
});
return;
}

View file

@ -591,6 +591,8 @@ vAPI.net = {};
/******************************************************************************/
vAPI.net.registerListeners = function() {
var µb = µBlock;
// Since it's not used
this.onBeforeSendHeaders = null;
this.onHeadersReceived = null;
@ -615,9 +617,11 @@ vAPI.net.registerListeners = function() {
}
if ( e.message.isURLWhiteListed ) {
block = µBlock.URI.hostnameFromURI(e.message.isURLWhiteListed);
block = µBlock.URI.domainFromHostname(block) || block;
e.message = !!µBlock.netWhitelist[block];
block = µb.URI.hostnameFromURI(e.message.isURLWhiteListed);
block = µb.URI.domainFromHostname(block) || block;
// TODO: revise, this can't work properly
e.message = !!µb.netWhitelist[block];
return e.message;
}
@ -659,6 +663,7 @@ vAPI.net.registerListeners = function() {
return true;
}
e.message.hostname = µb.URI.hostnameFromURI(e.message.url);
e.message.tabId = vAPI.tabs.getTabId(e.target);
block = onBeforeRequest(e.message);

View file

@ -19,14 +19,14 @@
Home: https://github.com/gorhill/uBlock
*/
/* global vAPI */
/* exported µBlock */
'use strict';
/******************************************************************************/
var µBlock = (function() {
'use strict';
/******************************************************************************/
var oneSecond = 1000;

View file

@ -67,7 +67,6 @@ var logEntryJunkyardMax = 100;
LogEntry.prototype.init = function(details, result) {
this.tstamp = Date.now();
this.url = details.requestURL;
this.domain = details.requestDomain;
this.hostname = details.requestHostname;
this.type = details.requestType;
this.result = result;
@ -77,7 +76,7 @@ LogEntry.prototype.init = function(details, result) {
/******************************************************************************/
LogEntry.prototype.dispose = function() {
this.url = this.domain = this.hostname = this.type = this.result = '';
this.url = this.hostname = this.type = this.result = '';
if ( logEntryJunkyard.length < logEntryJunkyardMax ) {
logEntryJunkyard.push(this);
}

View file

@ -68,6 +68,7 @@ var typeNameToTypeValue = {
'inline-script': 14 << 4,
'popup': 15 << 4
};
var typeOtherToTypeValue = typeNameToTypeValue['other'];
const BlockAnyTypeAnyParty = BlockAction | AnyType | AnyParty;
const BlockAnyType = BlockAction | AnyType;
@ -1754,7 +1755,8 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r
// This will be used by hostname-based filters
pageHostname = context.pageHostname || '';
var type = typeNameToTypeValue[requestType];
// Be prepared to support unknown types
var type = typeNameToTypeValue[requestType] || typeOtherToTypeValue;
var categories = this.categories;
var bucket;
@ -1814,7 +1816,8 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r
FilterContainer.prototype.matchString = function(context) {
// https://github.com/gorhill/uBlock/issues/519
// Use exact type match for anything beyond `other`
var type = typeNameToTypeValue[context.requestType];
// Also, be prepared to support unknown types
var type = typeNameToTypeValue[context.requestType] || typeOtherToTypeValue;
if ( type > 8 << 4 ) {
return this.matchStringExactType(context, context.requestURL, context.requestType);
}

View file

@ -56,26 +56,6 @@ var onBeforeRequest = function(details) {
return;
}
// Commented out until (and if ever) there is a fix for:
// https://code.google.com/p/chromium/issues/detail?id=410382
//
// Try to transpose generic `other` category into something more meaningful.
if ( requestType === 'other' ) {
requestType = µb.transposeType('other', µb.URI.set(requestURL).path);
// https://github.com/gorhill/uBlock/issues/206
// https://code.google.com/p/chromium/issues/detail?id=410382
// Work around the issue of Chromium not properly setting the type for
// `object` requests. Unclear whether this issue will be fixed, hence
// this workaround to prevent torch-and-pitchfork mobs because ads are
// no longer blocked in videos.
// https://github.com/gorhill/uBlock/issues/281
// Looks like Chrome 38 (but not 39) doesn't provide the expected request
// header `X-Requested-With`. Sigh.
if ( requestType === 'other' ) {
requestType = 'object';
}
}
// Lookup the page store associated with this tab id.
pageStore = µb.pageStoreFromTabId(tabId);
if ( !pageStore ) {
@ -94,7 +74,7 @@ var onBeforeRequest = function(details) {
// Setup context and evaluate
requestContext.requestURL = requestURL;
requestContext.requestHostname = µb.URI.hostnameFromURI(requestURL);
requestContext.requestHostname = details.hostname;
requestContext.requestType = requestType;
var result = pageStore.filterRequest(requestContext);
@ -217,7 +197,7 @@ var onBeforeSendHeaders = function(details) {
var result = µb.staticNetFilteringEngine.matchStringExactType(pageDetails, requestURL, 'popup');
// Not blocked?
if ( result === '' || result.slice(0, 2) === '@@' ) {
if ( µb.isAllowResult(result) ) {
return;
}
@ -254,8 +234,7 @@ var onHeadersReceived = function(details) {
//}
var requestURL = details.url;
var requestHostname = µb.URI.hostnameFromURI(requestURL);
var requestDomain = µb.URI.domainFromHostname(requestHostname);
var requestHostname = details.hostname;
// https://github.com/gorhill/uBlock/issues/525
// When we are dealing with the root frame, due to fix to issue #516, it
@ -266,11 +245,12 @@ var onHeadersReceived = function(details) {
// inline scripts.
var context;
if ( details.parentFrameId === -1 ) {
var contextDomain = µb.URI.domainFromHostname(requestHostname);
context = {
rootHostname: requestHostname,
rootDomain: requestDomain,
rootDomain: contextDomain,
pageHostname: requestHostname,
pageDomain: requestDomain
pageDomain: contextDomain
};
} else {
context = pageStore;
@ -282,7 +262,6 @@ var onHeadersReceived = function(details) {
// URLs-different type
context.requestURL = requestURL + '{inline-script}';
context.requestHostname = requestHostname;
context.requestDomain = requestDomain;
context.requestType = 'inline-script';
var result = pageStore.filterRequest(context);
@ -323,7 +302,7 @@ var headerStartsWith = function(headers, prefix) {
var prefixLen = prefix.length;
var i = headers.length;
while ( i-- ) {
if ( headers[i].name.slice(0, prefixLen).toLowerCase() === prefix ) {
if ( headers[i].name.toLowerCase().lastIndexOf(prefix, 0) === 0 ) {
return headers[i].value;
}
}

View file

@ -281,26 +281,6 @@ var matchWhitelistDirective = function(url, hostname, directive) {
/******************************************************************************/
µBlock.transposeType = function(type, path) {
if ( type !== 'other' ) {
return type;
}
var pos = path.lastIndexOf('.');
if ( pos === -1 ) {
return type;
}
var ext = path.slice(pos) + '.';
if ( '.eot.ttf.otf.svg.woff.woff2.'.indexOf(ext) !== -1 ) {
return 'font';
}
if ( '.ico.'.indexOf(ext) !== -1 ) {
return 'image';
}
return type;
};
/******************************************************************************/
µBlock.elementPickerExec = function(tabId, targetElement) {
this.elementPickerTarget = targetElement || '';
vAPI.tabs.injectScript(tabId, { file: 'js/element-picker.js' });