Force download dużych plików

0

Witam,
mam problem z pobieraniem plików przez PHP. Wygląda na to, że serwer wydaje plik jakby za szybko i w pewnym momencie pobieranie po prostu się zatrzymuje, bo przeglądarka nie ma co pobierać, a pobrany plik pozostaje niepełny. Dodam, że czasem ściągnie się 50MB, czasem 100MB, czasem przerwie po 3 minutach, czasem po 2,5... Domyślam się, że to ma jakiś związek z prędkością pobierania. Im szybciej pobieram tym mniej się pobiera i szybciej kończy. Zauważyłem też, że czasami pobiera się dokładnie 63,6 KB (po prostu zrywa połączenie od razu) Problem nie występuje dla pliku 80MB, ale dla 160MB już tak.
Nie wiem już gdzie doszukiwać się błędu. Ustawianie timeoutów nic nie dało.
To są moje headery:

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));

Nie działa ani prosty readfile(), passthru(), ani fread(), nie działa też zwykły file_get_contents(). Wszystkie powodują wyżej opisane zachowanie.
Jest jedno rozwiązanie, które działa, ale niestety nie jest wydajne. Polega ono na serwowaniu pliku w kawałkach 1MB i usypianiu na sekundę skryptu po każdym kawałku. Zmiana wartości (rozmiar danych/czas uśpienia) również powoduje w/w problem. Takie podejście jest trochę bez sensu, bo prędkość pobierania jest sztucznie ograniczana przez skrypt do 1MB/s.

while (!feof($handle)) {
            echo fread($handle, 1024*1024);
            flush();
            sleep(1);
        }

Oczywiście pobieranie przez direct link działa poprawnie, ale pliki docelowo mają być dostępne tylko dla wybranych użytkowników.
Serwer to Nginx na az.pl więc X-Sendfile nie zrobię, a do X-accel, z tego co wyczytałem, to musiał bym prosić o edycję configu serwera (chyba mi nie pozwolą ;) )

Jakieś pomysły co może powodować takie zachowanie?

0

set_time_limit

po co ten sleep? [nie doczytałem] a nie, to jednak też Ci niepotrzebne :P

a jak plik ma dokładnie jakąś wartość rozmiaru - to podejrzyj jego zawartość - zapewne w treści znajdziesz błąd php.

0
dzek69 napisał(a):

set_time_limit

Jak pisałem, ustawianie limitów nic nie zmienia.

dzek69 napisał(a):

po co ten sleep? [nie doczytałem] a nie, to jednak też Ci niepotrzebne :P

No właśnie nie wiem po co on tam, ale to jest dosłownie jedyna opcja, kiedy plik ściąga się w całości. Bez sleepa przerywa.

dzek69 napisał(a):

a jak plik ma dokładnie jakąś wartość rozmiaru - to podejrzyj jego zawartość - zapewne w treści znajdziesz błąd php.

Też tak myślałem na początku, jednak on ściąga 63KB owego pliku. W środku jest sam kod binarny.

0

Trochę mi brzmi jak brak pamięci. Masz ustawione logowanie błędów do pliku, który mógłbyś odczytać? Spróbuj też podawać plik przez readfile (readfile od razu wypluwa output, nie trzeba echo)

0

Jak już wspomniałem, readfile() też się sypie. output_buffering mam wyłączony.
W logu serwera nic się nie pojawia. PHP też nie rzuca błędem. Po prostu w pewnym momencie przestają "przychodzić" nowe bajty, prędkość zaczyna spadać, dochodząc do 0 się zatrzymuje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1