Отдача файлов PHP скриптом

OFF-NO

Новичок
Отдача файлов PHP скриптом

Доброе время суток!
Хотелось бы услышать знатоков которые реализовывали систему отдачи файлов не посредственно скриптом.
В общем нужно реализовать систему загрузки файлов которая не даст запалить реальный урл к файлу + проверка по IP (уникальная ссылка - md5("ip адрес")).
Пример ссылки: http://site.ru/download/f528764d624db129b32c21fbca0cb8d6/18/13718.rar.
Наткнулся на готовый пример, идея хорошая:



PHP:
function downloadFile($filename,$realname,$mimetype='application/octet-stream') {
    if (!file_exists($filename)) die('Файл не найден');

    $from=$to=0; $cr=NULL;

    if (isset($_SERVER['HTTP_RANGE'])) {
        $range=substr($_SERVER['HTTP_RANGE'], strpos($_SERVER['HTTP_RANGE'], '=')+1);
        $from=strtok($range, '-');
        $to=strtok('/'); if ($to>0) $to++;
        if ($to) $to-=$from;
        header('HTTP/1.1 206 Partial Content');
        $cr='Content-Range: bytes ' . $from . '-' . (($to)?($to . '/' . $to+1):filesize($filename));
    } else    header('HTTP/1.1 200 Ok');

    $etag=md5($filename);
    $etag=substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);
    header('ETag: "' . $etag . '"');

    header('Accept-Ranges: bytes');
    header('Content-Length: ' . (filesize($filename)-$to+$from));
    if ($cr) header($cr);

    header('Connection: close');
    header('Content-Type: ' . $mimetype);
    header('Last-Modified: ' . gmdate('r', filemtime($filename)));
    $f=fopen($filename, 'r');
    header('Content-Disposition: attachment; filename="' . basename($realname) . '";');
        
    if ($from) fseek($f, $from, SEEK_SET);
    if (!isset($to) or empty($to)) {
        $size=filesize($filename)-$from;
    } else {
        $size=$to;
    }
    $downloaded=0;
    while(!feof($f) and !connection_status() and ($downloaded<$size)) {
        echo fread($f, 512000);
        $downloaded+=512000;
        flush();
    }
        
    fclose($f);
}
Почитал материалы, коменты пишут что сервак упадет.

------------------------------------------------------
Ну для начала я думаю можно попробовать сделать так:

$filename="88112.rar";
header("content-type: application/octet-stream");
readfile($filename);

Будет ли грузить данный пример сервак? А если добавить докачку ?
 

AmdY

Пью пиво
Команда форума
не нужно отдавать статику php скриптом, сто раз обсуждались другие пути с nginx или модулей апача
 

OFF-NO

Новичок
а как следует отдавать статику? если нужно чтоб ссылка генерилась методом md5("ip adress") ???
 

AmdY

Пью пиво
Команда форума
тебе нужно ссылку генерить или настроить отдачу определённому пользователю?
 

OFF-NO

Новичок
хочу узнать как правильнее сделать отдачу? тем самым каждому пользователю давать уникальную ссылку для него на один и тотже файл. nginx - читал статейку но в статье тоже отдаеться файл скриптом. http://mirtesen.ru/groups/30866308277/blog/43343178586 - вот статья.

AmdY - сказал что ненужно отдавать статику скриптом, а как же нужно?
 

dimagolov

Новичок
читал статейку но в статье тоже отдаеться файл скриптом. http://mirtesen.ru/groups/30866308277/blog/43343178586 - вот статья.
hearing without listening :(

читать мало, надо понять, что в ней написано.
 

OFF-NO

Новичок
SiMM
спасибо! Все понял, все получилось. По методу кук....
Теперь ктонить меня направит на правильный путь чтоб сделать отдачу файла например таким образом.
http://site.ru/download/f528764d624db129b32c21fbca0cb8d6/18/file/13718.rar.
Вообщем сча опишу работу...
Пользователь заходит на сайт где генерится ссылка для него, строка f528764d624db129b32c21fbca0cb8d6 кладется в определенную папку на серваке. Методом mod_rewrite проверяем есть ли файл с названием f528764d624db129b32c21fbca0cb8d6, если его нет то отправляем пользователя отдыхать. если есть то нужно отдать ему файл.
Сам файл будет лежать так http://site.ru/download/18/file/13718.rar.

Вопрос: Как отдать файл?
-------------------------------
Реализовал через куку. Т.е. также генерится кука, кладется файл в папку и через хитакес проверяем наличие файла, если есть то файл отдаем если нет то отправляем в тумбочку.
Метод хорош и работает т.к. ссылка выгледит http://site.ru/download/18/file/13718.rar. и через хитакис вся проверка, если все ок то файл отдается как обычно.
 

SiMM

Новичок
Точно так же. Передавать идентификатор загрузки в куке или в URI - большого значения не имеет.
 

SiMM

Новичок
> имеет, если ссылка http://site.ru/download/f528764d624...file/13718.rar. то выдает 404 ошибку (файла нет)
Потому что правило писать для mod_rewrite кто будет? Какая разница, для кук оно или для запроса - сути это не меняет.
 

cDLEON

Онанист РНРСlub
Почитал материалы, коменты пишут что сервак упадет.
Сервак упадёт только в том случае, если над апачем будет висеть ещё один веб-сервер вроде nginx.
А так он ни хера падать не будет. Другое дело если активных закачек будет много. А это на каждый поток по процессу.
Но разница не существенная (имхо) от той, когда апач сам эту статику отдаёт.
 

OFF-NO

Новичок
Автор оригинала: SiMM
> имеет, если ссылка http://site.ru/download/f528764d624...file/13718.rar. то выдает 404 ошибку (файла нет)
Потому что правило писать для mod_rewrite кто будет? Какая разница, для кук оно или для запроса - сути это не меняет.
Разница в том что когда делаешь через куки то ссылка актуальная http://site.ru/download/file/13718.rar.
А когда в ссылку добавляем md5() (пример f528764d624)- как директорию которой нет, то сервак возвращает 404 ошибку,и правильно т.к. нет директории f528764d624, значит не файла - пример ссылки: http://site.ru/download/f528764d624...file/13718.rar.

cDLEON
Ты предлагаешь использовать скрипт который дан в ТС выше?
 

fixxxer

К.О.
Партнер клуба
Автор оригинала: cDLEON
Сервак упадёт только в том случае, если над апачем будет висеть ещё один веб-сервер вроде nginx.
интересное мнение... аргументируй
 

cDLEON

Онанист РНРСlub
fixxxer
Ммм...Ещё забыл добавить, что ПыхПых должен стоять как модуль. (Как цги\фаст-цги не пробывал)
Я проводил тесты. После того, как у апача в буфере появляется 10кб-1мб(вроде бы...давно это было...) данных, пых вместе с скриптом засыпает, пока апач не отдаст этот кусок и не потребует ещё.
А в случае с проксированием данных, НГИНКС (пытаясь сделать во благо - убрать лишний апачевый процесс) кушает всё, что апач ему спихивает - в итоге - свап 8)
OFF-NO

Ты предлагаешь использовать скрипт который дан в ТС выше?
У меня написан похожий...Только там ещё контролирование количества потоков имеется. Скрипт этот стоит на довольно посещаемом сайте, на котором продаются фильмы...Так вот - сервер не ложится :)
 

fixxxer

К.О.
Партнер клуба
может быть, просто надо было настроить proxy buffers?

хотя конечно если отдавать большие файлы скриптом большому кол-ву пользователей - это тут ничего не поможет, тут действительно толку от фронтенда мало =) Только зачем, если есть X-Accel-* ?
 

cDLEON

Онанист РНРСlub
ожет быть, просто надо было настроить proxy buffers?
Может быть. Я в пчеле не рылся практически )
Только один хрен тут уже будет уже два буфера с данными и
толку от фронтенда мало =)
Только зачем, если есть X-Accel-* ?
Этот редирект не подходит тогда, когда требуется больший контроль за отдачей файла. Тобишь когда нужно знать сколько данных отдано :)
или для апача X-SendFile
А какой от него смысл когда пыхпых как модуль?
 

fixxxer

К.О.
Партнер клуба
>>Тобишь когда нужно знать сколько данных отдано

можно для этого локейшена сделать отдельный access log и его парсить
 
Сверху