Добрый день! Отдача файлов пользователям осуществляется через PHP-скрипт. Реализована "докачка" файлов по наличию у клиента HTTP_RANGE. Однако HTTP_RANGE отдают только браузеры: Opera и Firefox, Chrome и Яндекс.Браузер повторные запросы на возобновление загрузки отдают без HTTP_RANGE, соответственно загрузка файла начинается заново. Chrome вообще дублирует зачем-то загрузку, оставляя недокаченную старую. Вероятно я делаю что-то не так. Может быть браузеру изначально нужно отдать какие-то специфические заголовки, о том что сервер поддерживает докачку файлов? Код (PHP): $file = './files/' . 'Zhizn.posle.ludei.(01.serija.iz.10).Tela.chto.my.ostavili.2009.XviD.TVRip.avi'; $mime = 'video/x-msvideo'; if (file_exists($file)) { set_time_limit(0); // Неограниченное время выполнение скрипта (для длительных загрузок) ob_end_clean(); // Отключаем буферизацию вывода $fd = fopen($file, 'rb'); // Открываем файл для чтения $file_size = filesize($file); // Определяем размер файла $range = 0; // Если докачка if(isset($_SERVER['HTTP_RANGE'])) { $range = str_replace('bytes=', '', $_SERVER['HTTP_RANGE']); $range = str_replace('-', '', $range); // Убираем лишнее "-" header('Status: 206 Partial Content'); // Частичные данные fseek($fd, $range); // Устанавливаем смещение в читаемом файле } else { header('Status: 200 Ok'); // OK } // HTTP-заголовки //header('Content-Description: File Transfer'); header('Content-Type: ' . $mime); header('Content-Disposition: attachment; filename=' . basename($file)); //header('Content-Transfer-Encoding: binary'); //header('Expires: 0'); //header('Cache-Control: must-revalidate'); //header('Pragma: public'); header('Accept-Ranges: bytes'); // Указываем, что система счисления - байты header('Content-Length: ' . ($file_size - $range)); header('Content-Range: bytes ' . $range . '-' . $file_size . '/' . $file_size); // читаем файл и отправляем его пользователю while (!feof($fd)) { print fread($fd, 1024); // Вывод } fclose($fd); exit; } else { echo 'Файл не найден!'; } P.S: Web-сервер IIS 7.5 PHP, JavaScript, SQL и другой код пишите внутри тегов Код ( (Unknown Language)): [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
а с чего это лишнее? '-' может означать диапазон, или байты отсчитанные с конца. плюс запросы может содержать диапазон. от сих до сих. в общем что браузер запросил то и нужно отдавать. запросы могут быть: Код (Text): bytes=0-499 bytes=500-999 bytes=-500 bytes=9500- bytes=0-0,-1 bytes=500-600,601-999 как видно, могут запрашиваться даже несколько диапазонов. это все нужно корректно парсить и отдавать. иначе браузер видит что вы ему фигню какуюто шлете. плюет. и пытается запросить опять все сначала) хотите сделать нормальную докачку читайте документацию по http_RANGE. если лень - отдавайте файлы nginx-ом, например. он докачку может.
runcore, я знаком с положением о диапазоне(ах) значения Range. На данный момент пока не реализовано. Безусловно будет, но проблема в другом. При первичной отдаче клиенту файла, всё идёт замечательно, Браузеру пока не нужны никакие диапазоны - он скачивает файл целиком с 0 по размер файла. Но, если файл был скачен не до конца, по каким-то причинам загрузка была прервана - скажем половину скачал, а половину нет. Браузер же должен отдать web-серверу этот диапазон. Правильно? С какого по какой качать... В HTTP-заголовке от клиента это выглядит вот так: Код (Text): [Range] => bytes=129450409- и такие браузера как Opera и Firefox успешно предоставляют это значение. А вот Google Chrome и Яндекс.Браузер - НЕТ!!! (не дают они его!) Файл загружен наполовину, а они не говорят об этом. Почему? Я вот этого не понимаю. Откуда сервер знает, что сейчас ему нужно отдать диапазон, если сам клиент об этом молчит? С удовольствием сделал бы всё это на Nginx или Apache, но заказчик настаивает на IIS - хозяин барин.
Потому что это экспериментальная функция. Включается в скрытых настройках. По дефолту неактивна. Телятся с ней, потому что она может представлять дыру в безопасности. Соль в том, что файлик мы качаем с бита по бит. Без предварительной передачи хэша. Можно, в теории, сделать страничку, которая под видом закачки православного файла, устроит прерывание и, при повторном запросе, "докачает" тебе зловреда, к примеру. Проверка, является ли докачанный файл тем, что ты начинал качать, не проводится никак. ЯндексБраузер - это тот же хром, но с перерисованными формочками.
Fell-x27, логично! В общем, провёл несложный эксперимент. Яндекс.браузер докачивал файлы которые отдавались напрямую web-сервером. Но отданные скриптом - нет! Я решил сравнить HTTP-заголовки, которые отдаёт сервер при прямой загрузке, и то что отдаю скриптом я. Вот что из этого получилось. Прямая ссылка сервера: Код (Text): HTTP/1.1 200 OK Content-Length: 524918784 Content-Type: video/x-msvideo Last-Modified: Fri, 16 Jul 2010 20:43:38 GMT Accept-Ranges: bytes ETag: "624f98912725cb1:0" Server: Microsoft-IIS/7.5 Date: Wed, 10 Jun 2015 13:30:24 GMT Ссылка отданная моим скриптом Код (Text): HTTP/1.1 200 Ok Content-Length: 524918784 Content-Type: video/x-msvideo Content-Range: bytes 0-524918784/524918784 Accept-Ranges: bytes Server: Microsoft-IIS/7.5 X-Powered-By: PHP/5.6.9 Content-Disposition: attachment; filename=Zhizn.posle.ludei.(01.serija.iz.10).Tela.chto.my.ostavili.2009.XviD.TVRip.avi Date: Wed, 10 Jun 2015 13:31:08 GMT Первое что мне бросилось в глаза, заголовок: Last-Modified (дата-время изменения файла) Что в общем-то кажется логичным, Яндекс.Браузер молодец, он проверят когда файл был изменён. К такому случаю, когда например файл на сервере был изменён. Вдруг пока пользователь качал файл, его уже изменили на сервере, поэтому он сравнивает дату. Добавил заголовок Last-Modified к скрипту и Яндекс.Браузер стал предоставлять Range-параметр!!! ^^ Но с Хромом, дела обстоят иначе. Данный браузер не докачивает даже прямые ссылки. Что как выяснилось является известной проблемой у него. Если Хром перезапустить, то он уже не продолжит загрузку с места обрыва. Думаю дело в том, что когда браузер закрывается, он автоматически удаляет за собой части недокаченных файлов (наверное так) "сборка мусора"!