|
@ -173,11 +173,11 @@ var onBeforeChromeExtensionRequestHandler = function(details) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var µm = µMatrix; |
|
|
var µm = µMatrix; |
|
|
|
|
|
|
|
|
// Is the target page still blacklisted?
|
|
|
|
|
|
var pageURL = decodeURIComponent(matches[1]); |
|
|
var pageURL = decodeURIComponent(matches[1]); |
|
|
var hostname = decodeURIComponent(matches[2]); |
|
|
|
|
|
if ( µm.mustBlock(µm.scopeFromURL(pageURL), hostname, 'doc') ) { |
|
|
|
|
|
|
|
|
var pageHostname = decodeURIComponent(matches[2]); |
|
|
|
|
|
|
|
|
|
|
|
// Blacklisted as per matrix?
|
|
|
|
|
|
if ( µm.mustBlock(µm.scopeFromURL(pageURL), pageHostname, 'doc') ) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -208,15 +208,16 @@ var onBeforeRootFrameRequestHandler = function(details) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var uri = µm.URI.set(details.url); |
|
|
var uri = µm.URI.set(details.url); |
|
|
if ( uri.scheme !== 'http' && uri.scheme !== 'https' ) { |
|
|
|
|
|
|
|
|
if ( uri.scheme.indexOf('http') === -1 ) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var requestURL = uri.normalizedURI(); |
|
|
var requestURL = uri.normalizedURI(); |
|
|
var requestHostname = uri.hostname; |
|
|
var requestHostname = uri.hostname; |
|
|
var pageStats = µm.pageStatsFromTabId(tabId); |
|
|
|
|
|
var pageURL = µm.pageUrlFromPageStats(pageStats); |
|
|
|
|
|
var block = µm.mustBlock(pageStats.pageHostname, requestHostname, 'doc'); |
|
|
|
|
|
|
|
|
var pageStore = µm.pageStatsFromTabId(tabId); |
|
|
|
|
|
|
|
|
|
|
|
// Disallow request as per matrix?
|
|
|
|
|
|
var block = µm.mustBlock(pageStore.pageHostname, requestHostname, 'doc'); |
|
|
|
|
|
|
|
|
// console.debug('onBeforeRequestHandler()> block=%s "%s": %o', block, details.url, details);
|
|
|
// console.debug('onBeforeRequestHandler()> block=%s "%s": %o', block, details.url, details);
|
|
|
|
|
|
|
|
@ -225,7 +226,7 @@ var onBeforeRootFrameRequestHandler = function(details) { |
|
|
// rhill 2013-11-07: Senseless to do this for behind-the-scene requests.
|
|
|
// rhill 2013-11-07: Senseless to do this for behind-the-scene requests.
|
|
|
// rhill 2013-12-03: Do this here only for root frames.
|
|
|
// rhill 2013-12-03: Do this here only for root frames.
|
|
|
if ( tabId !== µm.behindTheSceneTabId ) { |
|
|
if ( tabId !== µm.behindTheSceneTabId ) { |
|
|
µm.cookieHunter.recordPageCookies(pageStats); |
|
|
|
|
|
|
|
|
µm.cookieHunter.recordPageCookies(pageStore); |
|
|
} |
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
@ -236,7 +237,7 @@ var onBeforeRootFrameRequestHandler = function(details) { |
|
|
// requests, in order to ensure any potential redirects is reported
|
|
|
// requests, in order to ensure any potential redirects is reported
|
|
|
// in proper chronological order.
|
|
|
// in proper chronological order.
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/112
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/112
|
|
|
pageStats.recordRequest('doc', requestURL, block); |
|
|
|
|
|
|
|
|
pageStore.recordRequest('doc', requestURL, block); |
|
|
|
|
|
|
|
|
// If it's a blacklisted frame, redirect to frame.html
|
|
|
// If it's a blacklisted frame, redirect to frame.html
|
|
|
// rhill 2013-11-05: The root frame contains a link to noop.css, this
|
|
|
// rhill 2013-11-05: The root frame contains a link to noop.css, this
|
|
@ -261,33 +262,31 @@ var onBeforeRootFrameRequestHandler = function(details) { |
|
|
|
|
|
|
|
|
var processRequest = function(µm, details) { |
|
|
var processRequest = function(µm, details) { |
|
|
var µmuri = µm.URI; |
|
|
var µmuri = µm.URI; |
|
|
var requestType = requestTypeNormalizer[details.type]; |
|
|
|
|
|
var requestURL = µmuri.set(details.url).normalizedURI(); |
|
|
var requestURL = µmuri.set(details.url).normalizedURI(); |
|
|
var requestHostname = µmuri.hostname; |
|
|
var requestHostname = µmuri.hostname; |
|
|
var requestPath = µmuri.path; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// rhill 2013-12-15:
|
|
|
|
|
|
// Try to transpose generic `other` category into something more
|
|
|
|
|
|
// meaningful.
|
|
|
|
|
|
var requestType = requestTypeNormalizer[details.type]; |
|
|
|
|
|
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 HTTP Switchboard, i.e. `opera://startpage`,
|
|
|
|
|
|
|
|
|
// which cannot be handled by µMatrix, i.e. `opera://startpage`,
|
|
|
// as this would lead to complications with no obvious solution, like how
|
|
|
// as this would lead to complications with no obvious solution, like how
|
|
|
// to scope on unknown scheme? Etc.
|
|
|
// to scope on unknown scheme? Etc.
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/191
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/191
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
|
|
|
var pageStats = µm.pageStatsFromTabId(details.tabId); |
|
|
|
|
|
if ( !pageStats ) { |
|
|
|
|
|
pageStats = µm.pageStatsFromTabId(µm.behindTheSceneTabId); |
|
|
|
|
|
} |
|
|
|
|
|
var pageURL = µm.pageUrlFromPageStats(pageStats); |
|
|
|
|
|
|
|
|
|
|
|
// rhill 2013-12-15:
|
|
|
|
|
|
// Try to transpose generic `other` category into something more
|
|
|
|
|
|
// meaningful.
|
|
|
|
|
|
if ( requestType === 'other' ) { |
|
|
|
|
|
requestType = µm.transposeType(requestType, requestPath); |
|
|
|
|
|
|
|
|
var pageStore = µm.pageStatsFromTabId(details.tabId); |
|
|
|
|
|
if ( !pageStore ) { |
|
|
|
|
|
pageStore = µm.pageStatsFromTabId(µm.behindTheSceneTabId); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Block request?
|
|
|
|
|
|
var block = µm.mustBlock(pageStats.pageHostname, requestHostname, requestType); |
|
|
|
|
|
|
|
|
// Disallow request as per temporary matrix?
|
|
|
|
|
|
var block = µm.mustBlock(pageStore.pageHostname, requestHostname, requestType); |
|
|
|
|
|
|
|
|
// Record request.
|
|
|
// Record request.
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/342
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/342
|
|
@ -295,7 +294,7 @@ var processRequest = function(µm, 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.
|
|
|
pageStats.recordRequest(requestType, details.µmRequestURL || requestURL, block); |
|
|
|
|
|
|
|
|
pageStore.recordRequest(requestType, details.µmRequestURL || requestURL, block); |
|
|
|
|
|
|
|
|
// whitelisted?
|
|
|
// whitelisted?
|
|
|
if ( !block ) { |
|
|
if ( !block ) { |
|
@ -455,28 +454,29 @@ var onBeforeSendHeadersHandler = function(details) { |
|
|
// https://github.com/gorhill/httpswitchboard/issues/191
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/191
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
|
|
|
var tabId = details.tabId; |
|
|
var tabId = details.tabId; |
|
|
var pageStats = µm.pageStatsFromTabId(tabId); |
|
|
|
|
|
if ( !pageStats ) { |
|
|
|
|
|
|
|
|
var pageStore = µm.pageStatsFromTabId(tabId); |
|
|
|
|
|
if ( !pageStore ) { |
|
|
tabId = µm.behindTheSceneTabId; |
|
|
tabId = µm.behindTheSceneTabId; |
|
|
pageStats = µm.pageStatsFromTabId(tabId); |
|
|
|
|
|
|
|
|
pageStore = µm.pageStatsFromTabId(tabId); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var pageURL = µm.pageUrlFromPageStats(pageStats); |
|
|
|
|
|
var reqHostname = µm.hostnameFromURL(requestURL); |
|
|
var reqHostname = µm.hostnameFromURL(requestURL); |
|
|
|
|
|
|
|
|
var changed = false; |
|
|
var changed = false; |
|
|
|
|
|
|
|
|
if ( µm.mustBlock(pageStats.pageHostname, reqHostname, 'cookie') ) { |
|
|
|
|
|
|
|
|
if ( µm.mustBlock(pageStore.pageHostname, reqHostname, 'cookie') ) { |
|
|
changed = foilCookieHeaders(µm, details) || changed; |
|
|
changed = foilCookieHeaders(µm, details) || changed; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// TODO: use cookie cell to determine whether the referrer info must be
|
|
|
// TODO: use cookie cell to determine whether the referrer info must be
|
|
|
// foiled.
|
|
|
// foiled.
|
|
|
if ( µm.userSettings.processReferer && µm.mustBlock(pageStats.pageHostname, reqHostname, '*') ) { |
|
|
|
|
|
|
|
|
if ( µm.userSettings.processReferer && µm.mustBlock(pageStore.pageHostname, reqHostname, '*') ) { |
|
|
changed = foilRefererHeaders(µm, reqHostname, details) || changed; |
|
|
changed = foilRefererHeaders(µm, reqHostname, details) || changed; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ( µm.userSettings.spoofUserAgent ) { |
|
|
|
|
|
|
|
|
// TODO: move the master ua-spoofing switch into the matrix.
|
|
|
|
|
|
var mustSpoof = µm.userSettings.spoofUserAgent && |
|
|
|
|
|
µm.tMatrix.evaluateSwitchZ('ua-spoof-off', pageStore.pageHostname) === false; |
|
|
|
|
|
if ( mustSpoof ) { |
|
|
changed = foilUserAgent(µm, details) || changed; |
|
|
changed = foilUserAgent(µm, details) || changed; |
|
|
// https://github.com/gorhill/httpswitchboard/issues/252
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/252
|
|
|
// To avoid potential mismatch between the user agent from HTTP headers
|
|
|
// To avoid potential mismatch between the user agent from HTTP headers
|
|
@ -617,7 +617,7 @@ var onHeadersReceived = function(details) { |
|
|
// console.debug('onHeadersReceived()> "%s": %o', details.url, details);
|
|
|
// console.debug('onHeadersReceived()> "%s": %o', details.url, details);
|
|
|
|
|
|
|
|
|
// Ignore schemes other than 'http...'
|
|
|
// Ignore schemes other than 'http...'
|
|
|
if ( details.url.indexOf('http') !== 0 ) { |
|
|
|
|
|
|
|
|
if ( details.url.slice(0, 4) !== 'http' ) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -710,25 +710,32 @@ var onMainDocHeadersReceived = function(details) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Evaluate
|
|
|
|
|
|
if ( µm.mustAllow(pageStats.pageHostname, requestHostname, 'script') ) { |
|
|
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/181
|
|
|
|
|
|
pageStats.pageScriptBlocked = false; |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
// Maybe modify inbound headers
|
|
|
|
|
|
var csp = ''; |
|
|
|
|
|
|
|
|
|
|
|
// Enforce strict HTTPS?
|
|
|
|
|
|
if ( requestScheme === 'https' && µm.tMatrix.evaluateSwitchZ('https-strict', pageStats.pageHostname) ) { |
|
|
|
|
|
csp += "default-src https: 'unsafe-inline' 'unsafe-eval'"; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/181
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/181
|
|
|
pageStats.pageScriptBlocked = true; |
|
|
|
|
|
|
|
|
pageStats.pageScriptBlocked = µm.mustBlock(pageStats.pageHostname, requestHostname, 'script'); |
|
|
|
|
|
if ( pageStats.pageScriptBlocked ) { |
|
|
|
|
|
// If javascript not allowed, say so through a `Content-Security-Policy` directive.
|
|
|
|
|
|
// console.debug('onMainDocHeadersReceived()> PAGE CSP "%s": %o', details.url, details);
|
|
|
|
|
|
csp += " script-src 'none'"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// If javascript not allowed, say so through a `Content-Security-Policy`
|
|
|
|
|
|
// directive.
|
|
|
|
|
|
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/181
|
|
|
|
|
|
if ( csp !== '' ) { |
|
|
|
|
|
// If javascript not allowed, say so through a `Content-Security-Policy` directive.
|
|
|
// console.debug('onMainDocHeadersReceived()> PAGE CSP "%s": %o', details.url, details);
|
|
|
// console.debug('onMainDocHeadersReceived()> PAGE CSP "%s": %o', details.url, details);
|
|
|
headers.push({ |
|
|
headers.push({ |
|
|
'name': 'Content-Security-Policy', |
|
|
'name': 'Content-Security-Policy', |
|
|
'value': "script-src 'none'" |
|
|
|
|
|
|
|
|
'value': csp |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
return { responseHeaders: headers }; |
|
|
return { responseHeaders: headers }; |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/******************************************************************************/ |
|
|
/******************************************************************************/ |
|
|