implemented container site assignements & improved routing

This commit is contained in:
Fabian Freund
2025-11-09 07:25:54 +01:00
parent da232bf8aa
commit 107b2a9aa6
45 changed files with 1104 additions and 264 deletions
@@ -5,6 +5,7 @@ import { ProxyType } from '../domain/ProxyType'
import BlockingResponse = browser.webRequest.BlockingResponse
import _OnAuthRequiredDetails = browser.webRequest._OnAuthRequiredDetails
import _OnRequestDetails = browser.proxy._OnRequestDetails
import _OnBeforeRequestDetails = browser.webRequest._OnBeforeRequestDetails
const localhosts = new Set(['localhost', '127.0.0.1', '[::1]'])
@@ -127,13 +128,79 @@ export default class BackgroundMain {
return doNotProxy
}
run(browser: { proxy: any }): void {
const filter = { urls: ['<all_urls>'] }
async onBeforeRequest(options: _OnBeforeRequestDetails, port: browser.runtime.Port): Promise<browser.webRequest.BlockingResponse> {
const tab = (options.tabId > -1) ? (await browser.tabs.get(options.tabId)) : null
browser.proxy.onRequest.addListener(this.onRequest.bind(this), filter)
if (options.frameId !== 0 || tab === null) {
return {};
}
const url = URL.parse(options.url);
if (url !== null && this.store.isSiteOriginAssigned(url)) {
let cookieStoreId: string
if (tab.cookieStoreId?.startsWith(containerIdentifier) === true) {
cookieStoreId = tab.cookieStoreId.substring(containerIdentifier.length)
} else if (tab.cookieStoreId === privateIdentifier) {
// Handle private tabs - use 'private' as identifier
cookieStoreId = 'private'
} else {
cookieStoreId = 'general'
}
if (this.store.isSiteOriginInSameContext(url, cookieStoreId)) {
if (tab.highlighted) {
port.postMessage({
"type": "assignedSiteRequested",
"id": options.requestId,
"status": "success",
"result": {
"originUrl": options.originUrl,
"url": options.url,
"blocked": false
}
});
return {};
} else {
//When tab not selected, block the request
return {
cancel: true,
};
}
} else {
//Only send events when tab is selected
if (tab.highlighted) {
port.postMessage({
"type": "assignedSiteRequested",
"id": options.requestId,
"status": "success",
"result": {
"originUrl": options.originUrl,
"url": options.url,
"blocked": true
}
});
}
return {
cancel: true,
};
}
}
return {};
}
run(browser: { proxy: any, webRequest: any }, port: browser.runtime.Port): void {
browser.proxy.onRequest.addListener(this.onRequest.bind(this), { urls: ['<all_urls>'] })
browser.proxy.onError.addListener((e: Error) => {
console.error('Proxy error', e)
})
browser.webRequest.onBeforeRequest.addListener((options: _OnBeforeRequestDetails) => {
return this.onBeforeRequest(options, port);
}, { urls: ["<all_urls>"], types: ["main_frame"] }, ["blocking"])
}
}
@@ -8,7 +8,7 @@ const store = new Store()
interface Message {
id: String | undefined;
action: 'setProxyPort' | 'addContainerProxy' | 'removeContainerProxy' | 'healthcheck';
action: 'setProxyPort' | 'addContainerProxy' | 'removeContainerProxy' | 'healthcheck' | 'setSiteAssignments';
args: any;
}
@@ -42,6 +42,11 @@ port.onMessage.addListener((raw: unknown): void => {
store.removeContainerProxyRelation(message.args, "tor")
console.log('removed container relation ' + message.args)
break
case "setSiteAssignments":
const entries = new Map(Object.entries(message.args))
console.log('set site assignments ' + JSON.stringify(message.args))
store.setSiteAssignments(entries);
break
case "healthcheck":
port.postMessage({
"type": "healthcheck",
@@ -54,4 +59,4 @@ port.onMessage.addListener((raw: unknown): void => {
});
const backgroundListener = new BackgroundMain({ store })
backgroundListener.run(browser)
backgroundListener.run(browser, port)
@@ -79,6 +79,24 @@ export class Store {
private proxies: ProxyDao[] = []
private relations: { [key: string]: string[] } = {}
private siteAssignments: Map<string, string> = new Map<string, string>()
setSiteAssignments(sites: Map<string, unknown>): void {
this.siteAssignments = new Map(
Array.from(sites, ([key, value]) => {
return [URL.parse(key)!.origin, value as string]
})
);
}
isSiteOriginAssigned(uri: URL): boolean {
return this.siteAssignments.has(uri.origin)
}
isSiteOriginInSameContext(uri: URL, contextId: string): boolean {
return this.siteAssignments.get(uri.origin) === contextId;
}
getAllProxies(): ProxySettings[] {
const proxyDaos = this.getAllProxyDaos()
return proxyDaos.map(tryFromDao).filter(p => p !== undefined) as ProxySettings[]