class eZOwtResumableDownload { ... /*! Downloads data from $url to $localfile This is implemented using the CURL libraries, which are more robust than the built in fopen wrappers. Also it will attempt to resume a previous partial download using ranged GET calls if needed. \return 1 => on success -1 => failed to open output file for writing (permission denied?) -2 => failed to open remote url for reading -3 => failed during write to local file (disk full?) */ function downloadWithCurl() { $localfile = $this->localFileName(); $url = $this->getFullUrl($this->url); if (eZFile::file_exists($localfile)) { // resume $resumePoint = @eZFile::filesize( $localfile); $outputFileHandle = eZFile::fopen( $this->localFileName(), 'ab'); } else { $resumePoint=0; $outputFileHandle = eZFile::fopen( $this->localFileName(), 'wb'); } if (!$outputFileHandle) { return -1; } $this->_curlOutputFileHandle = $outputFileHandle; $ch = curl_init ($url); if (!$ch) { return -2; } if ($resumePoint>=$this->filesize) { $this->logMessage("Previous transfer is complete. No more data to download. Continuing", OWT_MESSAGE_INFO); return 1; } else if ($resumePoint) { $this->logMessage("Resuming previously aborted transfer from byte $resumePoint", OWT_MESSAGE_INFO); curl_setopt($ch, CURLOPT_RESUME_FROM, $resumePoint); } curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 20); // min bytes/sec curl_setopt($ch,CURLOPT_LOW_SPEED_TIME, 500); // in secs curl_setopt($ch,CURLOPT_FAILONERROR,1); curl_setopt($ch,CURLOPT_WRITEFUNCTION, array(&$this, "curlWriteCallback")); $this->_downloadStartStamp=time(); $this->_downloadedBytes=$resumePoint; $success = curl_exec($ch); if (!$success) { $this->logMessage('Transfer failed. Reason: '.curl_error($ch), OWT_MESSAGE_ERROR); return -3; } if ($outputFileHandle) { unset($this->_curlOutputFileHandle); fclose( $outputFileHandle ); } return 1; } ... }