Cloudflare-Blocker/background.js

65 lines
1.7 KiB
JavaScript

// These are Cloudflare's headers, taken from here:
// https://developers.cloudflare.com/fundamentals/reference/http-headers/
const CLOUDFLARE_HEADERS = new Set([
'cf-connecting-ip',
'cf-connecting-ipv6',
'cf-ew-via',
'cf-pseudo-ipv4',
'cf-ray',
'cf-ipcountry',
'cf-visitor',
'cf-worker'
]);
let blockingEnabled = true;
let stateLoaded = false;
const stateReady = browser.storage.local.get({ blockingEnabled: true })
.then(result => { blockingEnabled = result.blockingEnabled; })
.catch(() => { /* keep the default */ })
.then(() => { stateLoaded = true; });
browser.storage.onChanged.addListener((changes, area) => {
if (area === 'local' && changes.blockingEnabled) {
blockingEnabled = changes.blockingEnabled.newValue;
}
});
function blockedPageUrl(header, url) {
const query = new URLSearchParams({
name: header.name,
value: header.value || '',
url: url
}).toString();
return browser.runtime.getURL('blocked.html') + '?' + query;
}
function checkResponse(details) {
if (!blockingEnabled) {
return {};
}
const cfHeader = (details.responseHeaders || []).find(header =>
CLOUDFLARE_HEADERS.has(header.name.toLowerCase())
);
if (!cfHeader) {
return {};
}
if (details.type === 'main_frame') {
return { redirectUrl: blockedPageUrl(cfHeader, details.url) };
}
// Subresource (image, script, stylesheet, font, iframe, fetch...): drop
// just that request. The page itself keeps loading without it.
// Makes the extension a bit more usable.
return { cancel: true };
}
browser.webRequest.onHeadersReceived.addListener(
details => stateLoaded
? checkResponse(details)
: stateReady.then(() => checkResponse(details)),
{ urls: ['<all_urls>'] },
['blocking', 'responseHeaders']
);