This commit is contained in:
1 parent
7b43d260a2
commit
4357ce4094
9 files changed
+337
-100
No files matched your search
+33
-9
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user