Fixes issue with pornhub. Removes references.
CI / test (pull_request) Failing after 20s

This commit is contained in:
kfj001 committed 2026-08-30 04:48:23 +00:00
1 parent 7b43d260a2
commit 4357ce4094
9 files changed
+337 -100

No files matched your search

+27
View File
@@ -1147,6 +1147,7 @@ async function scanVideos(tabsToScan) {
}
const items = [...seen.values()];
await attachReferers(items);
const skipped = scrapeResults.filter(r => r === null).length;
log('scanVideos complete: scanned=', tabResults.length, 'skipped=', skipped, 'unique items=', items.length);
@@ -1157,6 +1158,31 @@ async function scanVideos(tabsToScan) {
return { items, scanned: tabResults.length, skipped };
}
/**
* Bind the provider referer the SW captured (domain-aware) to each item so it
* survives the watch-later flow and covers the sibling edge subdomains a segment
* may resolve to. Best-effort: playback still falls back to the SW's live store.
*/
async function attachReferers(items) {
const hostOf = (url) => { try { return new URL(url).host.toLowerCase(); } catch { return ''; } };
const hosts = [];
for (const it of items) {
const host = hostOf(it.hlsManifest || it.src || '');
if (host) hosts.push(host);
}
if (hosts.length === 0) return;
let referers = {};
try {
const resp = await chrome.runtime.sendMessage({ type: 'GOON_GET_REFERERS', hosts });
if (resp && resp.referers) referers = resp.referers;
} catch { /* referer is best-effort; the SW still resolves it at play time */ }
if (!Object.keys(referers).length) return;
for (const it of items) {
const host = hostOf(it.hlsManifest || it.src || '');
if (host && referers[host]) it.referer = referers[host];
}
}
/** Store video entries in chrome.storage.local. */
async function storeVideos(items) {
const stored = items.map(v => ({
@@ -1165,6 +1191,7 @@ async function storeVideos(items) {
tab: v.tab,
mediaType: v.mediaType || 'video',
hlsManifest: v.hlsManifest || undefined,
referer: v.referer || undefined,
}));
await chrome.storage.local.set({
[STORAGE_KEY]: stored,
+5
View File
@@ -33,6 +33,11 @@
"type": "string",
"enum": ["direct", "hls"],
"description": "Media delivery format. Defaults to 'direct' when omitted. Set to 'hls' for HTTP Live Streaming."
},
"referer": {
"type": ["string", "null"],
"format": "uri",
"description": "Provider Referer captured at scan time for the manifest's CDN; the proxy sends it so a referer-protecting CDN accepts sibling edge subdomains. Optional."
}
},
"additionalProperties": false,
+33 -9
View File
@@ -178,7 +178,7 @@ const panelsEl = document.getElementById('panels');
// Route through the service worker to bypass the CDN's CORS/Referer
// restrictions. The SW adds the required Referer and returns base64.
console.log('[goon-viewer] Proxying via SW:', (url || '').substring(0, 120));
chrome.runtime.sendMessage({ type: 'GOON_PROXY_FETCH', url, referer: originForUrl(url) }, (resp) => {
chrome.runtime.sendMessage({ type: 'GOON_PROXY_FETCH', url, referer: refererForUrl(url) }, (resp) => {
if (self._aborted) return;
const lastErr = chrome.runtime.lastError;
if (lastErr || !resp || !resp.ok) {
@@ -264,19 +264,34 @@ HlsLoader.canSupportLoader = function () { return true; };
// hardcode a particular CDN.
const PROXY_HOSTS_KEY = 'goon_proxy_hosts';
const proxyHosts = new Set();
// Provider referers bound to a stored entry at scan time, keyed by the entry's
// manifest registrable domain. A single provider referer covers every edge
// subdomain, so a segment on a sibling subhost resolves to the same referer.
const refererByDomain = new Map();
(async () => {
try {
const stored = await chrome.storage.local.get(PROXY_HOSTS_KEY);
const hosts = stored[PROXY_HOSTS_KEY];
if (Array.isArray(hosts)) for (const h of hosts) proxyHosts.add(String(h).toLowerCase());
if (Array.isArray(hosts)) for (const h of hosts) proxyHosts.add(registrableDomainOf(String(h).toLowerCase()));
} catch { /* ignore */ }
})();
// Origin for a URL's host — used as the Referer to request when a proxy fetch
// is made for that host (the SW also captures the live referer per host).
function originForUrl(url) {
if (!url) return '';
try { return new URL(url).origin + '/'; } catch { return ''; }
// Registrable domain of a CDN host — the label a single provider referer
// applies to (a referer-protecting CDN serves from many edge subdomains that
// share one referer). Last-two-labels heuristic; mirrors the SW's copy.
function registrableDomainOf(host) {
if (!host) return '';
const parts = host.split('.');
if (parts.length < 2) return host;
return parts.slice(-2).join('.');
}
// The provider referer to send for a proxied request: the referer bound to the
// entry at scan time (domain-keyed), or '' when none was captured. No self-origin
// fallback — a self-origin referer is guaranteed-wrong for hotlink protection.
function refererForUrl(url) {
const ref = refererByDomain.get(registrableDomainOf(hostOfUrl(url)));
return ref || '';
}
// Whether a given video URL should be proxied: its host is a known
@@ -284,7 +299,7 @@ HlsLoader.canSupportLoader = function () { return true; };
function needsProxy(url) {
if (!url || typeof url !== 'string') return false;
const host = hostOfUrl(url);
return host ? proxyHosts.has(host) : false;
return host ? proxyHosts.has(registrableDomainOf(host)) : false;
}
// host of a URL (lowercased); '' when malformed.
@@ -1184,11 +1199,20 @@ async function init() {
// Probe CORS on each video URL. Hosts that block extension-origin
// requests are learned as referer-protected and persisted so the viewer
// routes them through the service-worker proxy.
// Bind each entry's scan-time referer to its manifest's registrable
// domain, so the proxy sends it for every edge subdomain the provider
// serves from (segments often resolve to a sibling subhost).
for (const entry of videoUrls) {
const ref = entry && entry.referer;
if (!ref) continue;
const dom = registrableDomainOf(hostOfUrl(entry.src || entry.hlsManifest || ''));
if (dom) refererByDomain.set(dom, ref);
}
const urlsToTest = videoUrls.map(v => v.src || v.hlsManifest || 'none').filter(u => u !== 'none' && typeof u === 'string');
const blockedHosts = new Set();
for (const url of [...new Set(urlsToTest)]) {
const corsOk = await corsCheck(url);
if (!corsOk) blockedHosts.add(hostOfUrl(url));
if (!corsOk) blockedHosts.add(registrableDomainOf(hostOfUrl(url)));
console.log('[goon-viewer] CORS', corsOk ? 'OK' : 'BLOCKED:', url.substring(0, 120));
}
if (blockedHosts.size > 0) {