2009-12-12 10 views
12

En primer lugar, soy consciente de que se ha formulado una pregunta similar anteriormente.PHP Uso de archivos remotos con Resume Support

El tema se explica más o menos la pregunta, pero aún así,

el archivo está alojado en otro servidor, el usuario deberá descargar archivos a través de mi guión, transmite a él ...

Pero el problema es de usuario no se puede reanudar una vez que se detuvo ... alguna solución?

Respuesta

1

Si está utilizando PHP para servir el archivo, tiene que implementar toda la lógica de reanudación usted mismo.

Deberás enviar Accept-Ranges y respond appropriately al Ranges.

Eso es un pedazo de trabajo. Puede ser más fácil usar mod_proxy.

1

¿Cuál es el propósito de esto? ¿solo se ocultan urls o simplemente se permite que los miembros descarguen?

La forma en que lo describió, que es un poco complicado ...

  1. El servidor remoto la secuencia de comandos se descargará desde deberían apoyar reanudar descargas.
  2. Su script php debe verificar si el encabezado 'Aceptar rango' & pasarlo al servidor remoto (usar sockets es su mejor opción, supongo) para que su script actúe realmente como un proxy.
17

Usted puede tratar de implementar su propio script descarga usando Accept-Ranges y Content-Range aquí es una prof de concepto:

set_time_limit(0); 
$download = new ResumeDownload("word.dir.txt", 50000); //delay about in microsecs 
$download->process(); 

El uso de Internet Download Manager

inicio

Start

una pausa

Paused

estado de pausa

Paused State

Reanudar

Resume

Terminado

enter image description here

clase utilizada

class ResumeDownload { 
    private $file; 
    private $name; 
    private $boundary; 
    private $delay = 0; 
    private $size = 0; 

    function __construct($file, $delay = 0) { 
     if (! is_file($file)) { 
      header("HTTP/1.1 400 Invalid Request"); 
      die("<h3>File Not Found</h3>"); 
     } 

     $this->size = filesize($file); 
     $this->file = fopen($file, "r"); 
     $this->boundary = md5($file); 
     $this->delay = $delay; 
     $this->name = basename($file); 
    } 

    public function process() { 
     $ranges = NULL; 
     $t = 0; 
     if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_SERVER['HTTP_RANGE']) && $range = stristr(trim($_SERVER['HTTP_RANGE']), 'bytes=')) { 
      $range = substr($range, 6); 
      $ranges = explode(',', $range); 
      $t = count($ranges); 
     } 

     header("Accept-Ranges: bytes"); 
     header("Content-Type: application/octet-stream"); 
     header("Content-Transfer-Encoding: binary"); 
     header(sprintf('Content-Disposition: attachment; filename="%s"', $this->name)); 

     if ($t > 0) { 
      header("HTTP/1.1 206 Partial content"); 
      $t === 1 ? $this->pushSingle($range) : $this->pushMulti($ranges); 
     } else { 
      header("Content-Length: " . $this->size); 
      $this->readFile(); 
     } 

     flush(); 
    } 

    private function pushSingle($range) { 
     $start = $end = 0; 
     $this->getRange($range, $start, $end); 
     header("Content-Length: " . ($end - $start + 1)); 
     header(sprintf("Content-Range: bytes %d-%d/%d", $start, $end, $this->size)); 
     fseek($this->file, $start); 
     $this->readBuffer($end - $start + 1); 
     $this->readFile(); 
    } 

    private function pushMulti($ranges) { 
     $length = $start = $end = 0; 
     $output = ""; 

     $tl = "Content-type: application/octet-stream\r\n"; 
     $formatRange = "Content-range: bytes %d-%d/%d\r\n\r\n"; 

     foreach ($ranges as $range) { 
      $this->getRange($range, $start, $end); 
      $length += strlen("\r\n--$this->boundary\r\n"); 
      $length += strlen($tl); 
      $length += strlen(sprintf($formatRange, $start, $end, $this->size)); 
      $length += $end - $start + 1; 
     } 
     $length += strlen("\r\n--$this->boundary--\r\n"); 
     header("Content-Length: $length"); 
     header("Content-Type: multipart/x-byteranges; boundary=$this->boundary"); 
     foreach ($ranges as $range) { 
      $this->getRange($range, $start, $end); 
      echo "\r\n--$this->boundary\r\n"; 
      echo $tl; 
      echo sprintf($formatRange, $start, $end, $this->size); 
      fseek($this->file, $start); 
      $this->readBuffer($end - $start + 1); 
     } 
     echo "\r\n--$this->boundary--\r\n"; 
    } 

    private function getRange($range, &$start, &$end) { 
     list($start, $end) = explode('-', $range); 

     $fileSize = $this->size; 
     if ($start == '') { 
      $tmp = $end; 
      $end = $fileSize - 1; 
      $start = $fileSize - $tmp; 
      if ($start < 0) 
       $start = 0; 
     } else { 
      if ($end == '' || $end > $fileSize - 1) 
       $end = $fileSize - 1; 
     } 

     if ($start > $end) { 
      header("Status: 416 Requested range not satisfiable"); 
      header("Content-Range: */" . $fileSize); 
      exit(); 
     } 

     return array(
       $start, 
       $end 
     ); 
    } 

    private function readFile() { 
     while (! feof($this->file)) { 
      echo fgets($this->file); 
      flush(); 
      usleep($this->delay); 
     } 
    } 

    private function readBuffer($bytes, $size = 1024) { 
     $bytesLeft = $bytes; 
     while ($bytesLeft > 0 && ! feof($this->file)) { 
      $bytesLeft > $size ? $bytesRead = $size : $bytesRead = $bytesLeft; 
      $bytesLeft -= $bytesRead; 
      echo fread($this->file, $bytesRead); 
      flush(); 
      usleep($this->delay); 
     } 
    } 
} 

File Used

+0

Gracias! Me ayudaste mucho !!! – HtmHell

+0

De nada :) – Baba

+0

realy greate job 1+ –

Cuestiones relacionadas