2015-06-12 14 views
5

Sto usando il seguente codice, ho adattato: http://ee.php.net/manual/en/function.fread.php#84115 al mio codice per consentire il ripristino del download, funziona perfettamente su Firefox ma non funziona affatto in chrome. Se provo in chrome, il file viene scaricato, lo metto in pausa, attendo alcuni minuti, ma poi quando lo riprendo il download termina immediatamente e il file è corrotto.Ripr. Download PHP in Chrome RANGE HTTP non funzionante

Qualche idea del perché?

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

Non è [qui] (http://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file) sufficienti esempi di come fare questo? – yergo

+0

Non hai incluso lo script completo, stai terminando lo script con un '?>' Per caso? –

+0

Inoltre, quale software del server web stai usando? –

risposta

1

non ho provato eseguire il codice, ma sembra che ci sia una certa confusione con istruzione switch:

  1. Non ha alcun significato - se $ ext è impostata a tutti, lo farà cadere in uno e solo di default sezione
  2. ha sintassi sbagliata - dopo di default dovrebbe essere :
  3. ha variabile $new_name che non è impostata nessuna parte

Alla fine, avendo questi errori in risposta, diversi browser li gestiranno in modo diverso.

+0

Ancora di più - Non vedo alcun senso nella dichiarazione dell'interruttore di sorta. – sitilge

+0

Ciao, ho aggiornato il mio codice con la funzione completa e alcune modifiche, ho rimosso la parte dello switch per il tipo di contenuto perché voglio forzare il download, quindi uso sempre "application/octet-stream". – Mokkun

+0

@Mokkun, quindi significa che funziona per voi? Ho provato con un file zip da ~ 180MB, funziona per me su Chrome 43.0.2357.124 m. + Ho aggiunto 'usleep (100);' alla fine di 'while (! Feof ($ fp))' ciclo per simulare la velocità della rete. Funziona anche su Firefox, Opera. IE non consente l'arresto (pulsante disattivato), ma Safari per Windows dopo l'interruzione riprende il download dall'inizio. – Pilskalns