Initial commit: Animexe Laravel platform
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
const WORKER_PATH = '/cf-proxy';
|
||||
|
||||
export default {
|
||||
async fetch(request) {
|
||||
const url = new URL(request.url);
|
||||
|
||||
if (request.method === 'OPTIONS') {
|
||||
return new Response(null, { status: 204, headers: corsHeaders() });
|
||||
}
|
||||
|
||||
const uParam = url.searchParams.get('u') || '';
|
||||
const refParam = url.searchParams.get('ref') || '';
|
||||
|
||||
let targetUrl;
|
||||
try {
|
||||
targetUrl = atob(uParam);
|
||||
if (!targetUrl.startsWith('http')) throw 0;
|
||||
} catch {
|
||||
return new Response('Missing or invalid u param', { status: 400 });
|
||||
}
|
||||
|
||||
let referer;
|
||||
try {
|
||||
referer = refParam ? atob(refParam) : new URL(targetUrl).origin + '/';
|
||||
if (!referer.endsWith('/')) referer += '/';
|
||||
} catch {
|
||||
referer = new URL(targetUrl).origin + '/';
|
||||
}
|
||||
|
||||
let resp;
|
||||
try {
|
||||
resp = await fetch(targetUrl, {
|
||||
headers: {
|
||||
'Referer': referer,
|
||||
'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',
|
||||
'Accept': '*/*',
|
||||
'Accept-Language': 'tr-TR,tr;q=0.9,en;q=0.8',
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
return new Response('Upstream fetch failed: ' + e.message, { status: 502 });
|
||||
}
|
||||
|
||||
if (!resp.ok && resp.status !== 206) {
|
||||
// Referer ile de olmadıysa referer'sız dene (bazı CDN'ler Cloudflare'dan gelen Referer'ı reddeder)
|
||||
try {
|
||||
const fallbackResp = await fetch(targetUrl, {
|
||||
headers: {
|
||||
'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',
|
||||
'Accept': '*/*',
|
||||
},
|
||||
});
|
||||
if (fallbackResp.ok || fallbackResp.status === 206) {
|
||||
resp = fallbackResp;
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const ct = resp.headers.get('content-type') || '';
|
||||
const isM3u8 = ct.includes('mpegurl') || targetUrl.toLowerCase().includes('.m3u8');
|
||||
|
||||
if (isM3u8) {
|
||||
const body = await resp.text();
|
||||
if (body.trimStart().startsWith('#EXTM3U')) {
|
||||
const baseDir = targetUrl.substring(0, targetUrl.lastIndexOf('/') + 1);
|
||||
const workerBase = url.origin + WORKER_PATH + '?u=';
|
||||
const refSuffix = '&ref=' + btoa(referer);
|
||||
|
||||
const rewritten = body.split('\n').map(line => {
|
||||
const t = line.trimEnd();
|
||||
if (t === '') return '';
|
||||
if (t.startsWith('#')) {
|
||||
return t.replace(/URI="([^"]+)"/g, (_, uri) => {
|
||||
const abs = uri.startsWith('http') ? uri : baseDir + uri;
|
||||
return `URI="${workerBase}${btoa(abs)}${refSuffix}"`;
|
||||
});
|
||||
}
|
||||
const abs = t.startsWith('http') ? t : baseDir + t;
|
||||
return workerBase + btoa(abs) + refSuffix;
|
||||
}).join('\n');
|
||||
|
||||
return new Response(rewritten, {
|
||||
status: 200,
|
||||
headers: { ...corsHeaders(), 'Content-Type': 'application/vnd.apple.mpegurl', 'Cache-Control': 'no-cache' },
|
||||
});
|
||||
}
|
||||
// m3u8 gibi görünüp değil — binary olarak geçir
|
||||
return new Response(body, {
|
||||
status: resp.status,
|
||||
headers: { ...corsHeaders(), 'Content-Type': ct || 'video/mp2t' },
|
||||
});
|
||||
}
|
||||
|
||||
// Segment (.ts, .key, .png vb.) — body'yi doğrudan stream et (belleğe alma)
|
||||
let segCt = ct;
|
||||
if (!segCt || segCt.startsWith('image/') || segCt === 'application/octet-stream') {
|
||||
segCt = 'video/mp2t';
|
||||
}
|
||||
return new Response(resp.body, {
|
||||
status: resp.status,
|
||||
headers: { ...corsHeaders(), 'Content-Type': segCt, 'Cache-Control': 'public, max-age=3600' },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function corsHeaders() {
|
||||
return {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Range, Origin',
|
||||
'Access-Control-Expose-Headers': 'Content-Length, Content-Range, Content-Type',
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user