Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] force download + output buffering = uszkodzony plik
Forum PHP.pl > Forum > PHP
TheTester
Witam
Ostatnio natknąłem się na dość dziwny problem. Na podstawie tego co jest opisane na http://pl.php.net/manual/pl/function.header.php stworzyłem na swoje potrzeby skrypt do wypluwania pliku.
  1. <?php
  2. if(file_exists($link)) {
  3.                    header("Pragma: public");
  4.                    header("Expires: 0");
  5.                    header("Cache-Control: no-store, must-revalidate, post-check=0, pre-check=0");
  6.                    header("Content-Type: application/force-download");
  7.                    header("Content-Type: application/octet-stream");
  8.                    header("Content-Type: application/download");
  9.  
  10.                    header("Content-Disposition: attachment; filename=\"".basename($link)."\";");
  11.                    header("Content-Transfer-Encoding: binary");
  12.                    header("Content-Length: ".filesize($link));
  13.                                                
  14.                    @readfile($link);
  15.                }
  16. ?>

Gdzie $link, to ścieżka do pliku na serwerze.
Cały skrypt jest "wewnątrz" ob_start().
Ostatnio zauważyłem, że niektóre pliki (typ nieistotny) po ściągnięciu są uszkodzone, np. plik .zip wykazuje uszkodzenie archiwum. Poszukałem trochę i znalazłem inny, dość ciekawy przykład wypluwania plików, który działał, ale...Na moim kompie, gdzie Apache stoi na Win wszystko jest ok, ale na serwerze, który stoi na Linuxie pojawia się komunikat, że nie można odczytać pliku źródłowego. (Nie wiem czy różnica w systemie ma akurat znaczenie - podałem na wszelki wypadek) Ciekawostka - Opera pobiera plik; FF i IE nie chce.
Po krótkiej analizie, okazało się, że taki efekt powoduje dodanie ob_end_clean(), czyli wyłączenie buforowania przed podaniem pliku.
Gdzieś wyczytałem, że to może być wina Content-Length, ale usunięcie tego nagłówka nie pomaga.
Czy to może być wina źle skonfigurowanego serwera?

Nie mam specjalnie pomysłu gdzie by jeszcze się zaczepić w poszukiwaniu problemu, dlatego proszę o jakieś sugestie. smile.gif
ddiceman
http://pl.php.net/manual/pl/function.readfile.php#74675 - dodaj exit();
TheTester
Nie pomaga. Nadal efekt jest taki sam, czyli pobiera uszkodzony plik. Nadal dodanie ob_end_clean() pod Win podaje prawidłowy plik, a pod Linuxem przeglądarka zwraca niemożność odczytania pliku źródłowego.
ddiceman
Wyedytuj sobie dowolnym edytorem ten uszkodzony plik i zobacz, czy czasem nie ma w nim jakiegos komunikatu serwera (np. 500 Internal Server Error). Sprobuj tez z Windowsa skopiowac ten plik do Linuxa i porownac (edytor tekstu) koniec i poczatek pliku. Powiedz pozniej, czym sie roznia miedzy soba
TheTester
Ok. Już wszystko wiadomo. Miałem echo gdzieś w kodzie wcześniej (fragment kopiowany z innego kodu), który przeoczyłem. To spowodowało dodawanie zawartości echo na początku pliku. winksmiley.jpg
Dzięki za naprowadzenie na trop. smile.gif
Matius90
Dzięki ddiceman, bardzo mi pomogłeś wink.gif
Pozdrawiam serdecznie
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.