diff --git a/app/Http/Middleware/BotDetector.php b/app/Http/Middleware/BotDetector.php index 649dfe3..dece252 100644 --- a/app/Http/Middleware/BotDetector.php +++ b/app/Http/Middleware/BotDetector.php @@ -27,15 +27,17 @@ class BotDetector // Bu IP prefix'leri için tüm kontroller atlanır (güvenilir crawler'lar) private const TRUSTED_IP_PREFIXES = [ - '66.249.', // Googlebot - '64.233.', // Google - '74.125.', // Google - '209.85.', // Google - '216.239.', // Google - '34.68.', // Google Cloud us-central1 - '34.64.', // Google Cloud - '35.187.', // Google Cloud - '35.190.', // Google Cloud + '66.249.', // Googlebot IPv4 + '64.233.', // Google + '74.125.', // Google + '209.85.', // Google + '216.239.', // Google + '34.68.', // Google Cloud us-central1 + '34.64.', // Google Cloud + '35.187.', // Google Cloud + '35.190.', // Google Cloud + '2001:4860:', // Googlebot IPv6 + '2a00:1450:', // Google IPv6 ]; // İzin ver ama bot olarak işaretle (SEO crawler'lar) @@ -80,7 +82,12 @@ class BotDetector public function handle(Request $request, Closure $next) { - $ip = $request->ip(); + // Cloudflare / proxy arkasındaki gerçek istemci IP'sini tespit et + $cfIp = $request->header('CF-Connecting-IP') + ?: ($request->header('True-Client-IP') + ?: ($request->header('X-Forwarded-For') ? trim(explode(',', $request->header('X-Forwarded-For'))[0]) : null)); + $ip = $cfIp ?: $request->ip(); + $ua = strtolower($request->userAgent() ?? ''); $path = '/' . ltrim($request->path(), '/'); @@ -89,7 +96,23 @@ class BotDetector $path = '/' . substr($path, 11); } - // Skip paths + // Botların video parçalarını ve m3u8 playlistlerini boşuna taramasını engelle (CPU / FastCGI koruması) + $isBotCandidate = false; + if (!empty($ua)) { + foreach (array_merge(self::BAD_BOTS, self::GOOD_BOTS, self::GENERIC_BOTS) as $botPattern) { + if (str_contains($ua, $botPattern)) { + $isBotCandidate = true; + break; + } + } + } + if ($isBotCandidate && (str_starts_with($path, '/stream/') || str_starts_with($path, '/vtt-proxy'))) { + return response('No bot indexing allowed on media streams.', 403, [ + 'X-Robots-Tag' => 'noindex, nofollow, noarchive', + ]); + } + + // Skip paths (medya, tracking vb. insan trafiği için rate limit muafiyeti) foreach (self::SKIP_PATHS as $skip) { if (str_starts_with($path, $skip)) { return $next($request); diff --git a/public/robots.txt b/public/robots.txt index 18e449f..0ff1c05 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -11,8 +11,12 @@ Disallow: /watchlist Disallow: /notifications Disallow: /ai Disallow: /watch/ +Disallow: /stream/ +Disallow: /index.php/stream/ Disallow: /vtt-proxy Disallow: /track/ +Disallow: /calls/ +Disallow: /episode/ Disallow: /comments Crawl-delay: 1 @@ -20,11 +24,25 @@ User-agent: Googlebot Allow: / Disallow: /admin/ Disallow: /api/ +Disallow: /stream/ +Disallow: /index.php/stream/ +Disallow: /vtt-proxy +Disallow: /track/ +Disallow: /calls/ +Disallow: /episode/ +Disallow: /comments User-agent: Bingbot Allow: / Disallow: /admin/ Disallow: /api/ +Disallow: /stream/ +Disallow: /index.php/stream/ +Disallow: /vtt-proxy +Disallow: /track/ +Disallow: /calls/ +Disallow: /episode/ +Disallow: /comments # AI eğitim botlarını engelle (standart User-agent yöntemi) User-agent: GPTBot diff --git a/routes/web.php b/routes/web.php index 0c48854..38af6c1 100644 --- a/routes/web.php +++ b/routes/web.php @@ -554,6 +554,8 @@ Route::get("/stream/proxy", function (\Illuminate\Http\Request $request) { "Content-Type" => "video/mp4", "Access-Control-Allow-Origin" => "*", "Cache-Control" => "public, max-age=86400", + "X-Accel-Buffering" => "no", + "X-Robots-Tag" => "noindex, nofollow, noarchive", ]); } @@ -663,6 +665,8 @@ Route::get("/stream/proxy", function (\Illuminate\Http\Request $request) { "Content-Type" => "application/vnd.apple.mpegurl; charset=utf-8", "Access-Control-Allow-Origin" => "*", "Cache-Control" => "no-cache, no-store", + "X-Accel-Buffering" => "no", + "X-Robots-Tag" => "noindex, nofollow, noarchive", ]); } @@ -676,6 +680,8 @@ Route::get("/stream/proxy", function (\Illuminate\Http\Request $request) { "Content-Type" => $segCt ?: "video/mp2t", "Access-Control-Allow-Origin" => "*", "Cache-Control" => "public, max-age=3600", + "X-Accel-Buffering" => "no", + "X-Robots-Tag" => "noindex, nofollow, noarchive", ]); })->name("stream.proxy"); @@ -714,6 +720,8 @@ Route::get("/stream/seg", function (\Illuminate\Http\Request $request) { 'Content-Length' => $size, 'Access-Control-Allow-Origin' => '*', 'Cache-Control' => 'public, max-age=86400', + 'X-Accel-Buffering' => 'no', + 'X-Robots-Tag' => 'noindex, nofollow, noarchive', ]); } @@ -794,6 +802,8 @@ Route::get("/stream/seg", function (\Illuminate\Http\Request $request) { 'Content-Length' => strlen($content), 'Access-Control-Allow-Origin' => '*', 'Cache-Control' => 'public, max-age=86400', + 'X-Accel-Buffering' => 'no', + 'X-Robots-Tag' => 'noindex, nofollow, noarchive', ]); })->name('stream.seg');