Pull to refresh

Множественная загрузка файлов из архива с поддержкой RANGE запросов

Reading time 2 min
Views 1.7K
Иногда бывает полезным не сохранять кучу файлов на каком-либо хостинге, а использовать только один архивный файл. Но возникает проблема доступа к конкретному файлу в архиве. Предлагаю вашему вниманию PHP скрипт, который позволяет загружать часть архивного файла как целый файл. Поддерживается дозагрузка через запросы RANGE. Архив, в данном случае, просто склейка из множества файлов. В настоящий момент скрипт протестирован с менеджером загрузок Flashget.

Для того, чтобы загрузить конкретный файл достаточно указать его смещение в архивном файле, размер и имя этого файла следующим образом:

htp://адрес/имя_скрипта.php?name=filename&offset=3000&size=100

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

Copy Source | Copy HTML
  1. <?php
  2. $offset = isset($_REQUEST['offset']) ? (int) $_REQUEST['offset'] : 0;
  3. $size = isset($_REQUEST['size']) ? (int) $_REQUEST['size'] : false;
  4. $name = isset($_REQUEST['name']) ? urlencode($_REQUEST['name']) : 'download.bin';
  5.  
  6. if (empty($size)) die;
  7.  
  8. // link to archive file
  9. $url = 'http://archive_file_url';
  10.  
  11. @set_time_limit(0);
  12.  
  13. $range_size = $size;
  14. $range_offset = $offset;
  15.  
  16. if (isset($_SERVER['HTTP_RANGE'])) {
  17.     if (preg_match('/^bytes=(\d+)\-$/', $_SERVER['HTTP_RANGE'], $m)) {
  18.         $range_offset+=$m[1];
  19.         $range_size-=$m[1];
  20.     } elseif (preg_match('/^bytes=(\d+)\-(\d+)$/',$_SERVER['HTTP_RANGE'], $m)) {
  21.         $range_offset+=$m[1];
  22.         $range_size=$m[2]-$m[1]+1;
  23.     } else {
  24.       // TODO (aig): support other ranges if needed
  25.         die();
  26.     }
  27.     header('HTTP/1.1 206 Partial Content');
  28. } else {
  29.     header('HTTP/1.1 200 Ok');
  30. }
  31.  
  32. $range = ($range_offset)."-".($range_offset+$range_size-1);
  33. header("Content-Type: application/octet-stream");
  34. header("Accept-Ranges: bytes");
  35. header("Content-Length: $range_size");
  36. header('Content-Disposition: attachment; filename="' . $name . '";');
  37.  
  38. $ch = curl_init();
  39. curl_setopt($ch,CURLOPT_URL,$url);
  40. curl_setopt($ch,CURLOPT_RANGE,$range);
  41. curl_setopt($ch,CURLOPT_RETURNTRANSFER,0);
  42. curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
  43. curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3');
  44. curl_exec($ch);
  45. curl_close($ch);
  46. ?>
  47.  
Tags:
Hubs:
+2
Comments 4
Comments Comments 4

Articles