Fix reload loops on broken file: HTML documents (thanks bernie for report).
This commit is contained in:
parent
a83cf372eb
commit
affe284193
|
@ -68,37 +68,68 @@
|
||||||
|
|
||||||
let originalState = document.readyState;
|
let originalState = document.readyState;
|
||||||
let syncLoad = UA.isMozilla && /^(?:ftp|file):/.test(url);
|
let syncLoad = UA.isMozilla && /^(?:ftp|file):/.test(url);
|
||||||
let localPolicyKey;
|
let localPolicy;
|
||||||
if (syncLoad && originalState !== "complete") {
|
if (syncLoad && originalState !== "complete") {
|
||||||
localPolicyKey = `ns.policy.${url}|${browser.runtime.getURL("")}`;
|
localPolicy = {
|
||||||
|
key: `[ns.policy.${url}|${browser.runtime.getURL("")}|${Math.floor(Date.now() / 10000)}]`,
|
||||||
let [name, localPolicy] = window.name.split(localPolicyKey);
|
read(resetName = false) {
|
||||||
window.name = name;
|
let [policy, name] =
|
||||||
if (localPolicy) {
|
window.name.includes(this.key) ? window.name.split(this.key) : [null, window.name];
|
||||||
debug("Falling back to localPolicy", localPolicy);
|
this.policy = policy ? (policy = JSON.parse(policy)) : null;
|
||||||
try {
|
if (resetName) window.name = name;
|
||||||
this.setup(JSON.parse(localPolicy));
|
return {policy, name};
|
||||||
} catch(e) {
|
},
|
||||||
error(e, "Falling back: could not setup local policy", localPolicy);
|
write(policy = this.policy, name = window.name) {
|
||||||
localPolicyKey = null;
|
if (name.includes(this.key)) {
|
||||||
this.setup(null);
|
({name} = this.read());
|
||||||
|
}
|
||||||
|
let policyString = JSON.stringify(policy);
|
||||||
|
window.name = [policyString, name].join(this.key);
|
||||||
|
// verify
|
||||||
|
if (JSON.stringify(this.read(false).policy) !== policyString) {
|
||||||
|
throw new Error("Can't write localPolicy", policy, window.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
addEventListener("beforescriptexecute", e => {
|
|
||||||
console.log("Blocking early script", e.target);
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let {policy} = localPolicy.read(true);
|
||||||
|
if (policy) {
|
||||||
|
debug("Applying localPolicy", policy);
|
||||||
|
this.setup(policy);
|
||||||
|
let onBeforeUnload = e => {
|
||||||
|
// this fixes infinite reload loops if Firefox decides to reload the page immediately
|
||||||
|
// because it needs to be reparsed (e.g. broken / late charset declaration)
|
||||||
|
// see https://forums.informaction.com/viewtopic.php?p=102850
|
||||||
|
localPolicy.write(policy);
|
||||||
|
};
|
||||||
|
addEventListener("beforeunload", onBeforeUnload, false);
|
||||||
|
addEventListener("DOMContentLoaded", e => removeEventListener(onBeforeUnload, false), true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
error(e, "Falling back: could not setup local policy", localPolicy.policy);
|
||||||
|
this.setup(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
debug("Stopping synchronous load to fetch and apply localPolicy...");
|
||||||
|
addEventListener("beforescriptexecute", e => {
|
||||||
|
console.log("Blocking early script", e.target);
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
let setup = policy => {
|
let setup = policy => {
|
||||||
debug("Fetched %o, readyState %s", policy, document.readyState); // DEV_ONLY
|
debug("Fetched %o, readyState %s", policy, document.readyState); // DEV_ONLY
|
||||||
this.setup(policy);
|
this.setup(policy);
|
||||||
if (syncLoad && originalState !== "complete") {
|
if (localPolicy) {
|
||||||
window.name = [window.name, JSON.stringify(this.policy)].join(localPolicyKey);
|
try {
|
||||||
location.reload(false);
|
localPolicy.write(policy);
|
||||||
|
location.reload(false);
|
||||||
|
} catch (e) {
|
||||||
|
error(e, "Cannot write local policy, bailing out...")
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue