refactor: decouple from site-specific CDN references #5

Merged
kfj001 merged 11 commits from feature/no_mention_of_pornhub into master 2026-08-30 17:07:52 -07:00
Showing only changes of commit ff463c107a - Show all commits
+38 -32
View File
@@ -29,16 +29,17 @@ function buildModule(code) {
return `(async () => {\n${code}\n})();\n`; return `(async () => {\n${code}\n})();\n`;
} }
// A fresh mock of the chrome APIs the worker touches. `onBeforeSendHeaders`, // A fresh mock of the chrome APIs the worker touches. `onBeforeRequest` and
// `onBeforeRequest`, and `tabs.onRemoved` capture their listener so the test can // `tabs.onRemoved` capture their listener, and `tabs.get` serves the source
// drive them; `declarativeNetRequest.updateSessionRules` records the live rules. // tab's URL (the captured referer); `declarativeNetRequest.updateSessionRules`
// records the live rules.
function makeChromeEnv() { function makeChromeEnv() {
const storage = {}; const storage = {};
const handlers = { onMessage: [] }; const handlers = { onMessage: [] };
const tabUrls = {};
let sessionRules = {}; let sessionRules = {};
const webRequest = { const webRequest = {
onBeforeSendHeaders: { addListener: (cb, filter) => { handlers.onBeforeSendHeaders = cb; handlers.onBeforeSendHeadersFilter = filter; } },
onBeforeRequest: { addListener: (cb) => { handlers.onBeforeRequest = cb; } }, onBeforeRequest: { addListener: (cb) => { handlers.onBeforeRequest = cb; } },
}; };
@@ -62,6 +63,7 @@ function makeChromeEnv() {
}, },
webRequest, webRequest,
tabs: { tabs: {
get: async (tabId) => tabUrls[tabId] ? { tabId, url: tabUrls[tabId] } : undefined,
onRemoved: { addListener: (cb) => { handlers.onRemoved = cb; } }, onRemoved: { addListener: (cb) => { handlers.onRemoved = cb; } },
}, },
runtime: { onMessage: { addListener: (cb) => { handlers.onMessage.push(cb); } } }, runtime: { onMessage: { addListener: (cb) => { handlers.onMessage.push(cb); } } },
@@ -76,7 +78,9 @@ function makeChromeEnv() {
}, },
}; };
return { chrome, handlers, storage, getSessionRules: () => sessionRules }; return { chrome, handlers, storage, tabUrls,
setTabUrl: (tabId, url) => { tabUrls[tabId] = url; },
getSessionRules: () => sessionRules };
} }
// Load the worker into a fresh environment. `data:` URLs are cached by Node, so // Load the worker into a fresh environment. `data:` URLs are cached by Node, so
@@ -92,12 +96,12 @@ async function loadBackground(env) {
return module; return module;
} }
function videoDetails(tabId, url, referer) { // Drive a referer capture the way the worker now does it: the worker reads the
return { // source tab's URL (via chrome.tabs.get) as the provider referer, so we set the
tabId, // tab's URL and fire an onBeforeRequest for a video URL on that tab.
url, async function capture(env, videoUrl, referer) {
requestHeaders: referer ? [{ name: 'Referer', value: referer }] : [], env.setTabUrl(11, referer);
}; await env.handlers.onBeforeRequest({ tabId: 11, url: videoUrl });
} }
describe('PR#5: per-host referer capture + proxy race', () => { describe('PR#5: per-host referer capture + proxy race', () => {
@@ -109,9 +113,7 @@ describe('PR#5: per-host referer capture + proxy race', () => {
await loadBackground(env); await loadBackground(env);
// A live source tab captures the provider referer for its CDN host. // A live source tab captures the provider referer for its CDN host.
const cap = env.handlers.onBeforeSendHeaders; await capture(env, 'https://cdnA.example.com/hls/live/seg-1.ts', 'https://pageA.example.com/watch');
if (!cap) throw new Error('onBeforeSendHeaders listener was not registered');
await cap(videoDetails(11, 'https://cdnA.example.com/hls/live/seg-1.ts', 'https://pageA.example.com/watch'));
const rA = env.storage['goon_referers']?.['example.com']; const rA = env.storage['goon_referers']?.['example.com'];
if (!rA) throw new Error('referer was not captured for cdnA'); if (!rA) throw new Error('referer was not captured for cdnA');
@@ -136,9 +138,7 @@ describe('PR#5: per-host referer capture + proxy race', () => {
global.chrome = env.chrome; global.chrome = env.chrome;
await loadBackground(env); await loadBackground(env);
await env.handlers.onBeforeSendHeaders( await capture(env, 'https://cdnB.example.com/video/x/master.m3u8', 'https://pageB.example.com/v');
videoDetails(11, 'https://cdnB.example.com/video/x/master.m3u8', 'https://pageB.example.com/v')
);
// The very tab that captured the referer now closes. // The very tab that captured the referer now closes.
await env.handlers.onRemoved(11); await env.handlers.onRemoved(11);
@@ -253,8 +253,7 @@ describe('PR#5: per-host referer capture + proxy race', () => {
await loadBackground(env); await loadBackground(env);
// Capture the provider referer for hv-h.phncdn.com (one edge subdomain). // Capture the provider referer for hv-h.phncdn.com (one edge subdomain).
await env.handlers.onBeforeSendHeaders( await capture(env, 'https://hv-h.phncdn.com/hls/live/seg-1.ts', 'https://provider.example.com/watch');
videoDetails(11, 'https://hv-h.phncdn.com/hls/live/seg-1.ts', 'https://provider.example.com/watch'));
// Proxy a SIBLING subdomain ev-h.phncdn.com with NO referer in the message: // Proxy a SIBLING subdomain ev-h.phncdn.com with NO referer in the message:
// the SW must resolve it from the domain-keyed store. // the SW must resolve it from the domain-keyed store.
@@ -315,8 +314,7 @@ describe('PR#5: per-host referer capture + proxy race', () => {
await loadBackground(env); await loadBackground(env);
// Capture for hv-h.phncdn.com only. // Capture for hv-h.phncdn.com only.
await env.handlers.onBeforeSendHeaders( await capture(env, 'https://hv-h.phncdn.com/hls/live/seg-1.ts', 'https://provider.example.com/watch');
videoDetails(11, 'https://hv-h.phncdn.com/hls/live/seg-1.ts', 'https://provider.example.com/watch'));
const handler = env.handlers.onMessage[env.handlers.onMessage.length - 1]; const handler = env.handlers.onMessage[env.handlers.onMessage.length - 1];
let resp; let resp;
@@ -339,20 +337,28 @@ describe('PR#5: per-host referer capture + proxy race', () => {
} }
}); });
// Regression for the live 412 bug: the capture listener MUST request // Regression for the live 412 bug: the worker captures the provider referer
// requestHeaders via extraInfoSpec, or details.requestHeaders is undefined and // from the source tab's URL via chrome.tabs.get inside onBeforeRequest. The
// readReferer() returns '' for every request — so no referer is ever stored, // old path read request headers via onBeforeSendHeaders + extraInfoSpec, which
// every entry stays referer-less, and the phncdn proxy 412s. The callback-level // is rejected by some Chromium builds and fails the whole service worker, so it
// tests above pass even without this (they hand requestHeaders in directly), so // was removed; this asserts the new tab-URL capture is wired up and actually
// this asserts the registration itself. // stores a referer.
it('the onBeforeSendHeaders capture listener requests requestHeaders via extraInfoSpec', async () => { it('the onBeforeRequest capture reads the referer from the source tab URL', async () => {
const env = makeChromeEnv(); const env = makeChromeEnv();
global.chrome = env.chrome; global.chrome = env.chrome;
await loadBackground(env); await loadBackground(env);
const filter = env.handlers.onBeforeSendHeadersFilter;
if (!filter) throw new Error('onBeforeSendHeaders listener registered no filter object'); const cap = env.handlers.onBeforeRequest;
if (!Array.isArray(filter.extraInfoSpec) || !filter.extraInfoSpec.includes('requestHeaders')) { if (!cap) throw new Error('onBeforeRequest listener was not registered');
throw new Error('capture listener did not request requestHeaders via extraInfoSpec: ' + JSON.stringify(filter));
// A video request for cdnA from a tab whose URL IS the provider referer.
env.setTabUrl(11, 'https://pageA.example.com/watch');
await cap({ tabId: 11, url: 'https://cdnA.example.com/hls/live/seg-1.ts' });
const rA = env.storage['goon_referers']?.['example.com'];
if (!rA) throw new Error('referer was not captured from the source tab URL');
if (rA.referer !== 'https://pageA.example.com/watch') {
throw new Error('captured referer wrong: ' + JSON.stringify(rA));
} }
}); });
}); });