2015-06-12 2 views
5

Я использую следующий код, я адаптировал: http://ee.php.net/manual/en/function.fread.php#84115 к моему коду, чтобы разрешить загрузку резюме, он отлично работает на firefox, но не работает вообще в хроме. Если я пытаюсь выполнить хром, файл загружается, я приостанавливаю его, подождите несколько минут, но затем, когда я его возобновляю, загрузка заканчивается мгновенно, и файл поврежден.PHP скачать резюме в Chrome HTTP RANGE не работает

Любая идея, почему?

function dl_file_resumable($file, $is_resume=TRUE) 
{ 
    //First, see if the file exists 
    if (!is_file($file)) 
    { 
     die("<b>404 File not found!</b>"); 
    } 

    //Gather relevent info about file 
    $size = filesize($file); 
    $fileinfo = pathinfo($file); 

    //workaround for IE filename bug with multiple periods/multiple dots in filename 
    //that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe 
    $filename = (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) ? 
        preg_replace('/\./', '%2e', $fileinfo['basename'], substr_count($fileinfo['basename'], '.') - 1) : 
        $fileinfo['basename']; 

    $file_extension = strtolower($path_info['extension']); 

    $ctype='application/octet-stream'; 

    //check if http_range is sent by browser (or download manager) 
    if($is_resume && isset($_SERVER['HTTP_RANGE'])) 
    { 
     list($size_unit, $range_orig) = explode('=', $_SERVER['HTTP_RANGE'], 2); 

     if ($size_unit == 'bytes') 
     { 
      //multiple ranges could be specified at the same time, but for simplicity only serve the first range 
      //http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt 
      list($range, $extra_ranges) = explode(',', $range_orig, 2); 
     } 
     else 
     { 
      $range = ''; 
     } 
    } 
    else 
    { 
     $range = ''; 
    } 

    //figure out download piece from range (if set) 
    list($seek_start, $seek_end) = explode('-', $range, 2); 

    //set start and end based on range (if set), else set defaults 
    //also check for invalid ranges. 
    $seek_end = (empty($seek_end)) ? ($size - 1) : min(abs(intval($seek_end)),($size - 1)); 
    $seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0); 

    //add headers if resumable 
    if ($is_resume) 
    { 
     //Only send partial content header if downloading a piece of the file (IE workaround) 
     if ($seek_start > 0 || $seek_end < ($size - 1)) 
     { 
      header('HTTP/1.1 206 Partial Content'); 
     } 

     header('Accept-Ranges: bytes'); 
     header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$size); 
    } 

    //headers for IE Bugs (is this necessary?) 
    //header("Cache-Control: cache, must-revalidate"); 
    //header("Pragma: public"); 

    header('Content-Type: ' . $ctype); 
    header('Content-Disposition: attachment; filename="' . $filename . '"'); 
    header('Content-Length: '.($seek_end - $seek_start + 1)); 

    //open the file 
    $fp = fopen($file, 'rb'); 
    //seek to start of missing part 
    fseek($fp, $seek_start); 

    //start buffered download 
    while(!feof($fp)) 
    { 
     //reset time limit for big files 
     set_time_limit(0); 
     print(fread($fp, 1024*8)); 
     flush(); 
     ob_flush(); 
    } 

    fclose($fp); 
    exit; 
} 

dl_file_resumable('/home/var/www/app/back/media/ready/5a58hGuRFR.tar'); 
+0

Не существует [здесь] (http://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file) достаточно примеров того, как это сделать? – yergo

+0

Вы не включили полный скрипт, вы заканчиваете скрипт '?>', Если это возможно? –

+0

Кроме того, какое программное обеспечение веб-сервера вы используете? –

ответ

1

Я не пытался выполнить свой код, но это похоже, что есть некоторая путаница с переключателем заявлением:

  1. Это не имеет никакого смысла - если $ внутр установлен на всех, он будет попадают в один и только по умолчанию раздел
  2. Он имеет неправильный синтаксис - после того, как по умолчанию должно быть :
  3. Он имеет переменную $new_name, который не установлен в любом месте

В конце концов, имея эти ошибки в ответ, разные браузеры будут обрабатывать их по-разному.

+0

Даже больше - я не вижу смысла в инструкции переключателя. – sitilge

+0

Привет, я обновил свой код с полной функцией и некоторыми изменениями, я удалил часть коммутатора для типа контента, потому что хочу принудительно загрузить, поэтому я всегда использую «application/octet-stream». – Mokkun

+0

@Mokkun, значит, это работает для вас? Я пробовал с ~ 180MB zip-файлом, он работает для меня на chrome 43.0.2357.124 m. + Я добавил 'usleep (100);' в конце цикла while (! Feof ($ fp)) 'для имитации скорости сети. Он также работает в Firefox, Opera. IE не позволяет останавливаться (кнопка отключена), но Safari для окон после остановки возобновляет загрузку с начала. – Pilskalns