diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/15-firefox-proxy-settings.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/15-firefox-proxy-settings.js new file mode 100644 index 0000000..df44df1 --- /dev/null +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/15-firefox-proxy-settings.js @@ -0,0 +1,85 @@ +'use strict'; + +if (window.apis.platform.ifFirefox) { + + const prefix = 'firefox-only'; + + const ffxStorage = { + get(keys) { + return new Promise((resolve) => ( + chrome.storage.local.get( + keys, + window.utils.getOrDie(resolve), + ) + )); + }, + set(items) { + return new Promise((resolve) => ( + chrome.storage.local.set(items, resolve) + )); + }, + remove(keys) { + return new Promise((resolve) => ( + chrome.storage.local.remove(keys, resolve) + )); + }, + }; + + const originalSet = chrome.proxy.settings.set.bind( chrome.proxy.settings ); + chrome.proxy.settings.set = function(details, cb) { + const pac = window.utils.getProp(details, 'value.pacScript') || {}; + if (!(pac && pac.data)) { + return originalSet(details, cb); + } + + const blob = new Blob([pac.data], { type : 'application/x-ns-proxy-autoconfig' }); + const blobUrl = URL.createObjectURL(blob); + originalSet({ + value: { + proxyType: 'autoConfig', + autoConfigUrl: blobUrl, + }, + }, window.utils.chromified( async (err) => { + if (err) { + throw err; + } + await ffxStorage.set({ [`${prefix}-pacData`]: pac.data }); + cb(); + })); + }; + + const originalGet = chrome.proxy.settings.get.bind( chrome.proxy.settings ); + chrome.proxy.settings.get = function(details, cb) { + originalGet(details, window.utils.chromified((err, originalDetails) => { + if (err) { + throw err; + } + const autoConfigUrl = window.utils.getProp(originalDetails, 'value.autoConfigUrl'); + if (!autoConfigUrl) { + return cb(originalDetails); + } + window.apis.httpLib.get(autoConfigUrl, async (err, pacData) => { + if (err) { + pacData = await ffxStorage.get(`${prefix}-pacData`); + } + cb(Object.assign( + originalDetails, + { + value: { + mode: 'pac_script', + pacScript: { + data: pacData, + }, + }, + } + )); + }); + })); + }; + + const originalClear = chrome.proxy.settings.clear.bind( chrome.proxy.settings ); + chrome.proxy.settings.clear = async function(details, cb) { + await ffxStorage.remove(`${prefix}-pacData`); + originalClear(details, cb); + }; +} diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/35-pac-kitchen-api.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/35-pac-kitchen-api.js index 71ec0df..9c1bae5 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/35-pac-kitchen-api.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/35-pac-kitchen-api.js @@ -544,7 +544,10 @@ ${ if ( details && details.levelOfControl === 'controlled_by_this_extension' ) { - return chrome.proxy.settings.set(details, chromified(cb)); + const pac = window.utils.getProp(details, 'value.pacScript'); + if (pac && pac.data) { + return chrome.proxy.settings.set(details, chromified(cb)); + } } kitchenState(ifIncontinence, true); @@ -621,50 +624,21 @@ ${ const originalSet = chrome.proxy.settings.set.bind( chrome.proxy.settings ); chrome.proxy.settings.set = function(details, cb) { - - const pac = window.utils.getProp(details, 'value.pacScript') || {}; - const autoConfigUrl = window.utils.getProp(details, 'value.autoConfigUrl'); - const ifNothingToCook = !(pac && pac.data || autoConfigUrl); - if (ifNothingToCook) { + const pac = window.utils.getProp(details, 'value.pacScript'); + if (!(pac && pac.data)) { return originalSet(details, cb); } - const getPacData = (getPacCb) => - pac.data ? getPacCb(null, pac.data) : window.apis.httpLib.get(autoConfigUrl, getPacCb); + const pacMods = getCurrentConfigs(); + pac.data = pacKitchen.cook( pac.data, pacMods ); + originalSet({value: details.value}, window.utils.chromified((err) => { - getPacData((err, pacData) => { if (err) { - cb(err); - return; + throw err; } - const pacMods = getCurrentConfigs(); - const cookedData = pacKitchen.cook( pacData, pacMods ); - const setCb = (/* No args. */) => { + kitchenState(ifIncontinence, null); + cb && cb(); - kitchenState(ifIncontinence, null); - cb && cb(); - - }; - - if (window.apis.platform.ifFirefox) { - const autoConfigUrl = `data:application/x-ns-proxy-autoconfig,${escape(cookedData)}`; - return originalSet({ - value: { - proxyType: 'autoConfig', - autoConfigUrl, - }, - }, setCb); - } - - details.value.pacScript.data = cookedData; - return originalSet({ value: details.value }, setCb); - }); + })); }; - pacKitchen.checkIncontinence(); - chrome.proxy.settings.onChange.addListener( - timeouted( - pacKitchen.checkIncontinence.bind(pacKitchen) - ) - ); - } // Private namespace ends. diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/manifest.tmpl.json b/extensions/chromium/runet-censorship-bypass/src/extension-common/manifest.tmpl.json index 0f75361..fe76a68 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/manifest.tmpl.json +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/manifest.tmpl.json @@ -14,6 +14,7 @@ "proxy" , "alarms" , "storage" + , "unlimitedStorage" , "" , "tabs" , "contextMenus" @@ -30,6 +31,7 @@ , "11-error-handlers-api.js" , "12-errors-lib.js" , "13-http-lib.js" + , "15-firefox-proxy-settings.js" ${scripts_2x} , "35-pac-kitchen-api.js" , "37-sync-pac-script-with-pac-provider-api.js"