mirror of
https://github.com/gorhill/uMatrix.git
synced 2024-09-29 16:51:13 +13:00
various fixes
This commit is contained in:
parent
33b5ac1a57
commit
4ad7c65362
10 changed files with 176 additions and 152 deletions
|
@ -1971,7 +1971,7 @@ vAPI.cookies.getAll = function(callback) {
|
||||||
vAPI.cookies.remove = function(details, callback) {
|
vAPI.cookies.remove = function(details, callback) {
|
||||||
// TODO
|
// TODO
|
||||||
if ( typeof callback === 'function' ) {
|
if ( typeof callback === 'function' ) {
|
||||||
callback();
|
callback(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
body {
|
body {
|
||||||
|
background-color: white;
|
||||||
border: 0;
|
border: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
color: black;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
@ -57,67 +59,62 @@ input:focus {
|
||||||
}
|
}
|
||||||
#content table tr {
|
#content table tr {
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
|
color: #444;
|
||||||
}
|
}
|
||||||
#content table tr.cat_info {
|
#content table tr.cat_info {
|
||||||
color: #00a;
|
color: #00f;
|
||||||
}
|
}
|
||||||
#content table tr.blocked {
|
#content table tr.blocked {
|
||||||
color: #c00;
|
color: #f00;
|
||||||
}
|
}
|
||||||
#content table tr:nth-of-type(2n+1) {
|
#content table tr:nth-of-type(2n+1) {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
}
|
}
|
||||||
#content table tr > td[colspan="3"]:nth-of-type(2) {
|
|
||||||
white-space: normal;
|
|
||||||
word-break: break-all;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
#content table tr.doc {
|
#content table tr.doc {
|
||||||
background-color: #666;
|
background-color: #666;
|
||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
#content table tr.doc > td {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
#content table tr.doc > td:nth-of-type(2) {
|
|
||||||
padding: 0.6em 0;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
#content table tr.allowed {
|
|
||||||
background-color: rgba(0, 160, 0, 0.1);
|
|
||||||
}
|
|
||||||
#content table tr.allowed:nth-of-type(2n+1) {
|
|
||||||
background-color: rgba(0, 160, 0, 0.2);
|
|
||||||
}
|
|
||||||
body.colorBlind #content table tr.allowed {
|
|
||||||
background-color: rgba(255, 194, 57, 0.1)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
body:not(.filterOff) #content table tr.hidden {
|
body:not(.filterOff) #content table tr.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#content table tr td {
|
#content table tr td {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
|
min-width: 0.5em;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
#content table tr.doc > td {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
#content table tr td:nth-of-type(1) {
|
#content table tr td:nth-of-type(1) {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
width: 8em;
|
width: 8em;
|
||||||
}
|
}
|
||||||
#content table tr td:nth-of-type(2) {
|
#content table tr td:nth-of-type(2) {
|
||||||
white-space: pre;
|
width: 1em;
|
||||||
width: 2em;
|
|
||||||
}
|
}
|
||||||
#content table tr td:nth-of-type(3) {
|
#content table tr td:nth-of-type(3) {
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
width: 8em;
|
width: 2em;
|
||||||
}
|
}
|
||||||
#content table tr td:nth-of-type(4) {
|
#content table tr td:nth-of-type(4) {
|
||||||
|
white-space: pre;
|
||||||
|
width: 8em;
|
||||||
|
}
|
||||||
|
#content table tr td:nth-of-type(5) {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
#content table tr.tab_bts > td:nth-of-type(2):before {
|
||||||
|
content: '\f070';
|
||||||
|
font: 1em FontAwesome;
|
||||||
|
}
|
||||||
|
#content table tr > td[colspan="3"]:nth-of-type(3) {
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-all;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ body .toolbar button.disabled {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
body .toolbar button.fa {
|
body .toolbar button.fa {
|
||||||
font: 1.75em 'FontAwesome';
|
font: 1.75em FontAwesome;
|
||||||
min-width: 1.1em;
|
min-width: 1.1em;
|
||||||
}
|
}
|
||||||
body.tScopeGlobal .scopeRel:not(.disabled) {
|
body.tScopeGlobal .scopeRel:not(.disabled) {
|
||||||
|
|
|
@ -287,20 +287,28 @@ var removeCookieAsync = function(cookieKey) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// TODO: i18n
|
||||||
|
|
||||||
var chromeCookieRemove = function(url, name) {
|
var chromeCookieRemove = function(url, name) {
|
||||||
|
var sessionCookieKey = cookieKeyFromCookieURL(url, 'session', name);
|
||||||
|
var persistCookieKey = cookieKeyFromCookieURL(url, 'persistent', name);
|
||||||
var callback = function(details) {
|
var callback = function(details) {
|
||||||
if ( !details ) {
|
var success = !!details;
|
||||||
return;
|
if ( cookieDict.hasOwnProperty(sessionCookieKey) ) {
|
||||||
|
if ( success ) {
|
||||||
|
µm.logger.writeOne('', 'info', 'cookie deleted: ' + sessionCookieKey);
|
||||||
|
µm.cookieRemovedCounter += 1;
|
||||||
|
} else {
|
||||||
|
µm.logger.writeOne('', 'error', 'failed to delete cookie: ' + sessionCookieKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var cookieKey = cookieKeyFromCookieURL(details.url, 'session', details.name);
|
if ( cookieDict.hasOwnProperty(persistCookieKey) ) {
|
||||||
if ( removeCookieFromDict(cookieKey) ) {
|
if ( success ) {
|
||||||
µm.logger.writeOne('', 'info', 'cookie deleted: ' + cookieKey);
|
µm.logger.writeOne('', 'info', 'cookie deleted: ' + persistCookieKey);
|
||||||
µm.cookieRemovedCounter += 1;
|
µm.cookieRemovedCounter += 1;
|
||||||
}
|
} else {
|
||||||
cookieKey = cookieKeyFromCookieURL(details.url, 'persistent', details.name);
|
µm.logger.writeOne('', 'error', 'failed to delete cookie: ' + persistCookieKey);
|
||||||
if ( removeCookieFromDict(cookieKey) ) {
|
}
|
||||||
µm.logger.writeOne('', 'info', 'cookie deleted: ' + cookieKey);
|
|
||||||
µm.cookieRemovedCounter += 1;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,9 @@ var body = doc.body;
|
||||||
var tbody = doc.querySelector('#content tbody');
|
var tbody = doc.querySelector('#content tbody');
|
||||||
var trJunkyard = [];
|
var trJunkyard = [];
|
||||||
var tdJunkyard = [];
|
var tdJunkyard = [];
|
||||||
var firstVarDataCol = 1;
|
var firstVarDataCol = 2; // currently, column 2 (0-based index)
|
||||||
var lastVarDataCol = 3;
|
var lastVarDataIndex = 3; // currently, d0-d3
|
||||||
|
var noTabId = '';
|
||||||
|
|
||||||
var prettyRequestTypes = {
|
var prettyRequestTypes = {
|
||||||
'main_frame': 'doc',
|
'main_frame': 'doc',
|
||||||
|
@ -61,12 +62,22 @@ var timeOptions = {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var createCell = function() {
|
var createCellAt = function(tr, index) {
|
||||||
var td = tdJunkyard.pop();
|
var td = tr.cells[index];
|
||||||
if ( td ) {
|
var mustAppend = !td;
|
||||||
return td;
|
if ( mustAppend ) {
|
||||||
|
td = tdJunkyard.pop();
|
||||||
}
|
}
|
||||||
return doc.createElement('td');
|
if ( td ) {
|
||||||
|
td.removeAttribute('colspan');
|
||||||
|
td.textContent = '';
|
||||||
|
} else {
|
||||||
|
td = doc.createElement('td');
|
||||||
|
}
|
||||||
|
if ( mustAppend ) {
|
||||||
|
tr.appendChild(td);
|
||||||
|
}
|
||||||
|
return td;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -78,23 +89,13 @@ var createRow = function(entry) {
|
||||||
} else {
|
} else {
|
||||||
tr = doc.createElement('tr');
|
tr = doc.createElement('tr');
|
||||||
}
|
}
|
||||||
var td;
|
|
||||||
for ( var index = 0; index < firstVarDataCol; index++ ) {
|
for ( var index = 0; index < firstVarDataCol; index++ ) {
|
||||||
td = tr.cells[index];
|
createCellAt(tr, index);
|
||||||
if ( td === undefined ) {
|
|
||||||
td = createCell();
|
|
||||||
tr.appendChild(td);
|
|
||||||
}
|
|
||||||
td.removeAttribute('colspan');
|
|
||||||
}
|
}
|
||||||
var i = 1, span = 1;
|
var i = 1, span = 1, td;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
td = tr.cells[index];
|
td = createCellAt(tr, index);
|
||||||
if ( td === undefined ) {
|
if ( i === lastVarDataIndex ) {
|
||||||
td = createCell();
|
|
||||||
tr.appendChild(td);
|
|
||||||
}
|
|
||||||
if ( i === lastVarDataCol ) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( entry['d' + i] === undefined ) {
|
if ( entry['d' + i] === undefined ) {
|
||||||
|
@ -102,8 +103,6 @@ var createRow = function(entry) {
|
||||||
} else {
|
} else {
|
||||||
if ( span !== 1 ) {
|
if ( span !== 1 ) {
|
||||||
td.setAttribute('colspan', span);
|
td.setAttribute('colspan', span);
|
||||||
} else {
|
|
||||||
td.removeAttribute('colspan');
|
|
||||||
}
|
}
|
||||||
index += 1;
|
index += 1;
|
||||||
span = 1;
|
span = 1;
|
||||||
|
@ -112,8 +111,6 @@ var createRow = function(entry) {
|
||||||
}
|
}
|
||||||
if ( span !== 1 ) {
|
if ( span !== 1 ) {
|
||||||
td.setAttribute('colspan', span);
|
td.setAttribute('colspan', span);
|
||||||
} else {
|
|
||||||
td.removeAttribute('colspan');
|
|
||||||
}
|
}
|
||||||
index += 1;
|
index += 1;
|
||||||
while ( td = tr.cells[index] ) {
|
while ( td = tr.cells[index] ) {
|
||||||
|
@ -134,17 +131,25 @@ var createGap = function(url) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var renderLogEntry = function(entry) {
|
var renderLogEntry = function(entry) {
|
||||||
|
var fvdc = firstVarDataCol;
|
||||||
var tr = createRow(entry);
|
var tr = createRow(entry);
|
||||||
|
|
||||||
tr.classList.add('tab_' + entry.tab);
|
if ( entry.tab === noTabId ) {
|
||||||
tr.classList.add('cat_' + entry.cat);
|
tr.classList.add('tab_bts');
|
||||||
|
} else if ( entry.tab !== '' ) {
|
||||||
|
tr.classList.add('tab_' + entry.tab);
|
||||||
|
}
|
||||||
|
if ( entry.cat !== '' ) {
|
||||||
|
tr.classList.add('cat_' + entry.cat);
|
||||||
|
}
|
||||||
|
|
||||||
var time = new Date(entry.tstamp);
|
var time = new Date(entry.tstamp);
|
||||||
tr.cells[0].textContent = time.toLocaleString('fullwide', timeOptions);
|
tr.cells[0].textContent = time.toLocaleString('fullwide', timeOptions);
|
||||||
|
|
||||||
switch ( entry.cat ) {
|
switch ( entry.cat ) {
|
||||||
|
case 'error':
|
||||||
case 'info':
|
case 'info':
|
||||||
tr.cells[firstVarDataCol].textContent = entry.d0;
|
tr.cells[fvdc].textContent = entry.d0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'net':
|
case 'net':
|
||||||
|
@ -155,15 +160,16 @@ var renderLogEntry = function(entry) {
|
||||||
}
|
}
|
||||||
if ( entry.d0 ) {
|
if ( entry.d0 ) {
|
||||||
tr.classList.add('blocked');
|
tr.classList.add('blocked');
|
||||||
tr.cells[1].textContent = '---';
|
tr.cells[fvdc].textContent = '---';
|
||||||
} else {
|
} else {
|
||||||
tr.cells[1].textContent = '';
|
tr.cells[fvdc].textContent = '';
|
||||||
}
|
}
|
||||||
tr.cells[2].textContent = (prettyRequestTypes[entry.d1] || entry.d1) + '\t';
|
tr.cells[fvdc+1].textContent = (prettyRequestTypes[entry.d1] || entry.d1) + '\t';
|
||||||
tr.cells[3].textContent = entry.d2 + '\t';
|
tr.cells[fvdc+2].textContent = entry.d2 + '\t';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
tr.cells[fvdc].textContent = entry.d0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +184,8 @@ var renderLogBuffer = function(response) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noTabId = response.noTabId;
|
||||||
|
|
||||||
// Preserve scroll position
|
// Preserve scroll position
|
||||||
var height = tbody.offsetHeight;
|
var height = tbody.offsetHeight;
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,9 @@ LogEntry.prototype.init = function(args) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
LogEntry.prototype.dispose = function() {
|
LogEntry.prototype.dispose = function() {
|
||||||
this.url = this.hostname = this.type = this.result = '';
|
this.tstamp = 0;
|
||||||
|
this.tab = this.cat = '';
|
||||||
|
this.d0 = this.d1 = this.d2 = this.d3 = undefined;
|
||||||
if ( logEntryJunkyard.length < logEntryJunkyardMax ) {
|
if ( logEntryJunkyard.length < logEntryJunkyardMax ) {
|
||||||
logEntryJunkyard.push(this);
|
logEntryJunkyard.push(this);
|
||||||
}
|
}
|
||||||
|
@ -152,16 +154,26 @@ var logBuffer = null;
|
||||||
// thus removed from memory.
|
// thus removed from memory.
|
||||||
var logBufferObsoleteAfter = 60 * 1000;
|
var logBufferObsoleteAfter = 60 * 1000;
|
||||||
|
|
||||||
// The janitor will look for stale log buffer every 2 minutes.
|
/******************************************************************************/
|
||||||
var loggerJanitorPeriod = 2 * 60 * 1000;
|
|
||||||
|
var janitor = function() {
|
||||||
|
if (
|
||||||
|
logBuffer !== null &&
|
||||||
|
logBuffer.lastReadTime < (Date.now() - logBufferObsoleteAfter)
|
||||||
|
) {
|
||||||
|
logBuffer = logBuffer.dispose();
|
||||||
|
}
|
||||||
|
if ( logBuffer !== null ) {
|
||||||
|
setTimeout(janitor, logBufferObsoleteAfter);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var writeOne = function() {
|
var writeOne = function() {
|
||||||
if ( logBuffer === null ) {
|
if ( logBuffer !== null ) {
|
||||||
return;
|
logBuffer.writeOne(arguments);
|
||||||
}
|
}
|
||||||
logBuffer.writeOne(arguments);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -169,26 +181,13 @@ var writeOne = function() {
|
||||||
var readAll = function(tabId) {
|
var readAll = function(tabId) {
|
||||||
if ( logBuffer === null ) {
|
if ( logBuffer === null ) {
|
||||||
logBuffer = new LogBuffer();
|
logBuffer = new LogBuffer();
|
||||||
|
setTimeout(janitor, logBufferObsoleteAfter);
|
||||||
}
|
}
|
||||||
return logBuffer.readAll();
|
return logBuffer.readAll();
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var loggerJanitor = function() {
|
|
||||||
if (
|
|
||||||
logBuffer !== null &&
|
|
||||||
logBuffer.lastReadTime < (Date.now() - logBufferObsoleteAfter)
|
|
||||||
) {
|
|
||||||
logBuffer = logBuffer.dispose();
|
|
||||||
}
|
|
||||||
setTimeout(loggerJanitor, loggerJanitorPeriod);
|
|
||||||
};
|
|
||||||
|
|
||||||
setTimeout(loggerJanitor, loggerJanitorPeriod);
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
writeOne: writeOne,
|
writeOne: writeOne,
|
||||||
readAll: readAll
|
readAll: readAll
|
||||||
|
|
|
@ -974,6 +974,7 @@ var onMessage = function(request, sender, callback) {
|
||||||
case 'readMany':
|
case 'readMany':
|
||||||
response = {
|
response = {
|
||||||
colorBlind: false,
|
colorBlind: false,
|
||||||
|
noTabId: vAPI.noTabId,
|
||||||
entries: µm.logger.readAll(request.tabId)
|
entries: µm.logger.readAll(request.tabId)
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -157,8 +157,10 @@ housekeep itself.
|
||||||
this.stack = [];
|
this.stack = [];
|
||||||
this.rawURL =
|
this.rawURL =
|
||||||
this.normalURL =
|
this.normalURL =
|
||||||
|
this.scheme =
|
||||||
this.rootHostname =
|
this.rootHostname =
|
||||||
this.rootDomain = '';
|
this.rootDomain = '';
|
||||||
|
this.secure = false;
|
||||||
this.timer = null;
|
this.timer = null;
|
||||||
this.onTabCallback = null;
|
this.onTabCallback = null;
|
||||||
this.onTimerCallback = null;
|
this.onTimerCallback = null;
|
||||||
|
@ -209,13 +211,19 @@ housekeep itself.
|
||||||
// root URL.
|
// root URL.
|
||||||
TabContext.prototype.update = function() {
|
TabContext.prototype.update = function() {
|
||||||
if ( this.stack.length === 0 ) {
|
if ( this.stack.length === 0 ) {
|
||||||
this.rawURL = this.normalURL = this.rootHostname = this.rootDomain = '';
|
this.rawURL =
|
||||||
|
this.normalURL =
|
||||||
|
this.scheme =
|
||||||
|
this.rootHostname =
|
||||||
|
this.rootDomain = '';
|
||||||
} else {
|
} else {
|
||||||
this.rawURL = this.stack[this.stack.length - 1];
|
this.rawURL = this.stack[this.stack.length - 1];
|
||||||
this.normalURL = µm.normalizePageURL(this.tabId, this.rawURL);
|
this.normalURL = µm.normalizePageURL(this.tabId, this.rawURL);
|
||||||
|
this.scheme = µm.URI.schemeFromURI(this.rawURL);
|
||||||
this.rootHostname = µm.URI.hostnameFromURI(this.normalURL);
|
this.rootHostname = µm.URI.hostnameFromURI(this.normalURL);
|
||||||
this.rootDomain = µm.URI.domainFromHostname(this.rootHostname) || this.rootHostname;
|
this.rootDomain = µm.URI.domainFromHostname(this.rootHostname) || this.rootHostname;
|
||||||
}
|
}
|
||||||
|
this.secure = µm.URI.isSecureScheme(this.scheme);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Called whenever a candidate root URL is spotted for the tab.
|
// Called whenever a candidate root URL is spotted for the tab.
|
||||||
|
@ -223,6 +231,10 @@ housekeep itself.
|
||||||
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) {
|
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var count = this.stack.length;
|
||||||
|
if ( count !== 0 && this.stack[count - 1] === url ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.stack.push(url);
|
this.stack.push(url);
|
||||||
this.update();
|
this.update();
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,11 +73,10 @@ var onBeforeRootFrameRequestHandler = function(details) {
|
||||||
|
|
||||||
var onBeforeRequestHandler = function(details) {
|
var onBeforeRequestHandler = function(details) {
|
||||||
var µm = µMatrix;
|
var µm = µMatrix;
|
||||||
var µmuri = µm.URI.set(details.url);
|
|
||||||
var requestScheme = µmuri.scheme;
|
|
||||||
|
|
||||||
// rhill 2014-02-17: Ignore 'filesystem:': this can happen when listening
|
// rhill 2014-02-17: Ignore 'filesystem:': this can happen when listening
|
||||||
// to 'chrome-extension://'.
|
// to 'chrome-extension://'.
|
||||||
|
var requestScheme = µm.URI.schemeFromURI(details.url);
|
||||||
if ( requestScheme === 'filesystem' ) {
|
if ( requestScheme === 'filesystem' ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +95,7 @@ var onBeforeRequestHandler = function(details) {
|
||||||
var requestURL = details.url;
|
var requestURL = details.url;
|
||||||
|
|
||||||
// Ignore non-http schemes
|
// Ignore non-http schemes
|
||||||
if ( requestScheme.indexOf('http') !== 0 ) {
|
if ( requestScheme.lastIndexOf('http', 0) !== 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,10 +114,21 @@ var onBeforeRequestHandler = function(details) {
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
|
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
|
||||||
var tabContext = µm.tabContextManager.mustLookup(details.tabId);
|
var tabContext = µm.tabContextManager.mustLookup(details.tabId);
|
||||||
var tabId = tabContext.tabId;
|
var tabId = tabContext.tabId;
|
||||||
var requestHostname = µmuri.hostname;
|
|
||||||
|
// Enforce strict secure connection?
|
||||||
|
var block = false;
|
||||||
|
if (
|
||||||
|
tabContext.secure &&
|
||||||
|
µm.URI.isSecureScheme(requestScheme) === false &&
|
||||||
|
µm.tMatrix.evaluateSwitchZ('https-strict', tabContext.rootHostname)
|
||||||
|
) {
|
||||||
|
block = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Disallow request as per temporary matrix?
|
// Disallow request as per temporary matrix?
|
||||||
var block = µm.mustBlock(tabContext.rootHostname, requestHostname, requestType);
|
if ( block === false ) {
|
||||||
|
block = µm.mustBlock(tabContext.rootHostname, details.hostname, requestType);
|
||||||
|
}
|
||||||
|
|
||||||
// Record request.
|
// Record request.
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/342
|
// https://github.com/gorhill/httpswitchboard/issues/342
|
||||||
|
@ -126,16 +136,16 @@ var onBeforeRequestHandler = function(details) {
|
||||||
// processing has already been performed, and that a synthetic URL has
|
// processing has already been performed, and that a synthetic URL has
|
||||||
// been constructed for logging purpose. Use this synthetic URL if
|
// been constructed for logging purpose. Use this synthetic URL if
|
||||||
// it is available.
|
// it is available.
|
||||||
var pageStore = µm.mustPageStoreFromTabId(details.tabId);
|
var pageStore = µm.mustPageStoreFromTabId(tabContext.tabId);
|
||||||
pageStore.recordRequest(requestType, requestURL, block);
|
pageStore.recordRequest(requestType, requestURL, block);
|
||||||
|
|
||||||
// whitelisted?
|
// Allowed?
|
||||||
if ( !block ) {
|
if ( !block ) {
|
||||||
// console.debug('onBeforeRequestHandler()> ALLOW "%s": %o', details.url, details);
|
// console.debug('onBeforeRequestHandler()> ALLOW "%s": %o', details.url, details);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// blacklisted
|
// Blocked
|
||||||
// console.debug('onBeforeRequestHandler()> BLOCK "%s": %o', details.url, details);
|
// console.debug('onBeforeRequestHandler()> BLOCK "%s": %o', details.url, details);
|
||||||
|
|
||||||
return { 'cancel': true };
|
return { 'cancel': true };
|
||||||
|
@ -198,16 +208,14 @@ var onBeforeSendHeadersHandler = function(details) {
|
||||||
// If we reach this point, request is not blocked, so what is left to do
|
// If we reach this point, request is not blocked, so what is left to do
|
||||||
// is to sanitize headers.
|
// is to sanitize headers.
|
||||||
|
|
||||||
var reqHostname = µm.hostnameFromURL(requestURL);
|
if ( µm.mustBlock(pageStore.pageHostname, details.hostname, 'cookie') ) {
|
||||||
|
|
||||||
if ( µm.mustBlock(pageStore.pageHostname, reqHostname, 'cookie') ) {
|
|
||||||
if ( details.requestHeaders.setHeader('cookie', '') ) {
|
if ( details.requestHeaders.setHeader('cookie', '') ) {
|
||||||
µm.cookieHeaderFoiledCounter++;
|
µm.cookieHeaderFoiledCounter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( µm.tMatrix.evaluateSwitchZ('referrer-spoof', pageStore.pageHostname) ) {
|
if ( µm.tMatrix.evaluateSwitchZ('referrer-spoof', pageStore.pageHostname) ) {
|
||||||
foilRefererHeaders(µm, reqHostname, details);
|
foilRefererHeaders(µm, details.hostname, details);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( µm.tMatrix.evaluateSwitchZ('ua-spoof', pageStore.pageHostname) ) {
|
if ( µm.tMatrix.evaluateSwitchZ('ua-spoof', pageStore.pageHostname) ) {
|
||||||
|
@ -267,83 +275,63 @@ var onHeadersReceived = function(details) {
|
||||||
|
|
||||||
var onMainDocHeadersReceived = function(details) {
|
var onMainDocHeadersReceived = function(details) {
|
||||||
var µm = µMatrix;
|
var µm = µMatrix;
|
||||||
|
var tabId = details.tabId;
|
||||||
|
var requestURL = details.url;
|
||||||
|
|
||||||
// https://github.com/gorhill/uMatrix/issues/145
|
// https://github.com/gorhill/uMatrix/issues/145
|
||||||
// Check if the main_frame is a download
|
// Check if the main_frame is a download
|
||||||
if ( headerValue(details.responseHeaders, 'content-disposition').lastIndexOf('attachment', 0) === 0 ) {
|
if ( headerValue(details.responseHeaders, 'content-type').lastIndexOf('application/x-', 0) === 0 ) {
|
||||||
µm.tabContextManager.unpush(details.tabId, details.url);
|
µm.tabContextManager.unpush(tabId, requestURL);
|
||||||
|
} else {
|
||||||
|
µm.tabContextManager.push(tabId, requestURL);
|
||||||
}
|
}
|
||||||
var tabContext = µm.tabContextManager.lookup(details.tabId);
|
|
||||||
|
var tabContext = µm.tabContextManager.lookup(tabId);
|
||||||
if ( tabContext === null ) {
|
if ( tabContext === null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.debug('onMainDocHeadersReceived()> "%s": %o', details.url, details);
|
// console.debug('onMainDocHeadersReceived()> "%s": %o', requestURL, details);
|
||||||
|
|
||||||
// rhill 2013-12-07:
|
var blockScript = µm.mustBlock(tabContext.rootHostname, tabContext.rootHostname, 'script');
|
||||||
// Apparently in Opera, onBeforeRequest() is triggered while the
|
|
||||||
// URL is not yet bound to a tab (-1), which caused the code here
|
|
||||||
// to not be able to lookup the page store. So let the code here bind
|
|
||||||
// the page to a tab if not done yet.
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/75
|
|
||||||
|
|
||||||
// TODO: check this works fine on Opera
|
|
||||||
|
|
||||||
// Re-classify orphan HTTP requests as behind-the-scene requests. There is
|
|
||||||
// not much else which can be done, because there are URLs
|
|
||||||
// which cannot be handled by HTTP Switchboard, i.e. `opera://startpage`,
|
|
||||||
// as this would lead to complications with no obvious solution, like how
|
|
||||||
// to scope on unknown scheme? Etc.
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/191
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
|
|
||||||
var pageStore = µm.mustPageStoreFromTabId(details.tabId);
|
|
||||||
var headers = details.responseHeaders;
|
|
||||||
|
|
||||||
// Maybe modify inbound headers
|
|
||||||
var csp = '';
|
|
||||||
|
|
||||||
// Enforce strict HTTPS?
|
|
||||||
var requestScheme = µm.URI.schemeFromURI(details.url);
|
|
||||||
if ( requestScheme === 'https' && µm.tMatrix.evaluateSwitchZ('https-strict', tabContext.rootHostname) ) {
|
|
||||||
csp += "default-src chrome-search: data: https: wss: 'unsafe-eval' 'unsafe-inline';";
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/181
|
// https://github.com/gorhill/httpswitchboard/issues/181
|
||||||
pageStore.pageScriptBlocked = µm.mustBlock(tabContext.rootHostname, tabContext.rootHostname, 'script');
|
var pageStore = µm.pageStoreFromTabId(tabId);
|
||||||
if ( pageStore.pageScriptBlocked ) {
|
if ( pageStore ) {
|
||||||
// If javascript not allowed, say so through a `Content-Security-Policy` directive.
|
pageStore.pageScriptBlocked = blockScript;
|
||||||
// console.debug('onMainDocHeadersReceived()> PAGE CSP "%s": %o', details.url, details);
|
|
||||||
csp += " script-src 'none'";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/181
|
if ( !blockScript ) {
|
||||||
if ( csp !== '' ) {
|
return;
|
||||||
headers.push({
|
|
||||||
'name': 'Content-Security-Policy',
|
|
||||||
'value': csp.trim()
|
|
||||||
});
|
|
||||||
return { responseHeaders: headers };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
µm.logger.writeOne(tabId, 'net', '---', 'inline-script', requestURL);
|
||||||
|
|
||||||
|
// If javascript not allowed, say so through a `Content-Security-Policy` directive.
|
||||||
|
details.responseHeaders.push({
|
||||||
|
'name': 'Content-Security-Policy',
|
||||||
|
'value': "script-src 'none'"
|
||||||
|
});
|
||||||
|
return { responseHeaders: details.responseHeaders };
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var onSubDocHeadersReceived = function(details) {
|
var onSubDocHeadersReceived = function(details) {
|
||||||
|
var µm = µMatrix;
|
||||||
|
var tabId = details.tabId;
|
||||||
|
|
||||||
// console.debug('onSubDocHeadersReceived()> "%s": %o', details.url, details);
|
// console.debug('onSubDocHeadersReceived()> "%s": %o', details.url, details);
|
||||||
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
// Do not ignore traffic outside tabs.
|
// Do not ignore traffic outside tabs.
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
|
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
|
||||||
var tabId = details.tabId;
|
|
||||||
var tabContext = µm.tabContextManager.lookup(tabId);
|
var tabContext = µm.tabContextManager.lookup(tabId);
|
||||||
if ( tabContext === null ) {
|
if ( tabContext === null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate
|
// Evaluate
|
||||||
if ( µm.mustAllow(tabContext.rootHostname, µm.hostnameFromURL(details.url), 'script') ) {
|
if ( µm.mustAllow(tabContext.rootHostname, details.hostname, 'script') ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,6 +356,9 @@ var onSubDocHeadersReceived = function(details) {
|
||||||
|
|
||||||
// console.debug('onSubDocHeadersReceived()> FRAME CSP "%s": %o, scope="%s"', details.url, details, pageURL);
|
// console.debug('onSubDocHeadersReceived()> FRAME CSP "%s": %o, scope="%s"', details.url, details, pageURL);
|
||||||
|
|
||||||
|
µm.logger.writeOne(tabId, 'net', '---', 'inline-script', details.url);
|
||||||
|
|
||||||
|
// If javascript not allowed, say so through a `Content-Security-Policy` directive.
|
||||||
details.responseHeaders.push({
|
details.responseHeaders.push({
|
||||||
'name': 'Content-Security-Policy',
|
'name': 'Content-Security-Policy',
|
||||||
'value': "script-src 'none'"
|
'value': "script-src 'none'"
|
||||||
|
|
|
@ -236,6 +236,14 @@ URI.schemeFromURI = function(uri) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
URI.isSecureScheme = function(scheme) {
|
||||||
|
return scheme === 'https' ||
|
||||||
|
scheme === 'wss' ||
|
||||||
|
scheme === 'ftps';
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
URI.authorityFromURI = function(uri) {
|
URI.authorityFromURI = function(uri) {
|
||||||
var matches = reAuthorityFromURI.exec(uri);
|
var matches = reAuthorityFromURI.exec(uri);
|
||||||
if ( !matches ) {
|
if ( !matches ) {
|
||||||
|
|
Loading…
Reference in a new issue