diff --git a/app/Http/Controllers/DownloadController.php b/app/Http/Controllers/DownloadController.php index 2fc2060..6035c39 100644 --- a/app/Http/Controllers/DownloadController.php +++ b/app/Http/Controllers/DownloadController.php @@ -5,23 +5,35 @@ namespace App\Http\Controllers; use App\Models\Torrent; -use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory; +use Illuminate\Container\Attributes\Storage; +use Illuminate\Filesystem\FilesystemAdapter; use Illuminate\Http\Request; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\StreamedResponse; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; readonly class DownloadController { public function __construct( - private FilesystemFactory $filesystem, + #[Storage('torrents')] private FilesystemAdapter $disk, + private LoggerInterface $logger, ) {} public function __invoke(Request $request, Torrent $torrent): StreamedResponse { + $path = "{$torrent->hash}.torrent"; + + if (! $this->disk->exists($path)) { + // A row without its cached file means the disk has drifted from the + // database, which is worth knowing about even though the visitor + // only ever sees a missing torrent. + $this->logger->error('Cached torrent file is missing.', ['hash' => $torrent->hash]); + + throw new NotFoundHttpException; + } + $torrent->increment('downloads'); - // Read through the same disk the upload wrote to, so the two cannot - // drift apart the way a hardcoded storage path did. - return $this->filesystem->disk('torrents') - ->download("{$torrent->hash}.torrent"); + return $this->disk->download($path); } }