summaryrefslogtreecommitdiff
path: root/src/bg
diff options
context:
space:
mode:
Diffstat (limited to 'src/bg')
-rw-r--r--src/bg/ChildPolicies.js3
-rw-r--r--src/bg/ContentScriptOnce.js52
-rw-r--r--src/bg/RequestUtil.js169
-rw-r--r--src/bg/Settings.js2
-rw-r--r--src/bg/deferWebTraffic.js10
-rw-r--r--src/bg/main.js2
6 files changed, 63 insertions, 175 deletions
diff --git a/src/bg/ChildPolicies.js b/src/bg/ChildPolicies.js
index 0a77b8b..5b1b209 100644
--- a/src/bg/ChildPolicies.js
+++ b/src/bg/ChildPolicies.js
@@ -58,8 +58,9 @@
var ChildPolicies = {
async storeTabInfo(tabId, info) {
try {
+ let preamble = info ? `${marker} + ${JSON.stringify(JSON.stringify([info]))} + ${marker} + "," + ` : "";
await browser.tabs.executeScript(tabId, {
- code: `window.name = ${marker} + ${JSON.stringify(JSON.stringify([info]))} + ${marker} + "," + window.name;`,
+ code: `window.name = ${preamble}window.name.split(${marker} + ",").pop();`,
allFrames: false,
matchAboutBlank: true,
runAt: "document_start",
diff --git a/src/bg/ContentScriptOnce.js b/src/bg/ContentScriptOnce.js
new file mode 100644
index 0000000..5be602e
--- /dev/null
+++ b/src/bg/ContentScriptOnce.js
@@ -0,0 +1,52 @@
+var ContentScriptOnce = (() => {
+ "use strict";
+
+ let requestMap = new Map();
+
+ {
+ let cleanup = r => {
+ let {requestId} = r;
+ let scripts = requestMap.get(requestId);
+ if (scripts) {
+ window.setTimeout(() => {
+ requestMap.delete(requestId);
+ for (let s of scripts) s.unregister();
+ }, 0);
+ }
+ }
+
+ let filter = {
+ urls: ["<all_urls>"],
+ types: ["main_frame", "sub_frame", "object"]
+ };
+ let wr = browser.webRequest;
+ for (let event of ["onCompleted", "onErrorOccurred"]) {
+ wr[event].addListener(cleanup, filter);
+ }
+ }
+
+ return {
+ async execute(request, options) {
+ let {requestId, url} = request;
+ let scripts = requestMap.get(requestId);
+ if (!scripts) requestMap.set(requestId, scripts = new Set());
+ try {
+ let urlObj = new URL(url);
+ if (urlObj.port) {
+ urlObj.port = "";
+ url = urlObj.toString();
+ }
+ } catch (e) {}
+ let defOpts = {
+ runAt: "document_start",
+ matchAboutBlank: true,
+ matches: [url],
+ allFrames: true,
+ };
+
+ scripts.add(await browser.contentScripts.register(
+ Object.assign(defOpts, options)
+ ));
+ }
+ }
+})();
diff --git a/src/bg/RequestUtil.js b/src/bg/RequestUtil.js
deleted file mode 100644
index d6d3300..0000000
--- a/src/bg/RequestUtil.js
+++ /dev/null
@@ -1,169 +0,0 @@
-'use strict';
-{
- let xmlFeedOrImage = /^(?:(?:application|text)\/(?:(?:r(?:ss|df)|atom)\+)xml(;|$))|image\//i;
- let rawXml = /^(?:application|text)\/xml;/i;
- let brokenXMLOnLoad;
- (async () => brokenXMLOnLoad = parseInt((await browser.runtime.getBrowserInfo()).version) < 61)()
-
- let pendingScripts = new Map();
- let NOP = () => {};
-
- let reloadingTabs = new Map();
- let tabKey = (tabId, url) => `${tabId}:${url}`;
-
- let cleanup = r => {
- pendingScripts.delete(r.requestId);
- let key = tabKey(r.tabId, r.url);
- if (reloadingTabs.get(key) === false) {
- reloadingTabs.delete(key);
- }
- };
-
- let executeAll = async request => {
- let {url, tabId, frameId, requestId, type} = request;
- let scripts = pendingScripts.get(requestId);
- if (!scripts) return -1;
- pendingScripts.delete(requestId);
- let count = 0;
- let run = async details => {
- details = Object.assign({
- runAt: "document_start",
- matchAboutBlank: true,
- frameId
- }, details);
- try {
- let res;
- for (let attempts = 10; attempts-- > 0;) {
- try {
- res = await browser.tabs.executeScript(tabId, details);
- break;
- } catch(e) {
- if (!/No matching message handler/.test(e.message)) throw e;
- debug("Couldn't inject script into %s: too early? Retrying up to %s times...", url, attempts);
- }
- }
- count++;
- debug("Execute on start OK, result=%o", res, url, details);
- } catch (e) {
- error(e, "Execute on start failed", url, details);
- }
- };
- await Promise.all([...scripts.values()].map(run));
- return count;
- };
-
- {
- let filter = {
- urls: ["<all_urls>"],
- types: ["main_frame", "sub_frame"]
- };
- let wr = browser.webRequest;
- for (let event of ["onCompleted", "onErrorOccurred"]) {
- wr[event].addListener(cleanup, filter);
- }
-
- wr.onResponseStarted.addListener(r => {
- let scripts = pendingScripts.get(r.requestId);
- if (scripts) scripts.runAndFlush();
- }, filter);
- }
-
- var RequestUtil = {
-
- getResponseMetaData(request) {
- return request.response || (request.response = new ResponseMetaData(request));
- },
-
- executeOnStart(request, details) {
- let {requestId, url, tabId, frameId, statusCode, type} = request;
-
- if (statusCode >= 300 && statusCode < 400 || type === "object") return;
- if (frameId === 0) {
- let key = tabKey(tabId, url);
- debug("Checking whether %s is a reloading tab...", key);
- if (reloadingTabs.get(key)) {
- reloadingTabs.set(key, false); // doom it for removal in cleanup
- return;
- }
- }
-
- let response = this.getResponseMetaData(request);
- let {contentType, contentDisposition} = response;
- if (contentDisposition ||
- xmlFeedOrImage.test(contentType) && !/\/svg\b/i.test(contentType)) {
- debug("Skipping execute on start of %s %o.", url, response);
- return;
- }
-
- debug("Injecting script on start in %s (%o).", url, response);
-
- let scripts = pendingScripts.get(requestId);
- let scriptKey = JSON.stringify(details);
- if (!scripts) {
- pendingScripts.set(requestId, scripts = new Map());
- scripts.set(scriptKey, details);
- } else {
- scripts.set(scriptKey, details);
- return;
- }
-
- if (/^(?:application|text)\//.test(contentType)
- && !/[^;]+\b(html|xml)\b/i.test(contentType)) {
- debug("Not HTML: defer script to onResponseStarted for %s (%o)", url, response);
- return;
- }
-
- let mustCheckFeed = brokenXMLOnLoad && frameId === 0 && rawXml.test(contentType);
- debug("mustCheckFeed = %s, brokenXMLOnLoad = %s", mustCheckFeed, brokenXMLOnLoad);
- let filter = browser.webRequest.filterResponseData(requestId);
- let buffer = [];
- let responseCompleted = false;
- let mustReload = false;
- scripts.runAndFlush = async () => {
- scripts.runAndFlush = NOP;
- if (responseCompleted && buffer && !buffer.length) {
- filter.disconnect();
- }
- let scriptsRan = await executeAll(request);
- if (mustCheckFeed && !scriptsRan) {
- mustReload = true;
- debug(`Marking as "must reload"`, tabId, url);
- reloadingTabs.set(tabKey(tabId, url), true);
- }
- if (buffer) {
- debug("Flushing %s buffer chunks on %s", buffer.length, url);
- for (let chunk of buffer) {
- filter.write(chunk);
- }
- buffer = null;
- }
- filter.disconnect();
- if (responseCompleted) {
- filter.onstop(null);
- }
- };
-
- filter.ondata = event => {
- scripts.runAndFlush();
- if (buffer) {
- debug("buffering", url);
- buffer.push(event.data);
- return;
- }
-
- debug("ondata", url);
- filter.write(event.data);
- filter.disconnect();
- };
-
- filter.onstop = async event => {
- responseCompleted = true;
- await scripts.runAndFlush();
- if (mustReload && !buffer) {
- mustReload = false;
- browser.tabs.update(tabId, {url});
- }
- }
- }
- }
-}
diff --git a/src/bg/Settings.js b/src/bg/Settings.js
index 09f0edd..56c88f4 100644
--- a/src/bg/Settings.js
+++ b/src/bg/Settings.js
@@ -90,7 +90,7 @@ var Settings = {
if (typeof unrestrictedTab === "boolean") {
ns.unrestrictedTabs[unrestrictedTab ? "add" : "delete"](tabId);
- ChildPolicies.storeTabInfo(tabId, {unrestricted: unrestrictedTab});
+ ChildPolicies.storeTabInfo(tabId, unrestrictedTab && {unrestricted: true});
}
if (reloadAffected) {
browser.tabs.reload(tabId);
diff --git a/src/bg/deferWebTraffic.js b/src/bg/deferWebTraffic.js
index fced870..15d177b 100644
--- a/src/bg/deferWebTraffic.js
+++ b/src/bg/deferWebTraffic.js
@@ -34,16 +34,20 @@ function deferWebTraffic(promiseToWaitFor, next) {
if (frameId !== 0) {
documentUrl = request.frameAncestors.pop().url;
}
- reloadTab(tabId);
+ if (tabId !== -1) {
+ reloadTab(tabId);
+ } else {
+ debug("No tab to reload for %s %s from %s", type, url, documentUrl);
+ }
}
}
- debug("Deferring ", url, type);
+ debug("Deferring %s %s from %s", type, url, documentUrl);
try {
await promiseToWaitFor;
} catch (e) {
error(e);
}
- debug("Green light to ", url, type);
+ debug("Green light to %s %s from %s", type, url, documentUrl);
}
function spyTabs(request) {
diff --git a/src/bg/main.js b/src/bg/main.js
index 2eb2896..75ea868 100644
--- a/src/bg/main.js
+++ b/src/bg/main.js
@@ -36,7 +36,7 @@
await include("/bg/defaults.js");
await ns.defaults;
- await include(["/bg/RequestGuard.js", "/bg/RequestUtil.js"]);
+ await include("/bg/RequestGuard.js");
await RequestGuard.start();
await XSS.start(); // we must start it anyway to initialize sub-objects
if (!ns.sync.xss) {