servi($territorio->pdf_path, 'application/pdf', 'territorio-' . $territorio->numero . '.pdf'); } public function miniatura(Territorio $territorio): Response { return $this->servi($territorio->thumbnail_path, null, null); } public function versione(TerritorioPdfVersione $versione): Response { $numero = $versione->territorio?->numero ?? 'senza-territorio'; return $this->servi($versione->pdf_path, 'application/pdf', "territorio-{$numero}-versione-{$versione->id}.pdf"); } private function servi(?string $percorso, ?string $tipo, ?string $nome): Response { $disco = Storage::disk('public'); abort_unless($percorso && $disco->exists($percorso), 404); $intestazioni = []; if ($tipo) { $intestazioni['Content-Type'] = $tipo; } if ($nome) { $intestazioni['Content-Disposition'] = 'inline; filename="' . $nome . '"'; } // Privata: niente cache intermedie (Cloudflare). Va impostata dopo, // perché BinaryFileResponse si dichiara pubblica da sola e // sovrascriverebbe un Cache-Control passato fra le intestazioni. // L'indirizzo porta l'impronta del percorso (?v=), che cambia col file. return response()->file($disco->path($percorso), $intestazioni) ->setPrivate() ->setMaxAge(86400); } }