fix(player,vtt): fix CORS proxy bypass on third-party streams and improve vtt-proxy resilience
This commit is contained in:
@@ -1941,8 +1941,7 @@ const IS_AUTH = {{ auth()->check() ? 'true' : 'false' }};
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
// CORS açık CDN'ler — doğrudan tarayıcıdan yükle (sunucu proxy YOK).
|
// CORS açık CDN'ler — doğrudan tarayıcıdan yükle (sunucu proxy YOK).
|
||||||
// NOT: aniziumserver.sbs/site/com buradan bilerek çıkarıldı — CORS izni
|
// NOT: aniziumserver.sbs/site/com, tau-video, zappy-net vb. CORS izni vermediği için proxy'den geçmelidir.
|
||||||
// vermiyorlar (browser console'da doğrulandı), proxy'den geçmeleri gerekiyor.
|
|
||||||
const DIRECT_CORS_HOSTS = [
|
const DIRECT_CORS_HOSTS = [
|
||||||
'anizium.co',
|
'anizium.co',
|
||||||
'misakina.asia', 'misakina.cfd',
|
'misakina.asia', 'misakina.cfd',
|
||||||
@@ -1951,14 +1950,17 @@ const DIRECT_CORS_HOSTS = [
|
|||||||
'rhyzoku-2.asia', 'rhyzoku-4.asia',
|
'rhyzoku-2.asia', 'rhyzoku-4.asia',
|
||||||
'kamadotanjiro.asia', 'uryuishida.asia',
|
'kamadotanjiro.asia', 'uryuishida.asia',
|
||||||
'tohru.icu', 'tohru.cyou',
|
'tohru.icu', 'tohru.cyou',
|
||||||
'zappy-net.store', 'pixel-quirk.shop', 'tau-video.xyz',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Referer gereken (CORS kapalı) CDN'ler için son çare sunucu proxy'si
|
// Referer gereken (CORS kapalı) CDN'ler için sunucu proxy'si
|
||||||
const KNOWN_REFS = {
|
const KNOWN_REFS = {
|
||||||
'aniziumserver.sbs': 'https://anizium.co/',
|
'aniziumserver.sbs': 'https://anizium.co/',
|
||||||
'aniziumserver.site': 'https://anizium.co/',
|
'aniziumserver.site': 'https://anizium.co/',
|
||||||
'aniziumserver.com': 'https://anizium.co/',
|
'aniziumserver.com': 'https://anizium.co/',
|
||||||
|
'tau-video.xyz': 'https://anizium.co/',
|
||||||
|
'zappy-net.store': 'https://anizium.co/',
|
||||||
|
'zappy-net.online': 'https://anizium.co/',
|
||||||
|
'pixel-quirk.shop': 'https://anizium.co/',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sunucu-proxy'sine sarılmış URL'yi çöz (gerçek CDN URL'sini çıkar)
|
// Sunucu-proxy'sine sarılmış URL'yi çöz (gerçek CDN URL'sini çıkar)
|
||||||
@@ -1975,7 +1977,6 @@ function _unwrapProxy(url) {
|
|||||||
function proxyUrl(url) {
|
function proxyUrl(url) {
|
||||||
if (!url) return url;
|
if (!url) return url;
|
||||||
try {
|
try {
|
||||||
// Sunucu proxy'sine sarılmışsa aç — doğrudan CDN'e gitmeyi dene
|
|
||||||
var wrapped = url.indexOf('/stream/proxy') !== -1
|
var wrapped = url.indexOf('/stream/proxy') !== -1
|
||||||
|| url.indexOf('/hls-proxy.php') !== -1
|
|| url.indexOf('/hls-proxy.php') !== -1
|
||||||
|| url.indexOf('/cf-proxy') !== -1;
|
|| url.indexOf('/cf-proxy') !== -1;
|
||||||
@@ -1990,13 +1991,12 @@ function proxyUrl(url) {
|
|||||||
// CORS açık CDN → DOĞRUDAN (no-referrer meta sayesinde 200)
|
// CORS açık CDN → DOĞRUDAN (no-referrer meta sayesinde 200)
|
||||||
if (DIRECT_CORS_HOSTS.some(function(d){ return host === d || host.endsWith('.' + d); })) return real;
|
if (DIRECT_CORS_HOSTS.some(function(d){ return host === d || host.endsWith('.' + d); })) return real;
|
||||||
|
|
||||||
// Zaten sarılmış ama bilinmeyen host → sunucu proxy'sini koru
|
// Zaten proxy'ye sarılmışsa proxy'yi koru (CORS engeli almaması için)
|
||||||
if (wrapped) return url;
|
if (wrapped) return url;
|
||||||
|
|
||||||
// Sarılmamış dış URL, referer gereken CDN → sunucu proxy'si (son çare)
|
// Sarılmamış dış URL, referer gereken CDN → sunucu proxy'si
|
||||||
var ref = (Object.entries(KNOWN_REFS).find(function(e){ return host.endsWith(e[0]); }) || [null,''])[1];
|
var ref = (Object.entries(KNOWN_REFS).find(function(e){ return host.endsWith(e[0]); }) || [null,'https://anizium.co/'])[1];
|
||||||
if (ref) return '/hls-proxy.php?ref=' + encodeURIComponent(ref) + '&url=' + encodeURIComponent(real);
|
return '/stream/proxy?u=' + encodeURIComponent(btoa(real)) + '&ref=' + encodeURIComponent(btoa(ref));
|
||||||
return real; // referer gerekmiyorsa doğrudan dene
|
|
||||||
} catch(e) { return url; }
|
} catch(e) { return url; }
|
||||||
}
|
}
|
||||||
const SUBS = @json($subtitlesData);
|
const SUBS = @json($subtitlesData);
|
||||||
|
|||||||
+44
-10
@@ -498,6 +498,10 @@ Route::get("/stream/proxy", function (\Illuminate\Http\Request $request) {
|
|||||||
'aniziumserver.sbs' => 'https://anizium.co/',
|
'aniziumserver.sbs' => 'https://anizium.co/',
|
||||||
'aniziumserver.site' => 'https://anizium.co/',
|
'aniziumserver.site' => 'https://anizium.co/',
|
||||||
'aniziumserver.com' => 'https://anizium.co/',
|
'aniziumserver.com' => 'https://anizium.co/',
|
||||||
|
'tau-video.xyz' => 'https://anizium.co/',
|
||||||
|
'zappy-net.store' => 'https://anizium.co/',
|
||||||
|
'zappy-net.online' => 'https://anizium.co/',
|
||||||
|
'pixel-quirk.shop' => 'https://anizium.co/',
|
||||||
];
|
];
|
||||||
$referer = null;
|
$referer = null;
|
||||||
foreach ($knownRefs as $domain => $ref) {
|
foreach ($knownRefs as $domain => $ref) {
|
||||||
@@ -812,28 +816,58 @@ Route::get('/vtt-proxy', function (\Illuminate\Http\Request $request) {
|
|||||||
$url = $request->query('url', '');
|
$url = $request->query('url', '');
|
||||||
if (!filter_var($url, FILTER_VALIDATE_URL)) abort(400);
|
if (!filter_var($url, FILTER_VALIDATE_URL)) abort(400);
|
||||||
$host = parse_url($url, PHP_URL_HOST) ?? '';
|
$host = parse_url($url, PHP_URL_HOST) ?? '';
|
||||||
$allowed = ['b-cdn.net', 'bunnycdn.com', 'aniziumserver.site', 'aniziumserver.com', 'aniziumserver.sbs', 'anizium.co'];
|
$allowed = [
|
||||||
|
'b-cdn.net', 'bunnycdn.com',
|
||||||
|
'aniziumserver.site', 'aniziumserver.com', 'aniziumserver.sbs',
|
||||||
|
'anizium.co', 'anizium.net',
|
||||||
|
'tau-video.xyz', 'zappy-net.store', 'pixel-quirk.shop'
|
||||||
|
];
|
||||||
$ok = false;
|
$ok = false;
|
||||||
// Tam eşleşme veya gerçek alt-domain — "evilanizium.co" gibi sahte son ekler geçmez
|
// Tam eşleşme veya gerçek alt-domain — "evilanizium.co" gibi sahte son ekler geçmez
|
||||||
foreach ($allowed as $a) { if ($host === $a || str_ends_with($host, '.' . $a)) { $ok = true; break; } }
|
foreach ($allowed as $a) { if ($host === $a || str_ends_with($host, '.' . $a)) { $ok = true; break; } }
|
||||||
if (!$ok) abort(403);
|
if (!$ok) abort(403);
|
||||||
try {
|
try {
|
||||||
|
// Önce anizium.co referer ile dene
|
||||||
$resp = \Illuminate\Support\Facades\Http::timeout(15)
|
$resp = \Illuminate\Support\Facades\Http::timeout(15)
|
||||||
|
->withoutVerifying()
|
||||||
->withHeaders([
|
->withHeaders([
|
||||||
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
|
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
||||||
'Accept' => 'text/vtt,text/plain,*/*',
|
'Accept' => 'text/vtt,text/plain,*/*',
|
||||||
'Accept-Language' => 'tr-TR,tr;q=0.9,en;q=0.8',
|
'Accept-Language' => 'tr-TR,tr;q=0.9,en;q=0.8',
|
||||||
'Referer' => 'https://x.anizium.co/',
|
'Referer' => 'https://anizium.co/',
|
||||||
])
|
])
|
||||||
->get($url);
|
->get($url);
|
||||||
if (!$resp->successful()) abort($resp->status());
|
|
||||||
|
// Başarısızsa referer'sız dene
|
||||||
|
if (!$resp->successful()) {
|
||||||
|
$resp = \Illuminate\Support\Facades\Http::timeout(15)
|
||||||
|
->withoutVerifying()
|
||||||
|
->withHeaders([
|
||||||
|
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
||||||
|
'Accept' => '*/*',
|
||||||
|
])
|
||||||
|
->get($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$resp->successful()) abort(502);
|
||||||
$body = $resp->body();
|
$body = $resp->body();
|
||||||
// Cloudflare / Anizium hata sayfası dönmüşse (WEBVTT içermiyor) 502
|
|
||||||
if (!str_contains(substr($body, 0, 50), 'WEBVTT')) abort(502);
|
// BOM temizle
|
||||||
return response($body, 200)
|
$body = preg_replace('/^\xEF\xBB\xBF/', '', $body);
|
||||||
->header('Content-Type', 'text/vtt; charset=utf-8')
|
$trimmed = trim($body);
|
||||||
->header('Cache-Control', 'public, max-age=3600')
|
|
||||||
->header('Access-Control-Allow-Origin', '*');
|
// WEBVTT başlığı eksikse ama timestamp formatı içeriyorsa başa WEBVTT ekle
|
||||||
|
if (!str_starts_with($trimmed, 'WEBVTT') && str_contains($body, '-->')) {
|
||||||
|
$body = "WEBVTT\n\n" . $body;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($body, 200, [
|
||||||
|
'Content-Type' => 'text/vtt; charset=utf-8',
|
||||||
|
'Cache-Control' => 'public, max-age=3600',
|
||||||
|
'Access-Control-Allow-Origin' => '*',
|
||||||
|
'X-Accel-Buffering' => 'no',
|
||||||
|
'X-Robots-Tag' => 'noindex, nofollow, noarchive',
|
||||||
|
]);
|
||||||
} catch (\Exception $e) { abort(502); }
|
} catch (\Exception $e) { abort(502); }
|
||||||
})->name('vtt.proxy');
|
})->name('vtt.proxy');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user