Browse Source
Add ability to block early at launch; adapt to changes in Chromium 72+
Add ability to block early at launch; adapt to changes in Chromium 72+
Related issues: - "Requests bypass uMatrix on Firefox start" <https://github.com/uBlockOrigin/uMatrix-issues/issues/69> Using same approach as with uBO: https://github.com/gorhill/uBloc/commit/41548be6be35 `suspendTabsUntilReady` advanced setting added to "More" pane, useful only for Chromium -- the blocking of early network requests is enforced unconditionally on Firefox (because it supports returning Promises from webRequest handlers). - "Cookies leaking temporarily" <https://github.com/uBlockOrigin/uMatrix-issues/issues/74> Changes in the webRequest API in Chromium 72+ caused uMatrix to fail to process `Cookie` and `Referer` headers on that platform.pull/2/head
Raymond Hill
6 years ago
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
13 changed files with 623 additions and 460 deletions
-
234platform/chromium/polyfill.js
-
127platform/chromium/vapi-background.js
-
12platform/chromium/vapi-common.js
-
194platform/chromium/vapi-webrequest.js
-
30platform/firefox/polyfill.js
-
185platform/firefox/vapi-webrequest.js
-
9src/background.html
-
35src/js/background.js
-
4src/js/raw-settings.js
-
61src/js/start.js
-
97src/js/storage.js
-
76src/js/traffic.js
-
3tools/make-firefox.sh
@ -1,234 +0,0 @@ |
|||||
/******************************************************************************* |
|
||||
|
|
||||
uMatrix - a browser extension to block requests. |
|
||||
Copyright (C) 2017 Raymond Hill |
|
||||
|
|
||||
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/uMatrix
|
|
||||
|
|
||||
This file has been originally imported from: |
|
||||
https://github.com/gorhill/uBlock/tree/master/platform/chromium
|
|
||||
|
|
||||
*/ |
|
||||
|
|
||||
// For background page or non-background pages
|
|
||||
|
|
||||
/* exported objectAssign */ |
|
||||
|
|
||||
'use strict'; |
|
||||
|
|
||||
/******************************************************************************/ |
|
||||
/******************************************************************************/ |
|
||||
|
|
||||
// https://github.com/gorhill/uBlock/issues/1067
|
|
||||
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
|
|
||||
// Firefox 17/Chromium 41 supports `startsWith`.
|
|
||||
|
|
||||
if ( String.prototype.startsWith instanceof Function === false ) { |
|
||||
String.prototype.startsWith = function(needle, pos) { |
|
||||
if ( typeof pos !== 'number' ) { |
|
||||
pos = 0; |
|
||||
} |
|
||||
return this.lastIndexOf(needle, pos) === pos; |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
/******************************************************************************/ |
|
||||
|
|
||||
// https://github.com/gorhill/uBlock/issues/1067
|
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
|
|
||||
// Firefox 17/Chromium 41 supports `endsWith`.
|
|
||||
|
|
||||
if ( String.prototype.endsWith instanceof Function === false ) { |
|
||||
String.prototype.endsWith = function(needle, pos) { |
|
||||
if ( typeof pos !== 'number' ) { |
|
||||
pos = this.length; |
|
||||
} |
|
||||
pos -= needle.length; |
|
||||
return this.indexOf(needle, pos) === pos; |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
/******************************************************************************/ |
|
||||
|
|
||||
// As per MDN, Object.assign appeared first in Chromium 45.
|
|
||||
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Browser_compatibility
|
|
||||
|
|
||||
var objectAssign = Object.assign || function(target, source) { |
|
||||
var keys = Object.keys(source); |
|
||||
for ( var i = 0, n = keys.length, key; i < n; i++ ) { |
|
||||
key = keys[i]; |
|
||||
target[key] = source[key]; |
|
||||
} |
|
||||
return target; |
|
||||
}; |
|
||||
|
|
||||
/******************************************************************************/ |
|
||||
|
|
||||
// https://github.com/gorhill/uBlock/issues/1070
|
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#Browser_compatibility
|
|
||||
// This polyfill is designed to fulfill *only* what uBlock Origin needs -- this
|
|
||||
// is not an accurate API of the real Set() type.
|
|
||||
|
|
||||
if ( self.Set instanceof Function === false ) { |
|
||||
self.Set = function(iter) { |
|
||||
this.clear(); |
|
||||
if ( Array.isArray(iter) ) { |
|
||||
for ( var i = 0, n = iter.length; i < n; i++ ) { |
|
||||
this.add(iter[i]); |
|
||||
} |
|
||||
return; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
self.Set.polyfill = true; |
|
||||
|
|
||||
self.Set.prototype.clear = function() { |
|
||||
this._set = Object.create(null); |
|
||||
this.size = 0; |
|
||||
// Iterator stuff
|
|
||||
this._values = undefined; |
|
||||
this._i = undefined; |
|
||||
this.value = undefined; |
|
||||
this.done = true; |
|
||||
}; |
|
||||
|
|
||||
self.Set.prototype.add = function(k) { |
|
||||
if ( this._set[k] === undefined ) { |
|
||||
this._set[k] = true; |
|
||||
this.size += 1; |
|
||||
} |
|
||||
return this; |
|
||||
}; |
|
||||
|
|
||||
self.Set.prototype.delete = function(k) { |
|
||||
if ( this._set[k] !== undefined ) { |
|
||||
delete this._set[k]; |
|
||||
this.size -= 1; |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
}; |
|
||||
|
|
||||
self.Set.prototype.has = function(k) { |
|
||||
return this._set[k] !== undefined; |
|
||||
}; |
|
||||
|
|
||||
self.Set.prototype.next = function() { |
|
||||
if ( this._i < this.size ) { |
|
||||
this.value = this._values[this._i++]; |
|
||||
} else { |
|
||||
this._values = undefined; |
|
||||
this.value = undefined; |
|
||||
this.done = true; |
|
||||
} |
|
||||
return this; |
|
||||
}; |
|
||||
|
|
||||
self.Set.prototype.values = function() { |
|
||||
this._values = Object.keys(this._set); |
|
||||
this._i = 0; |
|
||||
this.value = undefined; |
|
||||
this.done = false; |
|
||||
return this; |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
/******************************************************************************/ |
|
||||
|
|
||||
// https://github.com/gorhill/uBlock/issues/1070
|
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#Browser_compatibility
|
|
||||
// This polyfill is designed to fulfill *only* what uBlock Origin needs -- this
|
|
||||
// is not an accurate API of the real Map() type.
|
|
||||
|
|
||||
if ( self.Map instanceof Function === false ) { |
|
||||
self.Map = function(iter) { |
|
||||
this.clear(); |
|
||||
if ( Array.isArray(iter) ) { |
|
||||
for ( var i = 0, n = iter.length, entry; i < n; i++ ) { |
|
||||
entry = iter[i]; |
|
||||
this.set(entry[0], entry[1]); |
|
||||
} |
|
||||
return; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
self.Map.polyfill = true; |
|
||||
|
|
||||
self.Map.prototype.clear = function() { |
|
||||
this._map = Object.create(null); |
|
||||
this.size = 0; |
|
||||
// Iterator stuff
|
|
||||
this._keys = undefined; |
|
||||
this._i = undefined; |
|
||||
this.value = undefined; |
|
||||
this.done = true; |
|
||||
}; |
|
||||
|
|
||||
self.Map.prototype.delete = function(k) { |
|
||||
if ( this._map[k] !== undefined ) { |
|
||||
delete this._map[k]; |
|
||||
this.size -= 1; |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
}; |
|
||||
|
|
||||
self.Map.prototype.entries = function() { |
|
||||
this._keys = Object.keys(this._map); |
|
||||
this._i = 0; |
|
||||
this.value = [ undefined, undefined ]; |
|
||||
this.done = false; |
|
||||
return this; |
|
||||
}; |
|
||||
|
|
||||
self.Map.prototype.get = function(k) { |
|
||||
return this._map[k]; |
|
||||
}; |
|
||||
|
|
||||
self.Map.prototype.has = function(k) { |
|
||||
return this._map[k] !== undefined; |
|
||||
}; |
|
||||
|
|
||||
self.Map.prototype.next = function() { |
|
||||
if ( this._i < this.size ) { |
|
||||
var key = this._keys[this._i++]; |
|
||||
this.value[0] = key; |
|
||||
this.value[1] = this._map[key]; |
|
||||
} else { |
|
||||
this._keys = undefined; |
|
||||
this.value = undefined; |
|
||||
this.done = true; |
|
||||
} |
|
||||
return this; |
|
||||
}; |
|
||||
|
|
||||
self.Map.prototype.set = function(k, v) { |
|
||||
if ( v !== undefined ) { |
|
||||
if ( this._map[k] === undefined ) { |
|
||||
this.size += 1; |
|
||||
} |
|
||||
this._map[k] = v; |
|
||||
} else { |
|
||||
if ( this._map[k] !== undefined ) { |
|
||||
this.size -= 1; |
|
||||
} |
|
||||
delete this._map[k]; |
|
||||
} |
|
||||
return this; |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
/******************************************************************************/ |
|
@ -0,0 +1,194 @@ |
|||||
|
/******************************************************************************* |
||||
|
|
||||
|
uMatrix - a browser extension to block requests. |
||||
|
Copyright (C) 2017-present Raymond Hill |
||||
|
|
||||
|
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/uMatrix
|
||||
|
*/ |
||||
|
|
||||
|
// For background page
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
/******************************************************************************/ |
||||
|
|
||||
|
(function() { |
||||
|
const extToTypeMap = new Map([ |
||||
|
['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'] |
||||
|
]); |
||||
|
|
||||
|
// 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) { |
||||
|
if ( aa.length === 0 ) { |
||||
|
return Array.from(vAPI.net.validTypes); |
||||
|
} |
||||
|
const out = new Set(); |
||||
|
let i = aa.length; |
||||
|
while ( i-- ) { |
||||
|
const type = aa[i]; |
||||
|
if ( vAPI.net.validTypes.has(type) ) { |
||||
|
out.add(type); |
||||
|
} |
||||
|
} |
||||
|
if ( out.has('other') === false ) { |
||||
|
for ( const type of extToTypeMap.values() ) { |
||||
|
if ( out.has(type) ) { |
||||
|
out.add('other'); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return Array.from(out); |
||||
|
}; |
||||
|
|
||||
|
const headerValue = function(headers, name) { |
||||
|
let i = headers.length; |
||||
|
while ( i-- ) { |
||||
|
if ( headers[i].name.toLowerCase() === name ) { |
||||
|
return headers[i].value.trim(); |
||||
|
} |
||||
|
} |
||||
|
return ''; |
||||
|
}; |
||||
|
|
||||
|
const parsedURL = new URL('https://www.example.org/'); |
||||
|
|
||||
|
vAPI.net.normalizeDetails = function(details) { |
||||
|
// Chromium 63+ supports the `initiator` property, which contains
|
||||
|
// the URL of the origin from which the network request was made.
|
||||
|
if ( |
||||
|
typeof details.initiator === 'string' && |
||||
|
details.initiator !== 'null' |
||||
|
) { |
||||
|
details.documentUrl = details.initiator; |
||||
|
} |
||||
|
|
||||
|
let type = details.type; |
||||
|
|
||||
|
// 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
|
||||
|
if ( type !== 'other' ) { return; } |
||||
|
|
||||
|
// Try to map known "extension" part of URL to request type.
|
||||
|
parsedURL.href = details.url; |
||||
|
const path = parsedURL.pathname, |
||||
|
pos = path.indexOf('.', path.length - 6); |
||||
|
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; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
vAPI.net.denormalizeFilters = function(filters) { |
||||
|
const urls = filters.urls || [ '<all_urls>' ]; |
||||
|
let types = filters.types; |
||||
|
if ( Array.isArray(types) ) { |
||||
|
types = denormalizeTypes(types); |
||||
|
} |
||||
|
if ( |
||||
|
(vAPI.net.validTypes.has('websocket')) && |
||||
|
(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://*/*'); |
||||
|
} |
||||
|
} |
||||
|
return { types, urls }; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
/******************************************************************************/ |
||||
|
|
||||
|
// 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); |
||||
|
|
||||
|
//console.log(`Aborting tab ${details.tabId}: ${details.type} ${details.url}`);
|
||||
|
|
||||
|
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 ) { |
||||
|
//console.log(`Reloading tab ${tabId}`);
|
||||
|
vAPI.tabs.reload(tabId); |
||||
|
} |
||||
|
pendings = undefined; |
||||
|
}, |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
/******************************************************************************/ |
@ -1,30 +0,0 @@ |
|||||
/******************************************************************************* |
|
||||
|
|
||||
uBlock Origin - a browser extension to block requests. |
|
||||
Copyright (C) 2016 The uBlock Origin authors |
|
||||
|
|
||||
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 or non-background pages
|
|
||||
|
|
||||
'use strict'; |
|
||||
|
|
||||
/******************************************************************************/ |
|
||||
|
|
||||
var objectAssign = Object.assign; |
|
||||
|
|
||||
/******************************************************************************/ |
|
@ -0,0 +1,185 @@ |
|||||
|
/******************************************************************************* |
||||
|
|
||||
|
uMatrix - a browser extension to block requests. |
||||
|
Copyright (C) 2017-present Raymond Hill |
||||
|
|
||||
|
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/uMatrix
|
||||
|
*/ |
||||
|
|
||||
|
// For background page
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
/******************************************************************************/ |
||||
|
|
||||
|
(function() { |
||||
|
|
||||
|
// https://github.com/gorhill/uBlock/issues/2950
|
||||
|
// Firefox 56 does not normalize URLs to ASCII, uBO must do this itself.
|
||||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=945240
|
||||
|
const evalMustPunycode = function() { |
||||
|
return vAPI.webextFlavor.soup.has('firefox') && |
||||
|
vAPI.webextFlavor.major < 57; |
||||
|
}; |
||||
|
|
||||
|
let mustPunycode = evalMustPunycode(); |
||||
|
|
||||
|
// The real actual webextFlavor value may not be set in stone, so listen
|
||||
|
// for possible future changes.
|
||||
|
window.addEventListener('webextFlavor', ( ) => { |
||||
|
mustPunycode = evalMustPunycode(); |
||||
|
}, { once: true }); |
||||
|
|
||||
|
const denormalizeTypes = function(aa) { |
||||
|
if ( aa.length === 0 ) { |
||||
|
return Array.from(vAPI.net.validTypes); |
||||
|
} |
||||
|
const out = new Set(); |
||||
|
let i = aa.length; |
||||
|
while ( i-- ) { |
||||
|
let type = aa[i]; |
||||
|
if ( vAPI.net.validTypes.has(type) ) { |
||||
|
out.add(type); |
||||
|
} |
||||
|
if ( type === 'image' && vAPI.net.validTypes.has('imageset') ) { |
||||
|
out.add('imageset'); |
||||
|
} |
||||
|
if ( type === 'sub_frame' ) { |
||||
|
out.add('object'); |
||||
|
} |
||||
|
} |
||||
|
return Array.from(out); |
||||
|
}; |
||||
|
|
||||
|
const punycode = self.punycode; |
||||
|
const reAsciiHostname = /^https?:\/\/[0-9a-z_.:@-]+[/?#]/; |
||||
|
const parsedURL = new URL('about:blank'); |
||||
|
|
||||
|
vAPI.net.normalizeDetails = function(details) { |
||||
|
if ( mustPunycode && !reAsciiHostname.test(details.url) ) { |
||||
|
parsedURL.href = details.url; |
||||
|
details.url = details.url.replace( |
||||
|
parsedURL.hostname, |
||||
|
punycode.toASCII(parsedURL.hostname) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
const type = details.type; |
||||
|
|
||||
|
// 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; |
||||
|
} |
||||
|
|
||||
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/345
|
||||
|
// Re-categorize an embedded object as a `sub_frame` if its
|
||||
|
// content type is that of a HTML document.
|
||||
|
if ( type === 'object' && Array.isArray(details.responseHeaders) ) { |
||||
|
for ( const header of details.responseHeaders ) { |
||||
|
if ( header.name.toLowerCase() === 'content-type' ) { |
||||
|
if ( header.value.startsWith('text/html') ) { |
||||
|
details.type = 'sub_frame'; |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
vAPI.net.denormalizeFilters = function(filters) { |
||||
|
const urls = filters.urls || [ '<all_urls>' ]; |
||||
|
let types = filters.types; |
||||
|
if ( Array.isArray(types) ) { |
||||
|
types = denormalizeTypes(types); |
||||
|
} |
||||
|
if ( |
||||
|
(vAPI.net.validTypes.has('websocket')) && |
||||
|
(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://*/*'); |
||||
|
} |
||||
|
} |
||||
|
return { types, urls }; |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
/******************************************************************************/ |
||||
|
|
||||
|
// Related issues:
|
||||
|
// - https://github.com/gorhill/uBlock/issues/1327
|
||||
|
// - https://github.com/uBlockOrigin/uBlock-issues/issues/128
|
||||
|
// - https://bugzilla.mozilla.org/show_bug.cgi?id=1503721
|
||||
|
|
||||
|
vAPI.net.onBeforeReady = (function() { |
||||
|
let pendings; |
||||
|
|
||||
|
const handler = function(details) { |
||||
|
if ( pendings === undefined ) { return; } |
||||
|
if ( details.tabId < 0 ) { return; } |
||||
|
|
||||
|
//console.log(`Deferring tab ${details.tabId}: ${details.type} ${details.url}`);
|
||||
|
|
||||
|
const pending = { |
||||
|
details: Object.assign({}, details), |
||||
|
resolve: undefined, |
||||
|
promise: undefined |
||||
|
}; |
||||
|
|
||||
|
pending.promise = new Promise(function(resolve) { |
||||
|
pending.resolve = resolve; |
||||
|
}); |
||||
|
|
||||
|
pendings.push(pending); |
||||
|
|
||||
|
return pending.promise; |
||||
|
}; |
||||
|
|
||||
|
return { |
||||
|
start: function() { |
||||
|
pendings = []; |
||||
|
browser.webRequest.onBeforeRequest.addListener( |
||||
|
handler, |
||||
|
{ urls: [ 'http://*/*', 'https://*/*' ] }, |
||||
|
[ 'blocking' ] |
||||
|
); |
||||
|
}, |
||||
|
stop: function(resolver) { |
||||
|
if ( pendings === undefined ) { return; } |
||||
|
for ( const pending of pendings ) { |
||||
|
const details = pending.details; |
||||
|
vAPI.net.normalizeDetails(details); |
||||
|
//console.log(`Processing tab ${details.tabId}: ${details.type} ${details.url}`);
|
||||
|
pending.resolve(resolver(details)); |
||||
|
} |
||||
|
pendings = undefined; |
||||
|
}, |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
/******************************************************************************/ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue