Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Сеть > Правильная отдача файла клиенту


Автор: v1kee 28.1.2011, 16:09
Здравствуйте уважаемые форумчане! 
Такая тема: клиент (например Download Master) обращается на сервер к скрипту download.php, скрипт начинает отдавать клиенту файл на сервере через:
Код

$fs = fopen('filename.rar','rb');
    header("Content-Disposition: attachment; filename=filename.rar");
    header("Accept-Ranges: bytes");
    header("Content-Length: $size");
    header("Content-Range: bytes $range-".($size-1)."/$size");
    header("Content-type: application/octet-stream");
    while (!feof($fs))
    {
        $line = fgets($fs,2048);
        print $line;
    }

таким образом он print'ит весь файл.
Проблема в том что если клиент отменяет закачку или она прервалась по техническим причинам у клиента, скрипт все равно продолжает работу, чем наверно впустую тратит процессорное время сервера! А если файл около 500 МБ скрипт будет работать пока не наступит конец файла...

Вопрос: как определить что клиент отменил передачу файла и завершить работу скрипта? Может в цикле while (!feof($fs)) вставить проверку на какую либо переменную глобальную, а когда в Download Master'e
клиент жмет паузу наверно отправляется заголовок какой нибудь что мол "закачка остановлена", перехват этого заголовка и изменение глобальной переменной приведет к выходу из цикла?

Помогите пожалуйста решить проблему, посоветуйте что нибудь?

Автор: gta4kv 28.1.2011, 16:24
ну во-первых отдача файла скриптом, это идея вообще отстой.

Если оно, всё таки надо, то:
Код

readfile($file_path);


без fopen и прочего. если нужна поддержка докачки, то или отдавать файл не скриптом, или анализировать заголовок X-Range, и тогда придется отдавать файл опять через fopen

Автор: skyboy 28.1.2011, 16:29
Цитата(gta4kv @  28.1.2011,  15:24 Найти цитируемый пост)
Если оно, всё таки надо, то:

... использовать x-sendfile или аналоги. ели тебе вообще нужен скрипт(авторизация, счетчик закачек etc)

Автор: gta4kv 28.1.2011, 16:35
skyboy,
это я собирался предложить дальше.. всё таки x-sendfile это уже не "отдача скриптом"

Автор: v1kee 28.1.2011, 16:55
Нет, мужики, это все конечно хорошо.... но необходимо через php.......

Автор: gta4kv 28.1.2011, 16:56
я написал в первом сообщение, как через PHP

Автор: skyboy 28.1.2011, 17:01
Цитата(v1kee @  28.1.2011,  15:55 Найти цитируемый пост)
Нет, мужики, это все конечно хорошо.... но необходимо через php....... 

что дает механизм x-sendfile - в курсе? если нет, то лучше сначала почитай. 
если в курсе - приведи хоть один аргумент в пользу "только РНР" супротив "PHP + X-SendFile"

Автор: v1kee 28.1.2011, 18:03
Понимаешь, я просто привожу пример такого рода - что скрипт выдает файл со своего сервера, на самом деле все так:
у меня 2 хостинга, первый недорогой с размером в 200 мегабайт, на втором у меня 4 Тб дискового пространства это FTP.
Это все связано таким образом - файл на самом деле хранится на втором хостинге, но я не могу отдавать файл просто так со своего FTP, так как это влечет скачивание файлов без учета трафика, и без учета рейтинга пользователя... Я не хочу чтобы адресс моего FTP фигурировал при передаче пакетов так как это влечет определенные затраты для меня,
поэтому я реализовал следующее:

1. Клиент обращается к download.php
2. download.php отсылает через сокет на FTP header с запросом "HEAD /file.rar HTTP/1.1" 
3. получив размер файла download.php отправляет заголовок GET
4. download.php качает по 2 килобайта и сразу направляет клиенту.

Вот вся цепочка. Теперь, зная что к чему, Вы можете посоветовать что нибудь для решения данной задачи без умного вида
выражений вроде:
Цитата(skyboy @  28.1.2011,  17:01 Найти цитируемый пост)
если нет, то лучше сначала почитай. 

?

Автор: skyboy 28.1.2011, 18:15
Цитата(v1kee @  28.1.2011,  15:09 Найти цитируемый пост)
Проблема в том что если клиент отменяет закачку или она прервалась по техническим причинам у клиента, скрипт все равно продолжает работу

Если коротко: так не должно быть. Для такого поведения надо совершить определенные действия.
http://ua.php.net/manual/en/features.connection-handling.php 
Цитата(v1kee @  28.1.2011,  17:03 Найти цитируемый пост)
без умного вида выражений вроде:

сорри, пишу, как могу.
в дальнейшем попытаюсь писать проще.
дабы не смущать.

Автор: skyboy 28.1.2011, 18:32
используемый FTP поддерживает докачку?

Добавлено через 36 секунд
давай, показывай настоящий скрипт.

Автор: v1kee 28.1.2011, 18:55
Щас почитаю по поводу http://ua.php.net/manual/en/features.connection-handling.php спасибо!
Да FTP поддерживает докачку, при условии что к нему обращаются с логином и паролем администратора.

Автор: skyboy 28.1.2011, 23:26
Цитата(v1kee @  28.1.2011,  17:55 Найти цитируемый пост)
Щас почитаю по поводу

соственно, скинул только ради описания факта - в отсутствие вызова ignore_user_abort работа скрипта должна прерываться сразу после разрыва соединения. если не рвется - то что-то не так.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)