From ba96a4ff4a20b4b597b4a90de02c42bad1fe2b6e Mon Sep 17 00:00:00 2001 From: gorhill Date: Sun, 29 Nov 2015 11:04:42 -0500 Subject: [PATCH] redirect engine: selfie-able + update-able --- src/js/redirect-engine.js | 115 +++++++++++++++++++++++++++++++------- src/js/start.js | 3 +- src/js/storage.js | 12 ++-- 3 files changed, 103 insertions(+), 27 deletions(-) diff --git a/src/js/redirect-engine.js b/src/js/redirect-engine.js index a2225c746..99329d3f0 100644 --- a/src/js/redirect-engine.js +++ b/src/js/redirect-engine.js @@ -40,28 +40,17 @@ var toBroaderHostname = function(hostname) { /******************************************************************************/ /******************************************************************************/ -var RedirectEntry = function(mime, lines) { - this.mime = mime; - this.encoded = mime.indexOf(';') !== -1; - var data = lines.join(this.encoded ? '' : '\n'); - // check for placeholders. - this.ph = this.encoded === false && this.rePlaceHolders.test(data); - if ( this.ph ) { - this.data = data; - } else { - this.data = - 'data:' + - mime + - (this.encoded ? '' : ';base64') + - ',' + - (this.encoded ? data : btoa(data)); - } +var RedirectEntry = function() { + this.mime = ''; + this.encoded = false; + this.ph = false; + this.data = ''; }; /******************************************************************************/ -RedirectEntry.prototype.rePlaceHolders = /\{\{.+?\}\}/; -RedirectEntry.prototype.reRequestURL = /\{\{requestURL\}\}/g; +RedirectEntry.rePlaceHolders = /\{\{.+?\}\}/; +RedirectEntry.reRequestURL = /\{\{requestURL\}\}/g; /******************************************************************************/ @@ -71,7 +60,44 @@ RedirectEntry.prototype.toURL = function(requestURL) { } return 'data:' + this.mime + ';base64,' + - btoa(this.data.replace(this.reRequestURL, requestURL)); + btoa(this.data.replace(RedirectEntry.reRequestURL, requestURL)); +}; + +/******************************************************************************/ + +RedirectEntry.fromFields = function(mime, lines) { + var r = new RedirectEntry(); + + r.mime = mime; + r.encoded = mime.indexOf(';') !== -1; + var data = lines.join(r.encoded ? '' : '\n'); + // check for placeholders. + r.ph = r.encoded === false && RedirectEntry.rePlaceHolders.test(data); + if ( r.ph ) { + r.data = data; + } else { + r.data = + 'data:' + + mime + + (r.encoded ? '' : ';base64') + + ',' + + (r.encoded ? data : btoa(data)); + } + + return r; +}; + +/******************************************************************************/ + +RedirectEntry.fromSelfie = function(selfie) { + var r = new RedirectEntry(); + + r.mime = selfie.mime; + r.encoded = selfie.encoded; + r.ph = selfie.ph; + r.data = selfie.data; + + return r; }; /******************************************************************************/ @@ -275,6 +301,53 @@ RedirectEngine.prototype.supportedTypes = (function() { /******************************************************************************/ +RedirectEngine.prototype.toSelfie = function() { + return { + resources: this.resources, + rules: this.rules + }; +}; + +/******************************************************************************/ + +RedirectEngine.prototype.fromSelfie = function(selfie) { + // Resources. + var resources = selfie.resources; + for ( var token in resources ) { + if ( resources.hasOwnProperty(token) === false ) { + continue; + } + this.resources[token] = RedirectEntry.fromSelfie(resources[token]); + } + + // Rules. + var typeEntry, desEntry, srcEntry; + var rules = selfie.rules; + for ( var type in rules ) { + if ( rules.hasOwnProperty(type) === false ) { + continue; + } + typeEntry = rules[type]; + for ( var des in typeEntry ) { + if ( typeEntry.hasOwnProperty(des) === false ) { + continue; + } + desEntry = typeEntry[des]; + for ( var src in desEntry ) { + if ( desEntry.hasOwnProperty(des) === false ) { + continue; + } + srcEntry = desEntry[src]; + this.addRule(src, des, type, srcEntry.c, srcEntry.r); + } + } + } + + return true; +}; + +/******************************************************************************/ + // TODO: combine same key-redirect pairs into a single regex. RedirectEngine.prototype.resourcesFromString = function(text) { @@ -316,14 +389,14 @@ RedirectEngine.prototype.resourcesFromString = function(text) { } // No more data, add the resource. - this.resources[fields[0]] = new RedirectEntry(fields[1], fields.slice(2)); + this.resources[fields[0]] = RedirectEntry.fromFields(fields[1], fields.slice(2)); fields = undefined; } // Process pending resource data. if ( fields !== undefined ) { - this.resources[fields[0]] = new RedirectEntry(fields[1], fields.slice(2)); + this.resources[fields[0]] = RedirectEntry.fromFields(fields[1], fields.slice(2)); } }; diff --git a/src/js/start.js b/src/js/start.js index 23c192cf4..5b92c2761 100644 --- a/src/js/start.js +++ b/src/js/start.js @@ -128,6 +128,7 @@ var onSelfieReady = function(selfie) { //console.log('start.js/onSelfieReady: selfie looks good'); µb.remoteBlacklists = selfie.filterLists; µb.staticNetFilteringEngine.fromSelfie(selfie.staticNetFilteringEngine); + µb.redirectEngine.fromSelfie(selfie.redirectEngine); µb.cosmeticFilteringEngine.fromSelfie(selfie.cosmeticFilteringEngine); return true; }; @@ -211,7 +212,6 @@ var onFirstFetchReady = function(fetched) { fromFetch(µb.restoreBackupSettings, fetched); onNetWhitelistReady(fetched.netWhitelist); onVersionReady(fetched.version); - µb.loadRedirectResources(); // If we have a selfie, skip loading PSL, filters if ( onSelfieReady(fetched.selfie) ) { @@ -219,6 +219,7 @@ var onFirstFetchReady = function(fetched) { return; } + µb.loadRedirectResources(); µb.loadPublicSuffixList(onPSLReady); }; diff --git a/src/js/storage.js b/src/js/storage.js index 58089dd7d..0dcabd8a5 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -185,6 +185,7 @@ entry.entryUsedCount += deltaEntryUsedCount; vAPI.storage.set({ 'remoteBlacklists': µb.remoteBlacklists }); µb.staticNetFilteringEngine.freeze(); + µb.redirectEngine.freeze(); µb.cosmeticFilteringEngine.freeze(); }; @@ -708,6 +709,7 @@ publicSuffixList: publicSuffixList.toSelfie(), filterLists: this.remoteBlacklists, staticNetFilteringEngine: this.staticNetFilteringEngine.toSelfie(), + redirectEngine: this.redirectEngine.toSelfie(), cosmeticFilteringEngine: this.cosmeticFilteringEngine.toSelfie() }; vAPI.storage.set({ selfie: selfie }); @@ -836,7 +838,7 @@ assets[location] = true; } assets[µb.pslPath] = true; - assets['assets/ublock/mirror-candidates.txt'] = true; + assets['assets/ublock/redirect-resources.txt'] = true; callback(assets); }; @@ -885,10 +887,6 @@ } }; - if ( details.hasOwnProperty('assets/ublock/mirror-candidates.txt') ) { - /* TODO */ - } - if ( details.hasOwnProperty(this.pslPath) ) { //console.debug('storage.js > µBlock.updateCompleteHandler: reloading PSL'); this.loadPublicSuffixList(onPSLReady); @@ -896,6 +894,10 @@ } else { onPSLReady(); } + + if ( details.hasOwnProperty('assets/ublock/redirect-resources.txt') ) { + µb.loadRedirectResources(); + } }; /******************************************************************************/