fix(stream,bot-detector): prevent false-positive 403 bans and memory exhaustion on direct video streams

This commit is contained in:
Mustafa Yildiz
2026-08-21 13:55:19 +03:00
parent ffe6d93cf6
commit 19c8d496c7
2 changed files with 86 additions and 28 deletions
+46 -3
View File
@@ -510,6 +510,52 @@ Route::get("/stream/proxy", function (\Illuminate\Http\Request $request) {
$customRef = base64_encode($referer);
}
$origin = rtrim($referer, '/');
$path = strtolower(parse_url($url, PHP_URL_PATH) ?? "");
$UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
// Doğrudan MP4 / video dosyası istendiyse belleğe yüklemeden stream et (PHP memory_limit çökmesini önler)
$isDirectMedia = str_ends_with($path, ".mp4")
|| str_ends_with($path, ".m4v")
|| str_ends_with($path, ".webm")
|| str_ends_with($path, ".mkv");
if ($isDirectMedia) {
$streamHeaders = [
"Referer: {$referer}",
"User-Agent: {$UA}",
"Accept: */*",
];
if ($range = $request->header('Range')) {
$streamHeaders[] = "Range: {$range}";
}
return response()->stream(function () use ($url, $streamHeaders) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_TIMEOUT => 300,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER => $streamHeaders,
CURLOPT_WRITEFUNCTION => function ($ch, $chunk) {
echo $chunk;
if (ob_get_level() > 0) {
ob_flush();
}
flush();
return strlen($chunk);
},
]);
curl_exec($ch);
curl_close($ch);
}, 200, [
"Content-Type" => "video/mp4",
"Access-Control-Allow-Origin" => "*",
"Cache-Control" => "public, max-age=86400",
]);
}
// Tek istek yürüten yardımcı — farklı header setleriyle tekrar denemek için.
// Redirect'ler elle takip edilir ki her adım SSRF kontrolünden geçsin.
@@ -546,8 +592,6 @@ Route::get("/stream/proxy", function (\Illuminate\Http\Request $request) {
}
};
$UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
// 1) Referer-only (gerçek oynatıcı davranışı — Origin göndermez, hotlink koruması daha toleranslı)
[$content, $httpCode, $contentType, $curlErrStr] = $fetchUpstream($url, [
"Referer: {$referer}",
@@ -578,7 +622,6 @@ Route::get("/stream/proxy", function (\Illuminate\Http\Request $request) {
abort(502);
}
$path = strtolower(parse_url($url, PHP_URL_PATH) ?? "");
$isM3u8 = str_ends_with($path, ".m3u8")
|| str_contains($contentType, "mpegurl")
|| str_starts_with(trim((string)$content), "#EXTM3U");