Делаю раздел "downloads", очень нужна ваша помощь по части скрытия файлов от жадных

Spear

почемучка
Делаю раздел "downloads", очень нужна ваша помощь по части скрытия файлов от жадных

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

Вообщем у меня вопросик - как такие проблемы решают на крупных проектах?

Один "советчик" сказал про "генерацию" уникального имени для файла. а каким боком это он имел ввиду? переименовывание имени файла при каждом обращении? Вообщем - я немного растерян, хотел бы узнать Ваши мнения.
 

Yourick

Новичок
единственно что в голову приходит, это если файлики небольшие -- по почте высылать :)
а вообще вот что я нашёл в мануале сёрче по слову download
(это только первый постинг из User contributed notes)

I have found that for certain formats, for example, PDF, the simple code:
header("Content-type: application/x-download");
header("Content-Disposition: attachment; filename=$file_download_name;");
@readfile($file_server_path);
does not work, and produces corrupted files for all browsers on all platforms. During the downloads, I noticed that the browser was not receiving ahead of time the length of the file, which was somehow causing some formats to be corrupted.
e.g.: "Downloading file example.pdf: 347.2 KB of ?"
I solved the problem by adding more headers:
$download_size = filesize($file_server_path);
header("Content-type: application/x-download");
header("Content-Disposition: attachment; filename=$file_download_name;");
header("Accept-Ranges: bytes");
header("Content-Length: $download_size");
@readfile($file_server_path);
Somehow the files aren't corrupted when the browser knows how big they are from the start.
I hope that helps :)
 

Spear

почемучка
Yourick
спасибо за ответ ;)

Вообщем для начала я хотел бы узнать - правильно ли будет использование вышеприведенного кода:


PHP:
$download_size = filesize($file_server_path);
header("Content-type: application/x-download");
header("Content-Disposition: attachment; filename=$file_download_name;");
header("Accept-Ranges: bytes");
header("Content-Length: $download_size");
@readfile($file_server_path);
и не будут ли возникать ошибки с разными браузерами (например IE6, Opera), будет ли работать "докачка" файлов?
Использовать ли readfile или
PHP:
$fp=fopen($filename, "rb");   
fpassthru($fp);
(нашел на форуме кусок кода)

Если все верно, появляются следующие вопросы - как, собственно, выдавать файл юзеру, чтобы имя было красивое, например
http://www.site.com/files/3495_filename.zip
Чтобы можно было без использования проверки рефера защитить файл от скачивания с других источников?

Например (это мои скромные наброски, как реализовать, пока что, не представляю):
вся инфа о файлах есть в БД (id, имя файла, дата последней генерации имени файла)

когда юзверь хочет скачать файл делаем проверку на время последней генерации имени. Если генерировалось позднее, чем 3 часа назад - генерим новое. Тут вопрос - что, собственно, генерировать? Сам говорю и не знаю.. Переименовывать файл?

пс
красоты ссылки типа http://www.site.com/files/3495_filename.zip
могу достичь и реврайтом, конечо. Главное - иметь из чего "реврайтить" :)

-~{}~ 03.07.05 02:45:

Ещё один вопрос, ответ на который я тоже не знаю:
Мне хотелось бы сделать у себя на сайте:
топ файлов за неделю (по скачиваемости)
за месяц.

Как бы это реализовать? лично я даже не догадываюсь..

-~{}~ 03.07.05 02:56:

по поводу учета статистики скачиваемых файлов за последнюю недлю и месяц... блин уже часа 3 точно только об этом и думаю.. незнаю как реализовать.
 

Yourick

Новичок
каждые три часа переименовывать неправильно
если первый юзер уже качает скажем три с половиной часа, а тут подползает второй, с желанием закачать его же?

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

нащщёт докачек не скажу, не больше твоего опыту в этом вопросе :)
 

Spear

почемучка
Yourick
:( А по поводу Топа есть какие-нить идеи? Ато я, блин, никак не придумаю ничего.. что-то крутится в голове - да не то :(
 

Yourick

Новичок
держать в базе список файлов, и по счётчику каждому. список файлов и директории выдрать не проблема, сравнить с базой и добавит вновь долитые тоже.(скажем появляются новые доступные файлы -- вызывать скрипт обновления базы в админке например специальную кнопку под это завести :) )
а если доунлоад через пхпшку будет итти, что тебе мешает каждый раз по конкретному файлу в базе счётчик инкрементить?
 

Spear

почемучка
Yourick
как-то ты нечитабельно написал. Понял только
>а если доунлоад через пхпшку будет итти, что тебе мешает
> каждый раз по конкретному файлу в базе счётчик
> инкрементить?

отвечаю:
это решит рпоблему лишь статистики ОБЩЕГО КОЛ-ва скачанных файлов..
мне нужно сделать
"ТОП 100 файлов за МЕСЯЦ"
вот в чем проблема
 

Paxan

Новичёк
Как это реализовано везде - ссылка действует в течении 24 часов.
mod_rewrite
 

SelenIT

IT-лунатик :)
>>...по конкретному файлу в базе счётчик
>> инкрементить?

>...решит рпоблему лишь статистики ОБЩЕГО КОЛ-ва скачанных файлов..

???
 

Paxan

Новичёк
Автор оригинала: SelenIT
>>...по конкретному файлу в базе счётчик
>> инкрементить?

>...решит рпоблему лишь статистики ОБЩЕГО КОЛ-ва скачанных файлов..

???
Пациент сам не понимает, что он хочет ;-)
 

Spear

почемучка
SelenIT
если так - то у меня в голове не укладывается как это сделать..
например добавлю в базу файлов ещё такие поля
counter
weekly
monthly

каждый раз при скачивании инкрементить все три..
то потом каждую неделю всем файлам обнулять weekly а каждый месяц - monthly?
А как-то более технично это можно сделать? Просто crontab'a на хостинге нет, а я могу и забыть за какую--то еделю обнулить статистику :(
 

Yourick

Новичок
ок, заведи ManyToMany таблицу с полями датазаливки и ИД файла
 

Spear

почемучка
Paxan
без стеба, пожалуйста :) Пациент понимает что он хочет. Пациент не понимает как выглядит то что он хочет :D

-~{}~ 03.07.05 03:51:

Yourick
я об этом ттоже думал, тгда страктура будет вида:

айди файла / дата заливки (и при каждом скачивании будет добавляться новое поле.

В этом случае я не знаю как вывести "100 самых-самых, где дата между сейчас и 30 дней назад".
То есть вывести просто "последние 100" - два пальца.. об асфальт. а вот 100 самых скачиваемых - не знаю.
 

SelenIT

IT-лунатик :)
select count(*) as cnt from ... where условие_для_даты group by id order by cnt desc
 

Spear

почемучка
например, таблица DownloadStats:

id | date

324 - 01.01.05
324 - 01.01.05
324 - 01.01.05
324 - 01.01.05
184 - 01.01.05
324 - 01.01.05
183 - 01.01.05

тоесть файл 324 скачали (например) в этот день 5 раз, файл 184 и 183 - по 1му разу.. как например вывести самый скачиваемый файл первого января 05 года?

-~{}~ 03.07.05 03:56:

SelenIT
второй вариант. Скачиваний - в день будет около 3-5 тысяч.
 

Yourick

Новичок
Select ID From Files
while($curID = read)
{
Select COUNT(ID) as c From DatesDownloads Where ID= $curID AND Date>=(*Текущая дата минус месяц*)
$arr[$curID]=c;
}
sort($arr);
foreach($arr as $file=> $count)
{
echo "Файл".$file."закачан".$count."раз";
}
 

Spear

почемучка
я просто запутался с запросами в БД, что-ли..

-~{}~ 03.07.05 04:06:

Автор оригинала: Yourick
Select ID From Files
while($curID = read)
{
Select COUNT(ID) as c From DatesDownloads Where ID= $curID AND Date>=(*Текущая дата минус месяц*)
$arr[$curID]=c;
}
sort($arr);
foreach($arr as $file=> $count)
{
echo "Файл".$file."закачан".$count."раз";
}
итого 100 запросов при "топ 100 файлов"? Что-то не то.
 

Yourick

Новичок
селен хороший запрос написал
на моё творение забей, сходу писал.
 

Spear

почемучка
Автор оригинала: SelenIT
select count(*) as cnt from ... where условие_для_даты group by id order by cnt desc
блинн, я тугодум какой-то.блин!
Вообще не могу понять - как этим запросом пользоваться.. он же выведет кол-во скачиваний, то есть нарпимер 5 (если файл Ч был скачал 5 раз)..
а нужно как-то вывести 100 айдишников самый скачиваемых :( помогите, пожалуйста! Тут вся загвоздка :(
 

Yourick

Новичок
таблицы:
files: ID, FileName
files_downloaded: FileID, Date

select count(*) as cnt from files_downloaded where *условие_для_даты* group by FileID order by cnt desc
limit 0,100

select count(*) ... group by FileID -- посчитать количество записей с одним и тем же FileID и так по всем FileID какие токо в этой таблице втсретятся

order by cnt desc -- строки с количеством записий того или иного FileID отсортировать по убывающей.

в итоге тебе будет перечисление количеств записей по каждому FileID за указанный промежуток времени, отсортированный по убывающей.

вроде так, щас некада проверять.
 
Сверху