Add Android support + now don't block the whole page if a sub-resource is served via CF

This commit is contained in:
libroot 2026-10-11 21:39:08 +00:00
commit b73bf5d4ca
7 changed files with 132 additions and 114 deletions

View file

@ -1,69 +1,65 @@
// 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;
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'toggleBlocking') {
blockingEnabled = message.enabled;
}
const stateReady = browser.storage.local.get({ blockingEnabled: true })
.then(result => { blockingEnabled = result.blockingEnabled; })
.catch(() => { /* keep the default */ })
.then(() => { stateLoaded = true; });
if (message.action === 'getBlockingState') {
sendResponse({ action: 'setBlockingState', enabled: blockingEnabled });
browser.storage.onChanged.addListener((changes, area) => {
if (area === 'local' && changes.blockingEnabled) {
blockingEnabled = changes.blockingEnabled.newValue;
}
});
chrome.webRequest.onHeadersReceived.addListener(
function(details) {
if (!blockingEnabled) {
return { cancel: false };
}
// These are Cloudflare's headers, taken from here:
// https://developers.cloudflare.com/fundamentals/reference/http-headers/
const cloudflare_headers = [
'cf-connecting-ip',
'cf-connecting-ipv6',
'cf-ew-via',
'cf-Pseudo-ipv4',
'cf-ray',
'cf-ipcountry',
'cf-visitor',
'cf-worker'
];
// You might want capture all headers prefixed with "cf-":
// const cf_header = details.responseHeaders.find(header =>
// header.name.toLowerCase().startsWith('cf-')
// );
const cf_header = details.responseHeaders.find(header =>
cloudflare_headers.includes(header.name.toLowerCase())
);
function blockedPageUrl(header, url) {
const query = new URLSearchParams({
name: header.name,
value: header.value || '',
url: url
}).toString();
return browser.runtime.getURL('blocked.html') + '?' + query;
}
if (cf_header) {
console.log('Cloudflare header found:', cf_header);
const query_params = new URLSearchParams({
name: cf_header.name,
value: cf_header.value,
url: details.url
}).toString();
function checkResponse(details) {
if (!blockingEnabled) {
return {};
}
/*
* It would be cool to pass the tab URL in the query params, but how?
* When accessing chrome.tabs here, the active tab URL is "about:newtab".
* Because we block the request immediately and the tab URL state doesn't
* never update to the URL we tried to access. I'd like to pass the URL
* to the web.archive.org/tab_url_here in blocked.html.
* Email contact@libroot.org if you know a solution!
*/
const cfHeader = (details.responseHeaders || []).find(header =>
CLOUDFLARE_HEADERS.has(header.name.toLowerCase())
);
if (!cfHeader) {
return {};
}
// Redirect to our custom blocked.html page
const url = chrome.runtime.getURL('blocked.html') + '?' + query_params;
console.log('Redirecting to blocked page:', url);
chrome.tabs.update(details.tabId, { url: url });
if (details.type === 'main_frame') {
return { redirectUrl: blockedPageUrl(cfHeader, details.url) };
}
// Block the request, reject Cloudflare!
return { cancel: true };
}
},
// 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']
);