Zamieszczony poniżej kod może być użyty do pobrania dowolnego pliku, dlatego warto zadbać o jego odpowiednie zabezpieczenie. Przecież nie chcemy aby przypadkiem ktoś zaczął pobierać kod naszego własnego modułu.
header('Cache-Control: public'); header('Content-Type: application/octet-stream'); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Cache-Control: post-check=0, pre-check=0'); header('Content-Disposition: attachment; filename="' . $Filename . '";'); header('Content-Length: ' . filesize($path)); header('Content-Transfer-Encoding: binary'); if (ob_get_level()) { ob_end_clean(); } if ($fd = fopen($path, 'rb')) { while (!feof($fd)) { print fread($fd, 1024); } fclose($fd); } else { drupal_not_found(); } drupal_exit();
Bardzo istotne okazało się ustawienie nagłówka Content-Length. Bez tego nagłówka, transfer pliku wykłada się w losowych momentach i przesłanie czegoś powyżej 40MB graniczyło z cudem. Ciekawa jest jeszcze inna sprawa. Pierwotnie chciałem użyć funkcji readfile(). Pomimo wyłączenia buforowania wyjścia, skrypt wykładał się z błędem informującym o braku pamięci (limit 120MB, plik 150MB). Teoretycznie pod spodem PHP robi dokładnie to samo co ja, czyli czyta plik w pętli porcjami wysyłając go do użytkownika. Teoria teorią, a praktyka wymusiła jawne czytanie pliku po 1024B.
Brak komentarzy:
Prześlij komentarz