diff --git a/platform/chromium/vapi-background.js b/platform/chromium/vapi-background.js index 9d573da..1736999 100644 --- a/platform/chromium/vapi-background.js +++ b/platform/chromium/vapi-background.js @@ -55,9 +55,7 @@ var noopFunc = function(){}; // https://github.com/gorhill/uMatrix/issues/234 // https://developer.chrome.com/extensions/privacy#property-network -chrome.privacy.network.networkPredictionEnabled.set({ - value: false -}); +chrome.privacy.network.networkPredictionEnabled.set({ value: false }); /******************************************************************************/ @@ -125,9 +123,7 @@ vAPI.tabs.registerListeners = function() { var onCreatedNavigationTarget = function(details) { //console.debug('onCreatedNavigationTarget: tab id %d = "%s"', details.tabId, details.url); - if ( reGoodForWebRequestAPI.test(details.url) ) { - return; - } + if ( reGoodForWebRequestAPI.test(details.url) ) { return; } details.tabId = details.tabId.toString(); onNavigationClient(details); }; @@ -563,78 +559,7 @@ vAPI.net = {}; /******************************************************************************/ vAPI.net.registerListeners = function() { - var µm = µMatrix, - reNetworkURL = /^(?:https?|wss?):\/\//, - 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 - + var µm = µMatrix; // Normalizing request types // >>>>>>>> @@ -647,30 +572,17 @@ vAPI.net.registerListeners = function() { var normalizeRequestDetails = function(details) { details.tabId = details.tabId.toString(); - var type = details.type; - - if ( type === 'imageset' ) { - details.type = 'image'; - return; - } - // The rest of the function code is to normalize request type - if ( type !== 'other' ) { - return; - } - - if ( details.requestHeaders instanceof HTTPRequestHeaders ) { - if ( details.requestHeaders.getHeader('ping-to') !== '' ) { - details.type = 'ping'; - return; - } - } + if ( details.type !== 'other' ) { return; } // Try to map known "extension" part of URL to request type. var path = µm.URI.pathFromURI(details.url), pos = path.indexOf('.', path.length - 6); - if ( pos !== -1 && (type = extToTypeMap.get(path.slice(pos + 1))) ) { - details.type = type; + if ( pos !== -1 ) { + var type = extToTypeMap.get(path.slice(pos + 1)); + if ( type !== undefined ) { + details.type = type; + } } }; // <<<<<<<< @@ -681,17 +593,9 @@ vAPI.net.registerListeners = function() { var onBeforeRequestClient = this.onBeforeRequest.callback; chrome.webRequest.onBeforeRequest.addListener( function(details) { - if ( reNetworkURL.test(details.url) ) { - normalizeRequestDetails(details); - return onBeforeRequestClient(details); - } + normalizeRequestDetails(details); + return onBeforeRequestClient(details); }, - //function(details) { - // quickProfiler.start('onBeforeRequest'); - // var r = onBeforeRequest(details); - // quickProfiler.stop(); - // return r; - //}, { 'urls': this.onBeforeRequest.urls || [ '' ], 'types': this.onBeforeRequest.types || undefined @@ -701,16 +605,8 @@ vAPI.net.registerListeners = function() { var onBeforeSendHeadersClient = this.onBeforeSendHeaders.callback; var onBeforeSendHeaders = function(details) { - details.requestHeaders = httpRequestHeadersFactory(details.requestHeaders); normalizeRequestDetails(details); - var result = onBeforeSendHeadersClient(details); - if ( typeof result === 'object' ) { - return result; - } - var modifiedHeaders = details.requestHeaders.dispose(); - if ( modifiedHeaders !== null ) { - return { requestHeaders: modifiedHeaders }; - } + return onBeforeSendHeadersClient(details); }; chrome.webRequest.onBeforeSendHeaders.addListener( onBeforeSendHeaders, diff --git a/src/js/logger-ui.js b/src/js/logger-ui.js index 4e40dd3..0ce7df5 100644 --- a/src/js/logger-ui.js +++ b/src/js/logger-ui.js @@ -49,6 +49,11 @@ var prettyRequestTypes = { 'xmlhttprequest': 'xhr' }; +var dontEmphasizeSet = new Set([ + 'COOKIE', + 'REFERER' +]); + /******************************************************************************/ // Adjust top padding of content table, to match that of toolbar height. @@ -245,7 +250,9 @@ var renderLogEntry = function(entry) { tr.cells[fvdc].textContent = ''; } tr.cells[fvdc+1].textContent = (prettyRequestTypes[entry.d2] || entry.d2); - if ( entry.d2 === 'cookie' ) { + if ( dontEmphasizeSet.has(entry.d2) ) { + tr.cells[fvdc+2].textContent = entry.d1; + } else if ( entry.d2 === 'cookie' ) { tr.cells[fvdc+2].appendChild(emphasizeCookie(entry.d1)); } else { tr.cells[fvdc+2].appendChild(emphasizeHostname(entry.d1)); diff --git a/src/js/traffic.js b/src/js/traffic.js index c25b4c1..d8a08d5 100644 --- a/src/js/traffic.js +++ b/src/js/traffic.js @@ -19,8 +19,6 @@ Home: https://github.com/gorhill/uMatrix */ -/* jshint boss: true */ - 'use strict'; /******************************************************************************/ @@ -75,6 +73,13 @@ var onBeforeRootFrameRequestHandler = function(details) { // Intercept and filter web requests according to white and black lists. var onBeforeRequestHandler = function(details) { + var µm = µMatrix, + µmuri = µm.URI, + requestURL = details.url, + requestScheme = µmuri.schemeFromURI(requestURL); + + if ( µmuri.isNetworkScheme(requestScheme) === false ) { return; } + var requestType = requestTypeNormalizer[details.type] || 'other'; // https://github.com/gorhill/httpswitchboard/issues/303 @@ -84,17 +89,6 @@ var onBeforeRequestHandler = function(details) { return onBeforeRootFrameRequestHandler(details); } - var µm = µMatrix, - µmuri = µm.URI, - requestURL = details.url, - requestScheme = µmuri.schemeFromURI(requestURL); - - // Ignore non-network schemes - if ( µmuri.isNetworkScheme(requestScheme) === false ) { - µm.logger.writeOne('', 'info', 'request not processed: ' + requestURL); - return; - } - // 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 µMatrix, i.e. `opera://startpage`, @@ -148,12 +142,13 @@ var onBeforeRequestHandler = function(details) { // Sanitize outgoing headers as per user settings. var onBeforeSendHeadersHandler = function(details) { - var µm = µMatrix; + var µm = µMatrix, + µmuri = µm.URI, + requestURL = details.url, + requestScheme = µmuri.schemeFromURI(requestURL); // Ignore non-network schemes - if ( µm.URI.isNetworkScheme(details.url) === false ) { - return; - } + if ( µmuri.isNetworkScheme(requestScheme) === false ) { return; } // Re-classify orphan HTTP requests as behind-the-scene requests. There is // not much else which can be done, because there are URLs @@ -162,8 +157,11 @@ var onBeforeSendHeadersHandler = function(details) { // 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 tabId = pageStore.tabId; + var tabId = details.tabId, + pageStore = µm.mustPageStoreFromTabId(tabId), + requestType = requestTypeNormalizer[details.type] || 'other', + requestHeaders = details.requestHeaders, + headerIndex, headerValue; // https://github.com/gorhill/httpswitchboard/issues/342 // Is this hyperlink auditing? @@ -186,13 +184,12 @@ var onBeforeSendHeadersHandler = function(details) { // With hyperlink-auditing, removing header(s) is pointless, the whole // request must be cancelled. - var requestURL = details.url; - var requestType = requestTypeNormalizer[details.type] || 'other'; - if ( requestType === 'ping' ) { - var linkAuditor = details.requestHeaders.getHeader('ping-to'); - if ( linkAuditor !== '' ) { + headerIndex = headerIndexFromName('ping-to', requestHeaders); + if ( headerIndex !== -1 ) { + headerValue = requestHeaders[headerIndex].value; + if ( headerValue !== '' ) { var block = µm.userSettings.processHyperlinkAuditing; - pageStore.recordRequest('other', requestURL + '{Ping-To:' + linkAuditor + '}', block); + pageStore.recordRequest('other', requestURL + '{Ping-To:' + headerValue + '}', block); µm.logger.writeOne(tabId, 'net', '', requestURL, 'ping', block); if ( block ) { µm.hyperlinkAuditingFoiledCounter += 1; @@ -203,42 +200,30 @@ var onBeforeSendHeadersHandler = function(details) { // If we reach this point, request is not blocked, so what is left to do // is to sanitize headers. - var requestHostname = µm.URI.hostnameFromURI(requestURL); - if ( µm.mustBlock(pageStore.pageHostname, requestHostname, 'cookie') ) { - if ( details.requestHeaders.setHeader('cookie', '') ) { - µm.cookieHeaderFoiledCounter++; - } - } + var rootHostname = pageStore.pageHostname, + requestHostname = µmuri.hostnameFromURI(requestURL), + modified = false; + + // Process `Cookie` header. - if ( µm.tMatrix.evaluateSwitchZ('referrer-spoof', pageStore.pageHostname) ) { - foilRefererHeaders(µm, requestHostname, details); + headerIndex = headerIndexFromName('cookie', requestHeaders); + if ( + headerIndex !== -1 && + µm.mustBlock(rootHostname, requestHostname, 'cookie') + ) { + headerValue = requestHeaders[headerIndex].value; + requestHeaders.splice(headerIndex, 1); + modified = true; + µm.cookieHeaderFoiledCounter++; + if ( requestType === 'doc' ) { + µm.logger.writeOne(tabId, 'net', '', headerValue, 'COOKIE', true); + } } -}; -/******************************************************************************/ + // Process `Referer` header. -var foilRefererHeaders = function(µm, toHostname, details) { - var foiled = false; - var µmuri = µm.URI; - var scheme = ''; - var toDomain = ''; - - var referer = details.requestHeaders.getHeader('referer'); - if ( referer !== '' ) { - toDomain = toDomain || µmuri.domainFromHostname(toHostname); - if ( toDomain !== µmuri.domainFromURI(referer) ) { - scheme = scheme || µmuri.schemeFromURI(details.url); - //console.debug('foilRefererHeaders()> foiled referer for "%s"', details.url); - //console.debug('\treferrer "%s"', header.value); - // https://github.com/gorhill/httpswitchboard/issues/222#issuecomment-44828402 - details.requestHeaders.setHeader( - 'referer', - scheme + '://' + toHostname + '/' - ); - foiled = true; - } - } + // https://github.com/gorhill/httpswitchboard/issues/222#issuecomment-44828402 // https://github.com/gorhill/uMatrix/issues/320 // http://tools.ietf.org/html/rfc6454#section-7.3 @@ -253,23 +238,29 @@ var foilRefererHeaders = function(µm, toHostname, details) { // https://github.com/gorhill/uMatrix/issues/358 // Do not spoof `Origin` header for the time being. This will be revisited. - //var origin = details.requestHeaders.getHeader('origin'); - //if ( origin !== '' && origin !== 'null' ) { - // toDomain = toDomain || µmuri.domainFromHostname(toHostname); - // if ( toDomain !== µmuri.domainFromURI(origin) ) { - // scheme = scheme || µmuri.schemeFromURI(details.url); - // //console.debug('foilRefererHeaders()> foiled origin for "%s"', details.url); - // //console.debug('\torigin "%s"', header.value); - // details.requestHeaders.setHeader( - // 'origin', - // scheme + '://' + toHostname - // ); - // foiled = true; - // } - //} - - if ( foiled ) { - µm.refererHeaderFoiledCounter++; + headerIndex = headerIndexFromName('referer', requestHeaders); + if ( headerIndex !== -1 ) { + headerValue = requestHeaders[headerIndex].value; + if ( + headerValue !== '' && + µm.tMatrix.evaluateSwitchZ('referrer-spoof', rootHostname) + ) { + var toDomain = µmuri.domainFromHostname(requestHostname); + if ( toDomain !== '' && toDomain !== µmuri.domainFromURI(headerValue) ) { + var newValue = requestScheme + '://' + requestHostname + '/'; + requestHeaders[headerIndex].value = newValue; + modified = true; + µm.refererHeaderFoiledCounter++; + if ( requestType === 'doc' ) { + µm.logger.writeOne(tabId, 'net', '', headerValue, 'REFERER', true); + µm.logger.writeOne(tabId, 'net', '', newValue, 'REFERER', false); + } + } + } + } + + if ( modified ) { + return { requestHeaders: requestHeaders }; } };