Browse Source

avoid over-reporting of cookies

Limit each distinct cookie to be reported at most
once a second. Sometimes a cookie's value can
be changed many times a second and it's not useful
to report every single instance of these
changes -- this just pollute both the badge
counter and the logger output.
pull/2/head
Raymond Hill 7 years ago
parent
commit
9fd6bdfddd
No known key found for this signature in database GPG Key ID: 25E1490B761470C2
  1. 169
      src/js/cookies.js
  2. 1
      src/js/pagestats.js

169
src/js/cookies.js

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uMatrix - a Chromium browser extension to black/white list requests.
Copyright (C) 2013-2017 Raymond Hill
uMatrix - a browser extension to black/white list requests.
Copyright (C) 2013-2018 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -184,64 +184,78 @@ var cookieMatchDomains = function(cookieKey, allHostnamesString) {
// Look for cookies to record for a specific web page // Look for cookies to record for a specific web page
var recordPageCookiesAsync = function(pageStats) {
var recordPageCookiesAsync = function(pageStore) {
// Store the page stats objects so that it doesn't go away // Store the page stats objects so that it doesn't go away
// before we handle the job. // before we handle the job.
// rhill 2013-10-19: pageStats could be nil, for example, this can
// rhill 2013-10-19: pageStore could be nil, for example, this can
// happens if a file:// ... makes an xmlHttpRequest // happens if a file:// ... makes an xmlHttpRequest
if ( !pageStats ) {
return;
}
recordPageCookiesQueue.set(pageStats.pageUrl, pageStats);
if ( processPageRecordQueueTimer === null ) {
if ( !pageStore ) { return; }
recordPageCookiesQueue.set(pageStore.pageUrl, pageStore);
if ( processPageRecordQueueTimer !== null ) { return; }
processPageRecordQueueTimer = vAPI.setTimeout(processPageRecordQueue, 1000); processPageRecordQueueTimer = vAPI.setTimeout(processPageRecordQueue, 1000);
}
}; };
/******************************************************************************/ /******************************************************************************/
var cookieLogEntryBuilder = [
'',
'{',
'',
'-cookie:',
'',
'}'
];
var recordPageCookie = function(pageStore, cookieKey) {
if ( vAPI.isBehindTheSceneTabId(pageStore.tabId) ) { return; }
var cookieEntry = cookieDict.get(cookieKey);
var pageHostname = pageStore.pageHostname;
var block = µm.mustBlock(pageHostname, cookieEntry.hostname, 'cookie');
cookieLogEntryBuilder[0] = cookieURLFromCookieEntry(cookieEntry);
cookieLogEntryBuilder[2] = cookieEntry.session ? 'session' : 'persistent';
cookieLogEntryBuilder[4] = encodeURIComponent(cookieEntry.name);
var cookieURL = cookieLogEntryBuilder.join('');
// rhill 2013-11-20:
var recordPageCookie = (function() {
let queue = new Map();
let queueTimer;
let cookieLogEntryBuilder = [ '', '{', '', '-cookie:', '', '}' ];
let process = function() {
queueTimer = undefined;
for ( let qentry of queue ) {
let pageStore = qentry[0];
if ( pageStore.tabId === '' ) { continue; }
for ( let cookieKey of qentry[1] ) {
let cookieEntry = cookieDict.get(cookieKey);
let block = µm.mustBlock(
pageStore.pageHostname,
cookieEntry.hostname,
'cookie'
);
// https://github.com/gorhill/httpswitchboard/issues/60 // https://github.com/gorhill/httpswitchboard/issues/60
// Need to URL-encode cookie name // Need to URL-encode cookie name
cookieLogEntryBuilder[0] =
cookieURLFromCookieEntry(cookieEntry);
cookieLogEntryBuilder[2] =
cookieEntry.session ? 'session' : 'persistent';
cookieLogEntryBuilder[4] =
encodeURIComponent(cookieEntry.name);
let cookieURL = cookieLogEntryBuilder.join('');
pageStore.recordRequest('cookie', cookieURL, block); pageStore.recordRequest('cookie', cookieURL, block);
µm.logger.writeOne(pageStore.tabId, 'net', pageHostname, cookieURL, 'cookie', block);
cookieEntry.usedOn.add(pageHostname);
µm.logger.writeOne(
pageStore.tabId,
'net',
pageStore.pageHostname,
cookieURL,
'cookie',
block
);
cookieEntry.usedOn.add(pageStore.pageHostname);
if ( !block ) { continue; }
if ( µm.userSettings.deleteCookies ) {
removeCookieAsync(cookieKey);
}
µm.updateBadgeAsync(pageStore.tabId);
}
}
queue.clear();
};
// rhill 2013-11-21:
// https://github.com/gorhill/httpswitchboard/issues/65
// Leave alone cookies from behind-the-scene requests if
// behind-the-scene processing is disabled.
if ( !block ) {
return;
return function(pageStore, cookieKey) {
if ( vAPI.isBehindTheSceneTabId(pageStore.tabId) ) { return; }
let entry = queue.get(pageStore);
if ( entry === undefined ) {
queue.set(pageStore, (entry = new Set()));
} }
if ( !µm.userSettings.deleteCookies ) {
return;
if ( entry.has(cookieKey) ) { return; }
entry.add(cookieKey);
if ( queueTimer === undefined ) {
queueTimer = vAPI.setTimeout(process, 277);
} }
removeCookieAsync(cookieKey);
}; };
})();
/******************************************************************************/ /******************************************************************************/
@ -473,12 +487,48 @@ var canRemoveCookie = function(cookieKey, srcHostnames) {
/******************************************************************************/ /******************************************************************************/
// Listen to any change in cookieland, we will update page stats accordingly. // Listen to any change in cookieland, we will update page stats accordingly.
vAPI.cookies.onChanged = function(cookie) {
// rhill 2013-12-11: If cookie value didn't change, no need to record.
//
// https://github.com/gorhill/httpswitchboard/issues/79 // https://github.com/gorhill/httpswitchboard/issues/79
var cookieKey = cookieKeyFromCookie(cookie);
var cookieEntry = cookieDict.get(cookieKey);
// If cookie value didn't change, no need to record.
vAPI.cookies.onChanged = (function() {
let queue = new Map();
let queueTimer;
// Go through all pages and update if needed, as one cookie can be used
// by many web pages, so they need to be recorded for all these pages.
let process = function() {
queueTimer = undefined;
let now = Date.now();
let cookieKeys = [];
for ( let qentry of queue ) {
if ( qentry[1] > now ) { continue; }
if ( cookieDict.has(qentry[0]) === false ) { continue; }
cookieKeys.push(qentry[0]);
queue.delete(qentry[0]);
}
if ( cookieKeys.length !== 0 ) {
let pageStores = µm.pageStores;
for ( let tabId in pageStores ) {
if ( pageStores.hasOwnProperty(tabId) === false ) { continue; }
let pageStore = pageStores[tabId];
let allHostnamesString = pageStore.allHostnamesString;
for ( let cookieKey of cookieKeys ) {
if ( cookieMatchDomains(cookieKey, allHostnamesString) ) {
recordPageCookie(pageStore, cookieKey);
}
}
}
}
if ( queue.size !== 0 ) {
queueTimer = vAPI.setTimeout(process, 797);
}
};
return function(cookie) {
let cookieKey = cookieKeyFromCookie(cookie);
let cookieEntry = cookieDict.get(cookieKey);
if ( cookieEntry === undefined ) { if ( cookieEntry === undefined ) {
cookieEntry = addCookieToDict(cookie); cookieEntry = addCookieToDict(cookie);
} else { } else {
@ -486,22 +536,13 @@ vAPI.cookies.onChanged = function(cookie) {
if ( cookie.value === cookieEntry.value ) { return; } if ( cookie.value === cookieEntry.value ) { return; }
cookieEntry.value = cookie.value; cookieEntry.value = cookie.value;
} }
// Go through all pages and update if needed, as one cookie can be used
// by many web pages, so they need to be recorded for all these pages.
var pageStores = µm.pageStores;
var pageStore;
for ( var tabId in pageStores ) {
if ( pageStores.hasOwnProperty(tabId) === false ) {
continue;
}
pageStore = pageStores[tabId];
if ( !cookieMatchDomains(cookieKey, pageStore.allHostnamesString) ) {
continue;
}
recordPageCookie(pageStore, cookieKey);
if ( queue.has(cookieKey) ) { return; }
queue.set(cookieKey, Date.now() + 653);
if ( queueTimer === undefined ) {
queueTimer = vAPI.setTimeout(process, 727);
} }
}; };
})();
/******************************************************************************/ /******************************************************************************/

1
src/js/pagestats.js

@ -134,6 +134,7 @@ PageStore.prototype = {
}, },
dispose: function() { dispose: function() {
this.tabId = '';
this.rawUrl = ''; this.rawUrl = '';
this.pageUrl = ''; this.pageUrl = '';
this.pageHostname = ''; this.pageHostname = '';

Loading…
Cancel
Save