mirror of
https://github.com/bytedream/stream-bypass.git
synced 2026-08-04 21:10:40 +02:00
redirect dynamically via injected content script instead of checking
each request
This commit is contained in:
@@ -4,19 +4,54 @@ import { HostSettings, UrlReferer } from '@/lib/settings';
|
|||||||
|
|
||||||
export default defineBackground(() => {
|
export default defineBackground(() => {
|
||||||
browser.runtime.onMessage.addListener(async (message, sender) => {
|
browser.runtime.onMessage.addListener(async (message, sender) => {
|
||||||
const messageType = message.type as BackgroundMessageType;
|
const type = message.type as BackgroundMessageType;
|
||||||
const messageData = message.data as BackgroundMessageData<typeof messageType>;
|
let data = message.data;
|
||||||
|
|
||||||
let response;
|
let response;
|
||||||
switch (messageType) {
|
|
||||||
case BackgroundMessageType.Ff2mpv:
|
switch (type) {
|
||||||
await browser.runtime.sendNativeMessage('ff2mpv', { url: messageData!.url });
|
case BackgroundMessageType.Ff2mpv: {
|
||||||
|
data = data as BackgroundMessageData<typeof type>;
|
||||||
|
|
||||||
|
await browser.runtime.sendNativeMessage('ff2mpv', { url: data.url });
|
||||||
break;
|
break;
|
||||||
case BackgroundMessageType.RequestTabUrl:
|
}
|
||||||
|
case BackgroundMessageType.RequestTabUrl: {
|
||||||
response = sender.tab?.url ?? null;
|
response = sender.tab?.url ?? null;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case BackgroundMessageType.RegisterContentScript: {
|
||||||
|
// requires "dynamic" host permissions, which is only available in mv2
|
||||||
|
if (import.meta.env.MANIFEST_VERSION === 3) break;
|
||||||
|
|
||||||
|
data = data as BackgroundMessageData<typeof type>;
|
||||||
|
|
||||||
|
const contentScript: Browser.scripting.RegisteredContentScript = {
|
||||||
|
id: 'temporary-hosts',
|
||||||
|
js: ['content-scripts/content.js'],
|
||||||
|
matches: [`*://${data.domain}/*`],
|
||||||
|
persistAcrossSessions: false,
|
||||||
|
allFrames: true,
|
||||||
|
runAt: 'document_end'
|
||||||
|
};
|
||||||
|
|
||||||
|
const contentScripts = await browser.scripting.getRegisteredContentScripts({ ids: [contentScript.id] });
|
||||||
|
if (contentScripts.length !== 0) {
|
||||||
|
const registeredContentScript = contentScripts[0];
|
||||||
|
|
||||||
|
// do not double register for same domain
|
||||||
|
if (registeredContentScript.matches!.indexOf(contentScript.matches![0]) !== -1) break;
|
||||||
|
|
||||||
|
contentScript.matches!.push(...contentScripts[0].matches!);
|
||||||
|
await browser.scripting.updateContentScripts([contentScript]);
|
||||||
|
} else {
|
||||||
|
await browser.scripting.registerContentScripts([contentScript]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
@@ -3,11 +3,7 @@ import { getHost, HostMatchType, hosts, type HostMatch } from '@/lib/host';
|
|||||||
import { FF2MPVSettings, PerDomainSettings } from '@/lib/settings';
|
import { FF2MPVSettings, PerDomainSettings } from '@/lib/settings';
|
||||||
|
|
||||||
export default defineContentScript({
|
export default defineContentScript({
|
||||||
matches: [
|
matches: [...Object.values(hosts).flatMap((h) => h.domains.map((d) => `*://${d}/*`))],
|
||||||
...Object.values(hosts).flatMap((h) => h.domains.map((d) => `*://${d}/*`)),
|
|
||||||
// only mv2 allows to match all urls
|
|
||||||
...(import.meta.env.MANIFEST_VERSION === 2 ? ['<all_urls>'] : [])
|
|
||||||
],
|
|
||||||
allFrames: true,
|
allFrames: true,
|
||||||
runAt: 'document_end',
|
runAt: 'document_end',
|
||||||
main
|
main
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// --- tab communication --- //
|
// --- tab communication --- //
|
||||||
export enum TabMessageType {
|
export enum TabMessageType {
|
||||||
RequestActiveMatch,
|
RequestActiveMatch = 10,
|
||||||
NotifyActiveMatch
|
NotifyActiveMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,8 +35,9 @@ export function listenTabMessages(listener: (type: TabMessageType, data: any) =>
|
|||||||
|
|
||||||
// --- background script communication --- //
|
// --- background script communication --- //
|
||||||
export enum BackgroundMessageType {
|
export enum BackgroundMessageType {
|
||||||
Ff2mpv,
|
Ff2mpv = 20,
|
||||||
RequestTabUrl
|
RequestTabUrl,
|
||||||
|
RegisterContentScript
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BackgroundMessageData<T extends BackgroundMessageType> = {
|
export type BackgroundMessageData<T extends BackgroundMessageType> = {
|
||||||
@@ -44,11 +45,15 @@ export type BackgroundMessageData<T extends BackgroundMessageType> = {
|
|||||||
url: string;
|
url: string;
|
||||||
};
|
};
|
||||||
[BackgroundMessageType.RequestTabUrl]: undefined;
|
[BackgroundMessageType.RequestTabUrl]: undefined;
|
||||||
|
[BackgroundMessageType.RegisterContentScript]: {
|
||||||
|
domain: string;
|
||||||
|
};
|
||||||
}[T];
|
}[T];
|
||||||
|
|
||||||
export type BackgroundMessageReply<T extends BackgroundMessageType> = {
|
export type BackgroundMessageReply<T extends BackgroundMessageType> = {
|
||||||
[BackgroundMessageType.Ff2mpv]: undefined;
|
[BackgroundMessageType.Ff2mpv]: undefined;
|
||||||
[BackgroundMessageType.RequestTabUrl]: string | null;
|
[BackgroundMessageType.RequestTabUrl]: string | null;
|
||||||
|
[BackgroundMessageType.RegisterContentScript]: undefined;
|
||||||
}[T];
|
}[T];
|
||||||
|
|
||||||
export async function sendBackgroundMessage<T extends BackgroundMessageType>(
|
export async function sendBackgroundMessage<T extends BackgroundMessageType>(
|
||||||
|
|||||||
+11
-2
@@ -1,4 +1,5 @@
|
|||||||
import { storage } from '#imports';
|
import { storage } from '#imports';
|
||||||
|
import { BackgroundMessageType, sendBackgroundMessage } from './communication';
|
||||||
import type { HostId } from '@/lib/host';
|
import type { HostId } from '@/lib/host';
|
||||||
|
|
||||||
class Setting<T> {
|
class Setting<T> {
|
||||||
@@ -38,11 +39,19 @@ export class HostSettings {
|
|||||||
/* tmp */
|
/* tmp */
|
||||||
private static temporaryHostDomain = new Setting<Record<string, string>>('local:temporaryHostDomain', {});
|
private static temporaryHostDomain = new Setting<Record<string, string>>('local:temporaryHostDomain', {});
|
||||||
|
|
||||||
static addTemporaryHostDomain = (hostId: HostId, domain: string) =>
|
static addTemporaryHostDomain = async (hostId: HostId, domain: string) => {
|
||||||
this.temporaryHostDomain.update((val) => {
|
// only has an effect with mv2
|
||||||
|
const backgroundScriptInject =
|
||||||
|
import.meta.env.MANIFEST_VERSION === 2
|
||||||
|
? sendBackgroundMessage(BackgroundMessageType.RegisterContentScript, { domain: domain })
|
||||||
|
: Promise.resolve();
|
||||||
|
const temporaryHostDomainUpdate = this.temporaryHostDomain.update((val) => {
|
||||||
val[domain] = hostId;
|
val[domain] = hostId;
|
||||||
return val;
|
return val;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return Promise.all([backgroundScriptInject, temporaryHostDomainUpdate]);
|
||||||
|
};
|
||||||
static checkTemporaryHostDomain = (domain: string) => this.temporaryHostDomain.get().then((val) => val[domain]);
|
static checkTemporaryHostDomain = (domain: string) => this.temporaryHostDomain.get().then((val) => val[domain]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -26,7 +26,10 @@ export default defineConfig({
|
|||||||
gecko_android: {}
|
gecko_android: {}
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
permissions: ['storage', ...(manifestVersion === 2 ? ['webRequest', 'webRequestBlocking', '<all_urls>'] : [])],
|
permissions: [
|
||||||
|
'storage',
|
||||||
|
...(manifestVersion === 2 ? ['scripting', 'webRequest', 'webRequestBlocking', '<all_urls>'] : [])
|
||||||
|
],
|
||||||
optional_permissions: ['nativeMessaging'],
|
optional_permissions: ['nativeMessaging'],
|
||||||
web_accessible_resources: [
|
web_accessible_resources: [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user