2017-09-02 12:11:33 +02:00
|
|
|
/*******************************************************************************
|
|
|
|
|
|
|
|
uBlock Origin - a browser extension to block requests.
|
2018-10-28 14:58:25 +01:00
|
|
|
Copyright (C) 2017-present Raymond Hill
|
2017-09-02 12:11:33 +02:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
|
|
|
|
|
|
Home: https://github.com/gorhill/uBlock
|
|
|
|
*/
|
|
|
|
|
|
|
|
// For background page
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2018-10-28 14:58:25 +01:00
|
|
|
(function() {
|
2018-11-08 22:58:45 +01:00
|
|
|
const extToTypeMap = new Map([
|
2017-09-02 12:11:33 +02:00
|
|
|
['eot','font'],['otf','font'],['svg','font'],['ttf','font'],['woff','font'],['woff2','font'],
|
|
|
|
['mp3','media'],['mp4','media'],['webm','media'],
|
|
|
|
['gif','image'],['ico','image'],['jpeg','image'],['jpg','image'],['png','image'],['webp','image']
|
|
|
|
]);
|
|
|
|
|
2018-11-08 22:58:45 +01:00
|
|
|
// https://www.reddit.com/r/uBlockOrigin/comments/9vcrk3/bug_in_ubo_1173_betas_when_saving_files_hosted_on/
|
|
|
|
// Some types can be mapped from 'other', thus include 'other' if and
|
|
|
|
// only if the caller is interested in at least one of those types.
|
|
|
|
const denormalizeTypes = function(aa) {
|
2017-09-02 12:11:33 +02:00
|
|
|
if ( aa.length === 0 ) {
|
2018-10-28 14:58:25 +01:00
|
|
|
return Array.from(vAPI.net.validTypes);
|
2017-09-02 12:11:33 +02:00
|
|
|
}
|
2018-11-08 22:58:45 +01:00
|
|
|
const out = new Set();
|
|
|
|
let i = aa.length;
|
2017-09-02 12:11:33 +02:00
|
|
|
while ( i-- ) {
|
2018-11-08 22:58:45 +01:00
|
|
|
const type = aa[i];
|
2018-10-28 14:58:25 +01:00
|
|
|
if ( vAPI.net.validTypes.has(type) ) {
|
2018-11-08 22:58:45 +01:00
|
|
|
out.add(type);
|
2017-09-02 12:11:33 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-08 22:58:45 +01:00
|
|
|
if ( out.has('other') === false ) {
|
|
|
|
for ( const type of extToTypeMap.values() ) {
|
|
|
|
if ( out.has(type) ) {
|
|
|
|
out.add('other');
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-09-02 12:11:33 +02:00
|
|
|
}
|
2018-11-08 22:58:45 +01:00
|
|
|
return Array.from(out);
|
2017-09-02 12:11:33 +02:00
|
|
|
};
|
|
|
|
|
2018-11-08 22:58:45 +01:00
|
|
|
const headerValue = function(headers, name) {
|
|
|
|
let i = headers.length;
|
2017-09-02 12:11:33 +02:00
|
|
|
while ( i-- ) {
|
|
|
|
if ( headers[i].name.toLowerCase() === name ) {
|
|
|
|
return headers[i].value.trim();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return '';
|
|
|
|
};
|
|
|
|
|
2018-11-08 22:58:45 +01:00
|
|
|
const parsedURL = new URL('https://www.example.org/');
|
2018-10-28 14:58:25 +01:00
|
|
|
|
|
|
|
vAPI.net.normalizeDetails = function(details) {
|
2018-03-30 21:29:46 +02:00
|
|
|
// Chromium 63+ supports the `initiator` property, which contains
|
|
|
|
// the URL of the origin from which the network request was made.
|
|
|
|
if (
|
2018-05-14 14:11:50 +02:00
|
|
|
typeof details.initiator === 'string' &&
|
|
|
|
details.initiator !== 'null'
|
2018-03-30 21:29:46 +02:00
|
|
|
) {
|
|
|
|
details.documentUrl = details.initiator;
|
|
|
|
}
|
|
|
|
|
2018-10-28 14:58:25 +01:00
|
|
|
let type = details.type;
|
2017-09-02 12:11:33 +02:00
|
|
|
|
|
|
|
// https://github.com/gorhill/uBlock/issues/1493
|
|
|
|
// Chromium 49+/WebExtensions support a new request type: `ping`,
|
|
|
|
// which is fired as a result of using `navigator.sendBeacon`.
|
|
|
|
if ( type === 'ping' ) {
|
|
|
|
details.type = 'beacon';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( type === 'imageset' ) {
|
|
|
|
details.type = 'image';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The rest of the function code is to normalize type
|
2018-11-08 22:58:45 +01:00
|
|
|
if ( type !== 'other' ) { return; }
|
2017-09-02 12:11:33 +02:00
|
|
|
|
|
|
|
// Try to map known "extension" part of URL to request type.
|
2018-10-28 14:58:25 +01:00
|
|
|
parsedURL.href = details.url;
|
2018-11-08 22:58:45 +01:00
|
|
|
const path = parsedURL.pathname,
|
|
|
|
pos = path.indexOf('.', path.length - 6);
|
2017-09-02 12:11:33 +02:00
|
|
|
if ( pos !== -1 && (type = extToTypeMap.get(path.slice(pos + 1))) ) {
|
|
|
|
details.type = type;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to extract type from response headers if present.
|
|
|
|
if ( details.responseHeaders ) {
|
|
|
|
type = headerValue(details.responseHeaders, 'content-type');
|
|
|
|
if ( type.startsWith('font/') ) {
|
|
|
|
details.type = 'font';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ( type.startsWith('image/') ) {
|
|
|
|
details.type = 'image';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ( type.startsWith('audio/') || type.startsWith('video/') ) {
|
|
|
|
details.type = 'media';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2018-03-31 16:20:44 +02:00
|
|
|
};
|
2017-09-02 12:11:33 +02:00
|
|
|
|
2018-10-28 14:58:25 +01:00
|
|
|
vAPI.net.denormalizeFilters = function(filters) {
|
2018-11-08 22:58:45 +01:00
|
|
|
const urls = filters.urls || [ '<all_urls>' ];
|
2018-10-28 14:58:25 +01:00
|
|
|
let types = filters.types;
|
|
|
|
if ( Array.isArray(types) ) {
|
|
|
|
types = denormalizeTypes(types);
|
2017-09-02 12:11:33 +02:00
|
|
|
}
|
|
|
|
if (
|
2018-10-28 14:58:25 +01:00
|
|
|
(vAPI.net.validTypes.has('websocket')) &&
|
2017-09-02 12:11:33 +02:00
|
|
|
(types === undefined || types.indexOf('websocket') !== -1) &&
|
|
|
|
(urls.indexOf('<all_urls>') === -1)
|
|
|
|
) {
|
|
|
|
if ( urls.indexOf('ws://*/*') === -1 ) {
|
|
|
|
urls.push('ws://*/*');
|
|
|
|
}
|
|
|
|
if ( urls.indexOf('wss://*/*') === -1 ) {
|
|
|
|
urls.push('wss://*/*');
|
|
|
|
}
|
|
|
|
}
|
2018-10-28 14:58:25 +01:00
|
|
|
return { types, urls };
|
|
|
|
};
|
|
|
|
})();
|
2017-09-02 12:11:33 +02:00
|
|
|
|
|
|
|
/******************************************************************************/
|
2018-12-23 23:59:31 +01:00
|
|
|
|
|
|
|
// https://github.com/gorhill/uBlock/issues/2067
|
|
|
|
// Experimental: Block everything until uBO is fully ready.
|
|
|
|
|
|
|
|
vAPI.net.onBeforeReady = (function() {
|
|
|
|
let pendings;
|
|
|
|
|
|
|
|
const handler = function(details) {
|
|
|
|
if ( pendings === undefined ) { return; }
|
|
|
|
if ( details.tabId < 0 ) { return; }
|
|
|
|
|
|
|
|
pendings.add(details.tabId);
|
|
|
|
|
|
|
|
return { cancel: true };
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
experimental: true,
|
|
|
|
start: function() {
|
|
|
|
pendings = new Set();
|
|
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
|
|
handler,
|
|
|
|
{ urls: [ 'http://*/*', 'https://*/*' ] },
|
|
|
|
[ 'blocking' ]
|
|
|
|
);
|
|
|
|
},
|
|
|
|
// https://github.com/gorhill/uBlock/issues/2067
|
|
|
|
// Force-reload tabs for which network requests were blocked
|
|
|
|
// during launch. This can happen only if tabs were "suspended".
|
|
|
|
stop: function() {
|
|
|
|
if ( pendings === undefined ) { return; }
|
|
|
|
browser.webRequest.onBeforeRequest.removeListener(handler);
|
|
|
|
for ( const tabId of pendings ) {
|
|
|
|
vAPI.tabs.reload(tabId);
|
|
|
|
}
|
|
|
|
pendings = undefined;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
})();
|
|
|
|
|
|
|
|
/******************************************************************************/
|