mirror of
https://github.com/gorhill/uMatrix.git
synced 2024-06-28 02:50:39 +12:00
sanitizing outgoing headers (drafty)
This commit is contained in:
parent
5106c4bc44
commit
595de33e83
|
@ -614,7 +614,79 @@ vAPI.net = {};
|
||||||
vAPI.net.registerListeners = function() {
|
vAPI.net.registerListeners = function() {
|
||||||
var µm = µMatrix;
|
var µm = µMatrix;
|
||||||
var µmuri = µm.URI;
|
var µmuri = µm.URI;
|
||||||
|
var httpRequestHeadersJunkyard = [];
|
||||||
|
|
||||||
|
// Abstraction layer to deal with request headers
|
||||||
|
// >>>>>>>>
|
||||||
|
var httpRequestHeadersFactory = function(headers) {
|
||||||
|
var entry = httpRequestHeadersJunkyard.pop();
|
||||||
|
if ( entry ) {
|
||||||
|
return entry.init(headers);
|
||||||
|
}
|
||||||
|
return new HTTPRequestHeaders(headers);
|
||||||
|
};
|
||||||
|
|
||||||
|
var HTTPRequestHeaders = function(headers) {
|
||||||
|
this.init(headers);
|
||||||
|
};
|
||||||
|
|
||||||
|
HTTPRequestHeaders.prototype.init = function(headers) {
|
||||||
|
this.modified = false;
|
||||||
|
this.headers = headers;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
HTTPRequestHeaders.prototype.dispose = function() {
|
||||||
|
var r = this.modified ? this.headers : null;
|
||||||
|
this.headers = null;
|
||||||
|
httpRequestHeadersJunkyard.push(this);
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
|
HTTPRequestHeaders.prototype.getHeader = function(target) {
|
||||||
|
var headers = this.headers;
|
||||||
|
var header, name;
|
||||||
|
var i = headers.length;
|
||||||
|
while ( i-- ) {
|
||||||
|
header = headers[i];
|
||||||
|
name = header.name.toLowerCase();
|
||||||
|
if ( name === target ) {
|
||||||
|
return header.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
HTTPRequestHeaders.prototype.setHeader = function(target, value, create) {
|
||||||
|
var headers = this.headers;
|
||||||
|
var header, name;
|
||||||
|
var i = headers.length;
|
||||||
|
while ( i-- ) {
|
||||||
|
header = headers[i];
|
||||||
|
name = header.name.toLowerCase();
|
||||||
|
if ( name === target ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( i < 0 && !create ) { // Header not found, don't add it
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( i < 0 ) { // Header not found, add it
|
||||||
|
headers.push({ name: target, value: value });
|
||||||
|
} else if ( value === '' ) { // Header found, remove it
|
||||||
|
headers.splice(i, 1);
|
||||||
|
} else { // Header found, modify it
|
||||||
|
header.value = value;
|
||||||
|
}
|
||||||
|
this.modified = true;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
// <<<<<<<<
|
||||||
|
// End of: Abstraction layer to deal with request headers
|
||||||
|
|
||||||
|
|
||||||
|
// Normalizing request types
|
||||||
|
// >>>>>>>>
|
||||||
var normalizeRequestDetails = function(details) {
|
var normalizeRequestDetails = function(details) {
|
||||||
µmuri.set(details.url);
|
µmuri.set(details.url);
|
||||||
|
|
||||||
|
@ -651,7 +723,12 @@ vAPI.net.registerListeners = function() {
|
||||||
// https://code.google.com/p/chromium/issues/detail?id=410382
|
// https://code.google.com/p/chromium/issues/detail?id=410382
|
||||||
details.type = 'object';
|
details.type = 'object';
|
||||||
};
|
};
|
||||||
|
// <<<<<<<<
|
||||||
|
// End of: Normalizing request types
|
||||||
|
|
||||||
|
|
||||||
|
// Network event handlers
|
||||||
|
// >>>>>>>>
|
||||||
var onBeforeRequestClient = this.onBeforeRequest.callback;
|
var onBeforeRequestClient = this.onBeforeRequest.callback;
|
||||||
var onBeforeRequest = function(details) {
|
var onBeforeRequest = function(details) {
|
||||||
normalizeRequestDetails(details);
|
normalizeRequestDetails(details);
|
||||||
|
@ -675,7 +752,15 @@ vAPI.net.registerListeners = function() {
|
||||||
var onBeforeSendHeadersClient = this.onBeforeSendHeaders.callback;
|
var onBeforeSendHeadersClient = this.onBeforeSendHeaders.callback;
|
||||||
var onBeforeSendHeaders = function(details) {
|
var onBeforeSendHeaders = function(details) {
|
||||||
normalizeRequestDetails(details);
|
normalizeRequestDetails(details);
|
||||||
return onBeforeSendHeadersClient(details);
|
details.requestHeaders = httpRequestHeadersFactory(details.requestHeaders);
|
||||||
|
var result = onBeforeSendHeadersClient(details);
|
||||||
|
if ( typeof result === 'object' ) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
var modifiedHeaders = details.requestHeaders.dispose();
|
||||||
|
if ( modifiedHeaders !== null ) {
|
||||||
|
return { requestHeaders: modifiedHeaders };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
chrome.webRequest.onBeforeSendHeaders.addListener(
|
chrome.webRequest.onBeforeSendHeaders.addListener(
|
||||||
onBeforeSendHeaders,
|
onBeforeSendHeaders,
|
||||||
|
@ -706,6 +791,8 @@ vAPI.net.registerListeners = function() {
|
||||||
'urls': this.onErrorOccurred.urls || ['<all_urls>']
|
'urls': this.onErrorOccurred.urls || ['<all_urls>']
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
// <<<<<<<<
|
||||||
|
// End of: Network event handlers
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -948,6 +948,52 @@ CallbackWrapper.prototype.proxy = function(response) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var httpRequestHeadersFactory = function(channel) {
|
||||||
|
var entry = httpRequestHeadersFactory.junkyard.pop();
|
||||||
|
if ( entry ) {
|
||||||
|
return entry.init(channel);
|
||||||
|
}
|
||||||
|
return new HTTPRequestHeaders(channel);
|
||||||
|
};
|
||||||
|
|
||||||
|
httpRequestHeadersFactory.junkyard = [];
|
||||||
|
|
||||||
|
var HTTPRequestHeaders = function(channel) {
|
||||||
|
this.init(channel);
|
||||||
|
};
|
||||||
|
|
||||||
|
HTTPRequestHeaders.prototype.init = function(channel) {
|
||||||
|
this.channel = channel;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
HTTPRequestHeaders.prototype.dispose = function() {
|
||||||
|
this.channel = null;
|
||||||
|
httpRequestHeadersFactory.junkyard.push(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
HTTPRequestHeaders.prototype.getHeader = function(name) {
|
||||||
|
try {
|
||||||
|
return this.channel.getRequestHeader(name);
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
HTTPRequestHeaders.prototype.setHeader = function(name, newValue, create) {
|
||||||
|
var oldValue = this.getHeader(name);
|
||||||
|
if ( newValue === oldValue ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( oldValue === '' && create !== true ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.channel.setRequestHeader(name, newValue, false);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var httpObserver = {
|
var httpObserver = {
|
||||||
classDescription: 'net-channel-event-sinks for ' + location.host,
|
classDescription: 'net-channel-event-sinks for ' + location.host,
|
||||||
classID: Components.ID('{dc8d6319-5f6e-4438-999e-53722db99e84}'),
|
classID: Components.ID('{dc8d6319-5f6e-4438-999e-53722db99e84}'),
|
||||||
|
@ -967,9 +1013,11 @@ var httpObserver = {
|
||||||
5: 'object',
|
5: 'object',
|
||||||
6: 'main_frame',
|
6: 'main_frame',
|
||||||
7: 'sub_frame',
|
7: 'sub_frame',
|
||||||
|
10: 'ping',
|
||||||
11: 'xmlhttprequest',
|
11: 'xmlhttprequest',
|
||||||
12: 'object',
|
12: 'object',
|
||||||
14: 'font',
|
14: 'font',
|
||||||
|
16: 'websocket',
|
||||||
21: 'image'
|
21: 'image'
|
||||||
},
|
},
|
||||||
lastRequest: [{}, {}],
|
lastRequest: [{}, {}],
|
||||||
|
@ -1061,41 +1109,47 @@ var httpObserver = {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleRequest: function(channel, URI, details) {
|
handleRequest: function(channel, URI, details) {
|
||||||
var onBeforeRequest = vAPI.net.onBeforeRequest;
|
|
||||||
var type = this.typeMap[details.type] || 'other';
|
var type = this.typeMap[details.type] || 'other';
|
||||||
|
var result;
|
||||||
if (
|
var callbackDetails = {
|
||||||
onBeforeRequest.types.size !== 0 &&
|
|
||||||
onBeforeRequest.types.has(type) === false
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = onBeforeRequest.callback({
|
|
||||||
frameId: details.frameId,
|
frameId: details.frameId,
|
||||||
hostname: URI.asciiHost,
|
hostname: URI.asciiHost,
|
||||||
parentFrameId: details.parentFrameId,
|
parentFrameId: details.parentFrameId,
|
||||||
tabId: details.tabId,
|
tabId: details.tabId,
|
||||||
type: type,
|
type: type,
|
||||||
url: URI.asciiSpec
|
url: URI.asciiSpec
|
||||||
});
|
};
|
||||||
|
|
||||||
if ( !result || typeof result !== 'object' ) {
|
var onBeforeRequest = vAPI.net.onBeforeRequest;
|
||||||
return false;
|
if ( onBeforeRequest.types.size === 0 || onBeforeRequest.types.has(type) ) {
|
||||||
|
result = onBeforeRequest.callback(callbackDetails);
|
||||||
|
|
||||||
|
if ( typeof result === 'object' && result.cancel === true ) {
|
||||||
|
channel.cancel(this.ABORT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if ( result.redirectUrl ) {
|
||||||
|
channel.redirectionLimit = 1;
|
||||||
|
channel.redirectTo(
|
||||||
|
Services.io.newURI(result.redirectUrl, null, null)
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( result.cancel === true ) {
|
var onBeforeSendHeaders = vAPI.net.onBeforeSendHeaders;
|
||||||
channel.cancel(this.ABORT);
|
if ( onBeforeSendHeaders.types.size === 0 || onBeforeSendHeaders.types.has(type) ) {
|
||||||
return true;
|
callbackDetails.requestHeaders = httpRequestHeadersFactory(channel);
|
||||||
}
|
result = onBeforeSendHeaders.callback(callbackDetails);
|
||||||
|
callbackDetails.requestHeaders.dispose();
|
||||||
|
|
||||||
/*if ( result.redirectUrl ) {
|
if ( typeof result === 'object' && result.cancel === true ) {
|
||||||
channel.redirectionLimit = 1;
|
channel.cancel(this.ABORT);
|
||||||
channel.redirectTo(
|
return true;
|
||||||
Services.io.newURI(result.redirectUrl, null, null)
|
}
|
||||||
);
|
|
||||||
return true;
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
@ -1263,10 +1317,8 @@ vAPI.net = {};
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.net.registerListeners = function() {
|
vAPI.net.registerListeners = function() {
|
||||||
// Since it's not used
|
|
||||||
this.onBeforeSendHeaders = null;
|
|
||||||
|
|
||||||
this.onBeforeRequest.types = new Set(this.onBeforeRequest.types);
|
this.onBeforeRequest.types = new Set(this.onBeforeRequest.types);
|
||||||
|
this.onBeforeSendHeaders.types = new Set(this.onBeforeSendHeaders.types);
|
||||||
|
|
||||||
var shouldLoadListenerMessageName = location.host + ':shouldLoad';
|
var shouldLoadListenerMessageName = location.host + ':shouldLoad';
|
||||||
var shouldLoadListener = function(e) {
|
var shouldLoadListener = function(e) {
|
||||||
|
|
|
@ -272,7 +272,7 @@ var onBeforeRequestHandler = function(details) {
|
||||||
|
|
||||||
// console.debug('onBeforeRequestHandler()> "%s": %o', details.url, details);
|
// console.debug('onBeforeRequestHandler()> "%s": %o', details.url, details);
|
||||||
|
|
||||||
var requestType = requestTypeNormalizer[details.type];
|
var requestType = requestTypeNormalizer[details.type] || 'other';
|
||||||
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/303
|
// https://github.com/gorhill/httpswitchboard/issues/303
|
||||||
// Wherever the main doc comes from, create a receiver page URL: synthetize
|
// Wherever the main doc comes from, create a receiver page URL: synthetize
|
||||||
|
@ -284,7 +284,7 @@ var onBeforeRequestHandler = function(details) {
|
||||||
var requestURL = details.url;
|
var requestURL = details.url;
|
||||||
|
|
||||||
// Is it µMatrix's noop css file?
|
// Is it µMatrix's noop css file?
|
||||||
if ( requestType === 'css' && requestURL.slice(0, µm.noopCSSURL.length) === µm.noopCSSURL ) {
|
if ( requestType === 'css' && requestURL.lastIndexOf(µm.noopCSSURL, 0) === 0 ) {
|
||||||
return onBeforeChromeExtensionRequestHandler(details);
|
return onBeforeChromeExtensionRequestHandler(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,19 +295,12 @@ var onBeforeRequestHandler = function(details) {
|
||||||
|
|
||||||
// Do not block myself from updating assets
|
// Do not block myself from updating assets
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/202
|
// https://github.com/gorhill/httpswitchboard/issues/202
|
||||||
if ( requestType === 'xhr' && requestURL.slice(0, µm.projectServerRoot.length) === µm.projectServerRoot ) {
|
if ( requestType === 'xhr' && requestURL.lastIndexOf(µm.projectServerRoot, 0) === 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestHostname = µmuri.hostname;
|
var requestHostname = µmuri.hostname;
|
||||||
|
|
||||||
// rhill 2013-12-15:
|
|
||||||
// Try to transpose generic `other` category into something more
|
|
||||||
// meaningful.
|
|
||||||
if ( requestType === 'other' ) {
|
|
||||||
requestType = µm.transposeType(requestType, µmuri.path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-classify orphan HTTP requests as behind-the-scene requests. There is
|
// Re-classify orphan HTTP requests as behind-the-scene requests. There is
|
||||||
// not much else which can be done, because there are URLs
|
// not much else which can be done, because there are URLs
|
||||||
// which cannot be handled by µMatrix, i.e. `opera://startpage`,
|
// which cannot be handled by µMatrix, i.e. `opera://startpage`,
|
||||||
|
@ -361,11 +354,7 @@ var onBeforeRequestHandler = function(details) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// This is where tabless requests are processed, as here there may be a chance
|
// Sanitize outgoing headers as per user settings.
|
||||||
// we can bind a request to a specific tab, as headers may contain useful
|
|
||||||
// information to accomplish this.
|
|
||||||
//
|
|
||||||
// Also we sanitize outgoing headers as per user settings.
|
|
||||||
|
|
||||||
var onBeforeSendHeadersHandler = function(details) {
|
var onBeforeSendHeadersHandler = function(details) {
|
||||||
|
|
||||||
|
@ -392,11 +381,27 @@ var onBeforeSendHeadersHandler = function(details) {
|
||||||
// If yes, create a synthetic URL for reporting hyperlink auditing
|
// If yes, create a synthetic URL for reporting hyperlink auditing
|
||||||
// in request log. This way the user is better informed of what went
|
// in request log. This way the user is better informed of what went
|
||||||
// on.
|
// on.
|
||||||
|
|
||||||
|
// http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing
|
||||||
|
//
|
||||||
|
// Target URL = the href of the link
|
||||||
|
// Doc URL = URL of the document containing the target URL
|
||||||
|
// Ping URLs = servers which will be told that user clicked target URL
|
||||||
|
//
|
||||||
|
// `Content-Type` = `text/ping` (always present)
|
||||||
|
// `Ping-To` = target URL (always present)
|
||||||
|
// `Ping-From` = doc URL
|
||||||
|
// `Referer` = doc URL
|
||||||
|
// request URL = URL which will receive the information
|
||||||
|
//
|
||||||
|
// With hyperlink-auditing, removing header(s) is pointless, the whole
|
||||||
|
// request must be cancelled.
|
||||||
|
|
||||||
var requestURL = details.url;
|
var requestURL = details.url;
|
||||||
var requestType = requestTypeNormalizer[details.type];
|
var requestType = requestTypeNormalizer[details.type] || 'other';
|
||||||
if ( requestType === 'other' ) {
|
if ( requestType === 'other' ) {
|
||||||
var linkAuditor = hyperlinkAuditorFromHeaders(details.requestHeaders);
|
var linkAuditor = details.requestHeaders.getHeader('ping-to');
|
||||||
if ( linkAuditor ) {
|
if ( linkAuditor !== '' ) {
|
||||||
var block = µm.userSettings.processHyperlinkAuditing;
|
var block = µm.userSettings.processHyperlinkAuditing;
|
||||||
pageStore.recordRequest('other', requestURL + '{Ping-To:' + linkAuditor + '}', block);
|
pageStore.recordRequest('other', requestURL + '{Ping-To:' + linkAuditor + '}', block);
|
||||||
µm.updateBadgeAsync(tabId);
|
µm.updateBadgeAsync(tabId);
|
||||||
|
@ -411,123 +416,41 @@ var onBeforeSendHeadersHandler = function(details) {
|
||||||
// is to sanitize headers.
|
// is to sanitize headers.
|
||||||
|
|
||||||
var reqHostname = µm.hostnameFromURL(requestURL);
|
var reqHostname = µm.hostnameFromURL(requestURL);
|
||||||
var changed = false;
|
|
||||||
|
|
||||||
if ( µm.mustBlock(pageStore.pageHostname, reqHostname, 'cookie') ) {
|
if ( µm.mustBlock(pageStore.pageHostname, reqHostname, 'cookie') ) {
|
||||||
changed = foilCookieHeaders(µm, details) || changed;
|
if ( details.requestHeaders.setHeader('cookie', '') ) {
|
||||||
|
µm.cookieHeaderFoiledCounter++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( µm.tMatrix.evaluateSwitchZ('referrer-spoof', pageStore.pageHostname) ) {
|
if ( µm.tMatrix.evaluateSwitchZ('referrer-spoof', pageStore.pageHostname) ) {
|
||||||
changed = foilRefererHeaders(µm, reqHostname, details) || changed;
|
foilRefererHeaders(µm, reqHostname, details);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( µm.tMatrix.evaluateSwitchZ('ua-spoof', pageStore.pageHostname) ) {
|
if ( µm.tMatrix.evaluateSwitchZ('ua-spoof', pageStore.pageHostname) ) {
|
||||||
changed = foilUserAgent(µm, details) || changed;
|
details.requestHeaders.setHeader('user-agent', µm.userAgentReplaceStr);
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/252
|
|
||||||
// To avoid potential mismatch between the user agent from HTTP headers
|
|
||||||
// and the user agent from subrequests and the window.navigator object,
|
|
||||||
// I could always store here the effective user agent, but I am really
|
|
||||||
// not convinced it is worth the added overhead given the low
|
|
||||||
// probability and the benign consequence if it ever happen. Can always
|
|
||||||
// be revised if ever I become aware a mismatch is a terrible thing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( changed ) {
|
|
||||||
// console.debug('onBeforeSendHeadersHandler()> CHANGED "%s": %o', requestURL, details);
|
|
||||||
return { requestHeaders: details.requestHeaders };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing
|
|
||||||
//
|
|
||||||
// Target URL = the href of the link
|
|
||||||
// Doc URL = URL of the document containing the target URL
|
|
||||||
// Ping URLs = servers which will be told that user clicked target URL
|
|
||||||
//
|
|
||||||
// `Content-Type` = `text/ping` (always present)
|
|
||||||
// `Ping-To` = target URL (always present)
|
|
||||||
// `Ping-From` = doc URL
|
|
||||||
// `Referer` = doc URL
|
|
||||||
// request URL = URL which will receive the information
|
|
||||||
//
|
|
||||||
// With hyperlink-auditing, removing header(s) is pointless, the whole
|
|
||||||
// request must be cancelled.
|
|
||||||
|
|
||||||
var hyperlinkAuditorFromHeaders = function(headers) {
|
|
||||||
var i = headers.length;
|
|
||||||
while ( i-- ) {
|
|
||||||
if ( headers[i].name.toLowerCase() === 'ping-to' ) {
|
|
||||||
return headers[i].value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var foilCookieHeaders = function(µm, details) {
|
|
||||||
var changed = false;
|
|
||||||
var headers = details.requestHeaders;
|
|
||||||
var header;
|
|
||||||
var i = headers.length;
|
|
||||||
while ( i-- ) {
|
|
||||||
header = headers[i];
|
|
||||||
if ( header.name.toLowerCase() !== 'cookie' ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// console.debug('foilCookieHeaders()> foiled browser attempt to send cookie(s) to "%s"', details.url);
|
|
||||||
headers.splice(i, 1);
|
|
||||||
µm.cookieHeaderFoiledCounter++;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var foilRefererHeaders = function(µm, toHostname, details) {
|
var foilRefererHeaders = function(µm, toHostname, details) {
|
||||||
var headers = details.requestHeaders;
|
var referer = details.requestHeaders.getHeader('referer');
|
||||||
var i = headers.length, header;
|
if ( referer === '' ) {
|
||||||
while ( i-- ) {
|
return;
|
||||||
header = headers[i];
|
|
||||||
if ( header.name.toLowerCase() === 'referer' ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( i === -1 ) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
var µmuri = µm.URI;
|
var µmuri = µm.URI;
|
||||||
var fromDomain = µmuri.domainFromURI(header.value);
|
if ( µmuri.domainFromHostname(toHostname) === µmuri.domainFromURI(referer) ) {
|
||||||
var toDomain = µmuri.domainFromHostname(toHostname);
|
return;
|
||||||
if ( toDomain === fromDomain ) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
//console.debug('foilRefererHeaders()> foiled referer for "%s"', details.url);
|
//console.debug('foilRefererHeaders()> foiled referer for "%s"', details.url);
|
||||||
//console.debug('\treferrer "%s"', header.value);
|
//console.debug('\treferrer "%s"', header.value);
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/222#issuecomment-44828402
|
// https://github.com/gorhill/httpswitchboard/issues/222#issuecomment-44828402
|
||||||
header.value = µmuri.schemeFromURI(details.url) + '://' + toHostname + '/';
|
details.requestHeaders.setHeader(
|
||||||
//console.debug('\treplaced with "%s"', header.value);
|
'referer',
|
||||||
|
µmuri.schemeFromURI(details.url) + '://' + toHostname + '/'
|
||||||
|
);
|
||||||
µm.refererHeaderFoiledCounter++;
|
µm.refererHeaderFoiledCounter++;
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var foilUserAgent = function(µm, details) {
|
|
||||||
var headers = details.requestHeaders;
|
|
||||||
var header;
|
|
||||||
var i = 0;
|
|
||||||
while ( header = headers[i] ) {
|
|
||||||
if ( header.name.toLowerCase() === 'user-agent' ) {
|
|
||||||
header.value = µm.userAgentReplaceStr;
|
|
||||||
return true; // Assuming only one `user-agent` entry
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -549,7 +472,7 @@ var onHeadersReceived = function(details) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestType = requestTypeNormalizer[details.type];
|
var requestType = requestTypeNormalizer[details.type] || 'other';
|
||||||
if ( requestType === 'frame' ) {
|
if ( requestType === 'frame' ) {
|
||||||
return onSubDocHeadersReceived(details);
|
return onSubDocHeadersReceived(details);
|
||||||
}
|
}
|
||||||
|
@ -731,7 +654,7 @@ var onSubDocHeadersReceived = function(details) {
|
||||||
|
|
||||||
var onErrorOccurredHandler = function(details) {
|
var onErrorOccurredHandler = function(details) {
|
||||||
// console.debug('onErrorOccurred()> "%s": %o', details.url, details);
|
// console.debug('onErrorOccurred()> "%s": %o', details.url, details);
|
||||||
var requestType = requestTypeNormalizer[details.type];
|
var requestType = requestTypeNormalizer[details.type] || 'other';
|
||||||
|
|
||||||
// Ignore all that is not a main document
|
// Ignore all that is not a main document
|
||||||
if ( requestType !== 'doc'|| details.parentFrameId >= 0 ) {
|
if ( requestType !== 'doc'|| details.parentFrameId >= 0 ) {
|
||||||
|
@ -788,7 +711,8 @@ var requestTypeNormalizer = {
|
||||||
'image' : 'image',
|
'image' : 'image',
|
||||||
'object' : 'plugin',
|
'object' : 'plugin',
|
||||||
'xmlhttprequest': 'xhr',
|
'xmlhttprequest': 'xhr',
|
||||||
'other' : 'other'
|
'other' : 'other',
|
||||||
|
'font' : 'css'
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -808,10 +732,6 @@ vAPI.net.onBeforeSendHeaders = {
|
||||||
"http://*/*",
|
"http://*/*",
|
||||||
"https://*/*"
|
"https://*/*"
|
||||||
],
|
],
|
||||||
types: [
|
|
||||||
"main_frame",
|
|
||||||
"sub_frame"
|
|
||||||
],
|
|
||||||
extra: [ 'blocking', 'requestHeaders' ],
|
extra: [ 'blocking', 'requestHeaders' ],
|
||||||
callback: onBeforeSendHeadersHandler
|
callback: onBeforeSendHeadersHandler
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
echo "*** µMatrix(Chromium): Creating package"
|
echo "*** µMatrix(Chromium): Creating package"
|
||||||
echo "*** µMatrix(Chromium): Copying files"
|
echo "*** µMatrix(Chromium): Copying files"
|
||||||
|
|
||||||
DES=./dist/uMatrix.chromium
|
DES=./dist/build/uMatrix.chromium
|
||||||
rm -rf $DES
|
rm -rf $DES
|
||||||
mkdir -p $DES
|
mkdir -p $DES
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue