destination = '/home/' . $data['username'] . '/' . $data['domain']; $url = $data['zip']; @set_time_limit(3600); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ch, CURLOPT_TIMEOUT, 3600); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //curl_setopt($ch, CURLOPT_MAXREDIRS, 3); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'readZip')); $r = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); if ($status != 200) { throw new ErrorException("Zip download error (code: $status)".($error ? ": $error" : '')); } curl_close($ch); if ($this->zipFile) { $this->zipFile->close(); } } protected function readZip($ch, $data) { if (is_file($this->destination.'/index.html')) { rename($this->destination.'/index.html', $this->destination.'/index_backup.html'); } $size = function_exists('mb_strlen') ? mb_strlen($data, '8bit') : strlen($data); $this->zipBuffer .= $data; //self::debugLog("Receive: ".$data); $continue = true; while ($continue) { $continue = false; $size_0 = function_exists('mb_strlen') ? mb_strlen($this->zipBuffer, '8bit') : strlen($this->zipBuffer); if ($this->zipFile && $size_0 >= $this->zipFile->compressedSize) { $continue = true; $this->zipFile->writeUncompressed(substr($this->zipBuffer, 0, $this->zipFile->compressedSize)); $this->zipBuffer = substr($this->zipBuffer, $this->zipFile->compressedSize); $this->zipFile->close(); $this->zipFile = null; } else if (!$this->zipFile && ($fp = strpos($this->zipBuffer, ZipFile::ZIP_FILE_HEAD)) !== false) { $continue = true; $this->zipBuffer = substr($this->zipBuffer, $fp); $hsize = 26 + strlen(ZipFile::ZIP_FILE_HEAD); if (strlen($this->zipBuffer) <= $hsize) { break; } // need more data $name_size_raw = unpack('v', substr($this->zipBuffer, strlen(ZipFile::ZIP_FILE_HEAD) + 22, 2)); $name_size = intval(reset($name_size_raw)); $extra_size_raw = unpack('v', substr($this->zipBuffer, strlen(ZipFile::ZIP_FILE_HEAD) + 24, 2)); $extra_size = intval(reset($extra_size_raw)); $hsize += $name_size + $extra_size; if (strlen($this->zipBuffer) < $hsize) { break; } // need more data // parse file header if ($this->zipFile) { $this->zipFile->close(); } $this->zipFile = ZipFile::parse(substr($this->zipBuffer, 0, $hsize), $this->destination); //self::debugLog('File: '.$this->zipFile->baseDir.'/'.$this->zipFile->name); $this->zipFile->open(); $this->zipBuffer = substr($this->zipBuffer, $hsize); } } return $size; } } class ZipFile { const ZIP_FILE_HEAD = "\x50\x4b\x03\x04"; public $version; public $flags; public $compression; public $modDateTime; public $crc32; public $crc32Raw; public $compressedSize; public $size; public $sizeRaw; public $name; public $extra; public $baseDir; private $handle; public function __construct($baseDir = null) { $this->baseDir = rtrim($baseDir, '/'); $this->modDateTime = date('Y-m-d H:i:s'); $this->compressedSize = 0; $this->size = 0; $this->name = 'new file'; } public function open() { $dir = dirname($this->baseDir.'/'.$this->name); if (!is_dir($dir)) { mkdir($dir, 0755, true); } if (!empty($this->name)) { $this->handle = fopen($this->baseDir.'/'.$this->name, 'w'); } else { throw new ErrorException("File name is empty"); } } public function close() { if ($this->handle !== false) { fclose($this->handle); chmod($this->baseDir.'/'.$this->name, 0644); } } public function write($data) { if ($this->handle !== false) { fwrite($this->handle, $data); } else { throw new ErrorException("File is not open"); } } public function writeUncompressed($data) { $data_u = gzinflate($data); $this->write($data_u); } /** * @param string $data * @return ZipFile */ public static function parse($data, $baseDir = null) { $data = substr($data, strlen(self::ZIP_FILE_HEAD)); $fh = new ZipFile($baseDir); $fh->version = substr($data, 0, 2); $fh->flags = substr($data, 2, 2); $fh->compression = substr($data, 4, 2); $hexdtime_raw = unpack('V', substr($data, 6, 4)); $hexdtime = reset($hexdtime_raw); $fh->modDateTime = ''.((($hexdtime >> 25) & 0xff) + 1980).'-'. sprintf('%02d', ($hexdtime >> 21) & 0x0f).'-'. sprintf('%02d', ($hexdtime >> 16) & 0x1f).' '. sprintf('%02d', ($hexdtime >> 11) & 0x1f).':'. sprintf('%02d', ($hexdtime >> 5) & 0x3f).':'. sprintf('%02d', ($hexdtime << 1) & 0x1f); $fh->crc32Raw = substr($data, 10, 4); $crc32 = unpack('V', $fh->crc32Raw); $fh->crc32 = sprintf('%08x', reset($crc32)); $clen = unpack('V', substr($data, 14, 4)); $fh->compressedSize = reset($clen); $fh->sizeRaw = substr($data, 18, 4); $ulen = unpack('V', $fh->sizeRaw); $fh->size = reset($ulen); $nlen_raw = unpack('v', substr($data, 22, 2)); $nlen = reset($nlen_raw); $elen_raw = unpack('v', substr($data, 24, 2)); $elen = reset($elen_raw); $fh->name = substr($data, 26, $nlen); $fh->extra = substr($data, 26 + $nlen, $elen); return $fh; } }