title: Download remote file straight to client?
body: <p>I need download remote file straight to client. After some googling, I found this script in the php manual but its resume capability does not work. This script uses <code>Http_Range</code> to generate  a resumable download link. Is there any other method to do this? Of course, it would be by using <code>cUrl</code> but I need download remote file straight to client. How can i resolve this problem?</p>
  
  <pre><code>&lt;?php          
  $url="http://dl.remote-domain.com/files/file.mp4";
  dl_file_resumable($url);
  
  function dl_file_resumable($file, $is_resume=TRUE)
  {
  
  
      //Gather relevent info about file
      $size = remotefilesize($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']);
  
      //This will set the Content-Type to the appropriate setting for the file
      switch($file_extension)
      {
          case 'exe': $ctype='application/octet-stream'; break;
          case 'zip': $ctype='application/zip'; break;
          case 'mp3': $ctype='audio/mpeg'; break;
          case 'mpg': $ctype='video/mpeg'; break;
          case 'avi': $ctype='video/x-msvideo'; break;
          default:    $ctype='application/force-download';
      }
  
      //check if http_range is sent by browser (or download manager)
      if($is_resume &amp;&amp; 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 &lt; 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 &gt; 0 || $seek_end &lt; ($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;
  }
  
  function remotefilesize($url, $user = "", $pw = "")
  {
      ob_start();
      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_HEADER, 1);
      curl_setopt($ch, CURLOPT_NOBODY, 1);
  
      if(!empty($user) &amp;&amp; !empty($pw))
      {
          $headers = array('Authorization: Basic ' .  base64_encode("$user:$pw"));
          curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      }
  
      $ok = curl_exec($ch);
      curl_close($ch);
      $head = ob_get_contents();
      ob_end_clean();
  
      $regex = '/Content-Length:\s([0-9].+?)\s/';
      $count = preg_match($regex, $head, $matches);
  
      return isset($matches[1]) ? $matches[1] : "unknown";
  }
  ?&gt;
  </code></pre>