Скачивание файлов и учет трафика

Toxic_Cat

Новичок
Все-равно система учета будет очень сложной и вообще надо подумать так ли она нужна? Цель оправдывает средства?
 

twistfire

Новичок
да в том то и дело, что нужна...
но хочется прощеи надежнее для польлователей сделать. чтобі не возникало проблем потом.
можно конечно сделать топорно - читать весь файл да и вічитать пока качает с юзера деньги...
а если закачка оборвется?
 

Toxic_Cat

Новичок
Автор оригинала: twistfire
да в том то и дело, что нужна...
но хочется прощеи надежнее для польлователей сделать. чтобі не возникало проблем потом.
можно конечно сделать топорно - читать весь файл да и вічитать пока качает с юзера деньги...
а если закачка оборвется?
Файл можно разбивать архиватором на несколько частей и только потом вымещать на сервер для скачивания...

Например если файлы до 10 мб то можно 5 шутк по 2мб выложить... Если закачка оборвется то 2мб будет не слишком большая потеря...

Если файлы по 700кб то архивы делать по 45мб

Но это тоже не слишком легко, тем более что это нудная работа...
 

twistfire

Новичок
мне кажется, что я конечно попітаюсь организовать докачку, как кто-то показывал, но как мне кажется - это будет не везде работать...
 

Turist

Новичок
Автор оригинала: twistfire
что-то уж это по-м-ему слишком сложная система получится.
А помоемому всё достаточно просто ;)
ПРо Range я и сам думал, но тогда качалки, которые самые хорошие, которые секциями качают - мне сервак просто убьют?
Поставьте ограничение на количество одновременно запущенных скриптов для одного IP
(будет много процессов Или нет, вот єто интересно, какая нагрузка?)
Было бы замечательно если бы вы сами проверили и опубликовали тут результаты
Т.е. я понимаю, что качалки просто будут требовать у скрипта различные части файла?
Да

Код тут:
http://www.livejournal.com/users/onlyforread/11715.html
 

twistfire

Новичок
супер..
а результаты обязательно размещу :) (но только как протестю с бд)

-~{}~ 11.12.05 16:38:

хм...
почему-то вообще неверно отдает файл... постоянные ошибки...

выложил...
http://netgen.com.ua/files/download.php
должен отдать файл 44a97be77.rar размером
212 932 bytes
отдал - но неисправный архив...
(качал с пом. Reget в неск. потоков)

на самом деле архив исправен..
в чем дело?

по-моему скрипт неверно отдает куски файла. Я не в состоянии разобраться, может поможет кто?

-~{}~ 11.12.05 16:55:

а у вас все нормально работает :) ? Может это у меня глюки? :)
 

Turist

Новичок
Думаю где нибудь ошибся на 1 байтик... надо посмотреть.
К сожелению быстро не получится, много дел. Постараюсь в течении недели.
 

twistfire

Новичок
Автор оригинала: Turist
Думаю где нибудь ошибся на 1 байтик... надо посмотреть.
К сожелению быстро не получится, много дел. Постараюсь в течении недели.
Посмотрите пожалуйста...
Очень поможет этот скрипт в построениии функциональной системы.
Заранее спасибо

-~{}~ 14.12.05 12:05:

хм...
почему-то не логируется вообще трафик.
думал не раьотает register_shutdown_function - работает вроде...

-~{}~ 14.12.05 19:06:

глупо как-то ...
уже другую функцию использовал - и все равно говорит - что файл битый, хотя это не так.
Когда читаю просто readfile - отлично відает файлик.
В чем дело? ГОРЮ....
 

Turist

Новичок
хм...
почему-то не логируется вообще трафик.
думал не раьотает register_shutdown_function - работает вроде...
Что значит не логируется? Не создаётся файл или туда ничего не пишется?
глупо как-то ...
уже другую функцию использовал - и все равно говорит - что файл битый, хотя это не так.
Когда читаю просто readfile - отлично відает файлик.
В чем дело? ГОРЮ....
Какую другую функцию?
Докачивать то докачивает? Размеры файлов сравнивали?
 

alexhemp

Новичок
twistfire
Офигеть - может тебе еще и ключи от квартиры где деньги лежат.

Единственный разумный путь такой:

1. Файлы отдавать с использованием техники получившей название anti-leech - генерировать уникальную для клиента, его ip и файла ссылку - используя например MD5 - при геренации ссылка записывается в БД

2. Отдавать файлы скриптом, поддерживая докачку в течении всего срока действия ссылки. Срок действия нужно выставлять разумным, не час и не два - все равно выданный линк уникален для ip.

3. Нужно предусмотреть режим получения новой ссылки на скачивание - у диалапщиков меняется ip при обрыве

4. Бороться с большим количеством запросов можно - не выдавать одновременно одному клиенту много ссылок на файл - т.е. качать одновременно можно с одного ip. Частоту выдачи ссылок и их общее количество - тоже ограничить (например 10 раз можно получить ссылку на один файл, если больше - то вопрос решать через администрацию)

5. Вести полный лог скачивания - т.е. кто-когда-откуда-что качает. Для разбора полетов в случае чего.

При выдаче возможны варианты (например отдавать сами большие файлы легким сервером - например nginx - но нужно кумекать над тем как он будет определять валидность ссылки - т.е. обращаться к базе).
 

twistfire

Новичок
2 turist:
размер файла сравнивал - одинаковый.
качал с помощью обычнойго загрузчика Firefox, и REGET.

Вот тот скрипт, который использовал я:

<?
$filename="44a97be77.rar";
$mime_type="application/octet-stream";
define('FILE_PART_SIZE',1024*8*10);
ignore_user_abort(false);

register_shutdown_function('shdn');

function shdn() {
global $g_total;
if (connection_aborted()) {
$h2=fopen("download.txt","a+");
$str2save=date("Y-m-d")." ".$_SERVER["REMOTE_ADDR"]." ".$g_total."\n";
fwrite($h2,$str2save);
fclose($h2);
}
}

if (file_exists($filename)) {
$filesize=filesize($filename);
} else {
exit('File '.$filename.' not found');
}

$g_total=0;

$h=fopen($filename,'rb');
if (!$h) {
exit('Can not open file: '.$filename);
}

header("Content-Type: $mime_type;");
header('Accept-Ranges: bytes');

if (isset($_SERVER['HTTP_RANGE'])) {
preg_match_all('/bytes=([0-9]*)-([0-9]*)/',$_SERVER['HTTP_RANGE'],$out);
header("HTTP/1.1 206 Partial Content");
$rlow=$out[1][0];
$rhigh=$out[2][0];
if (empty($rhigh)) $rhigh=$filesize-1;
header("Content-Range: bytes $rlow-$rhigh/$filesize");
$filesize = $rhigh - $rlow + 1;
}
header("Content-Length: $filesize");
header("Content-Disposition: attachment; filename=$filename");

set_time_limit(0);
if (isset($rhigh)) fread($h,$rlow);
while (!feof($h)) {
flush();
echo fread($h, FILE_PART_SIZE);
$g_total+=FILE_PART_SIZE;
sleep(2);
}

fclose($h);
ob_clean();
?>

получил файл...
вот часть заголовков
HTTP/1.1 206 Partial Content
Date: Wed, 14 Dec 2005 18:31:56 GMT
Server: Apache/1.3.33 (Unix) PHP/4.3.10 mod_ssl/2.8.22 OpenSSL/0.9.7g rus/PL30.20
Accept-Ranges: bytes
Content-Range: bytes 119449-212931/212932
Content-Length: 93483
Content-Disposition: attachment; filename=44a97be77.rar
Connection: close
Content-Type: application/octet-stream;

-~{}~ 14.12.05 21:38:

а может это быть связано с определенным типом файла или mime?
Т.е. не имеет значения с каким mime я отдаю файл?

И еще чуть не забыл - файл (лог) - даже не создается, а когда есть - в него ничего не пишется.
(Права выставил для группы и владельца на запись.)
 

Turist

Новичок
Во-первых, не нужно было выводить полностью мной же написанный код. Достаточно было на него указать.
Во-вторых, мне кажется, вы даже не пытались разобраться в том, как работает скрипт и что он делает, иначе вы бы вероятно нашли строку c функцией sleep(2), которую я по недосмотру забыл убрать (использовал во время отладки).
Далее вы утверждаете, что register_shutdown_function "вроде" работает. Что значит "вроде", как вы это проверяли?
Если файл не создаётся, то это на 99% значит, что у скрипта не хватает прав на создание/запись в директории. Проверьте в какую директорию вы пытаетесь писать и правильно ли на неё выставлены права. (Посмотрите что выдаётся в error_log)
Вы сравнивали размер файлов с точностью до байта? Вы пробовали посмотреть diff этих файлов (скаченного "битого" и исходного)? Вы хотя бы в error_log посмотрели?
Эта проблема не может быть связана с типом файла.
 

twistfire

Новичок
diff у меня нет возможности сделать.
error_log посмотерть тоже не могу.

строка sleep(2) как я думал - для уменьшения нагрузки на сервер.

насчет register_shutdown_function - я в другом скрипте попробовал - работает. Ну то ж тогда буду копать :)

-~{}~ 16.12.05 09:18:

а кто-нибудь тестил этот пример еще??
 
Сверху