andre há 7 meses atrás
pai
commit
73532a9e14
3 ficheiros alterados com 175 adições e 14 exclusões
  1. 3 13
      controllers/SiteController.php
  2. 168 0
      controllers/ZipController.php
  3. 4 1
      index.php

+ 3 - 13
controllers/SiteController.php

@@ -3,10 +3,10 @@ namespace application\controllers;
 
 class SiteController {
     public static function init($data): void {
-        $username =  $data['username'];
-        $domain =    $data['domain'];
+        $username =  $data['username'] ?? '';
+        $domain =    $data['domain'] ?? '';
         $adminName = $data['admin_name'] ?? '';
-        $adminPassword = $data['admin_password'];
+        $adminPassword = $data['admin_password'] ?? '';
         $webDir = "/home/$username/$domain";
         $placeholderdir = "/var/www/catchall";
         $configTemplate = '/etc/apache2/site-config.in';
@@ -91,16 +91,6 @@ class SiteController {
         echo json_encode(['success' => 'Development site deployed successfully','details' => '']);
     }
 
-    public static function deploy($data): void  {
-        $domain = $data['domain'] ?? '';
-        error_log("deploy: DEBUG: " . print_r($data, true));
-        if (empty($domain)) {
-            http_response_code(400);
-            echo json_encode(['error' => 'Missing required parameter: domainname']);
-            return;
-        }
-    }
-
     public static function revert($data): void {
         $username = $data['username'] ?? '';
         $domain = $data['domain'] ?? '';

+ 168 - 0
controllers/ZipController.php

@@ -0,0 +1,168 @@
+<?php
+namespace application\controllers;
+
+class ZipController {
+	
+	/** @var ZipFile */
+	private $zipFile = null;
+	private $zipBuffer = "";
+	private $destination = null;
+	
+	public function extractZip($data) {
+		$this->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;
+	}
+	
+}

+ 4 - 1
index.php

@@ -18,12 +18,14 @@ require_once __DIR__ . '/controllers/GetSSLDaysController.php';
 require_once __DIR__ . '/controllers/QuotaController.php';
 require_once __DIR__ . '/controllers/AccountController.php';
 require_once __DIR__ . '/controllers/SiteController.php';
+require_once __DIR__ . '/controllers/ZipController.php';
 
 use application\controllers\BackupController;
 use application\controllers\AccountController;
 use application\controllers\GetSSLDaysController;
 use application\controllers\QuotaController;
 use application\controllers\SiteController;
+use application\controllers\ZipController;
 
 const API_PASSWORD = 'your-secure-password';
 
@@ -94,7 +96,8 @@ switch ($endpoint) {
             $id = md5($domain.time());
             header('Content-Type: application/json; charset=utf-8', true);
             echo json_encode(array('result' => array('id' => $id, 'error' => $error)));
-            SiteController::deploy(['zip' => $_POST['zip'], 'username' => $username, 'domain' => $domain]);
+            $deployment = new ZipController();
+            $deployment->extractZip(['zip' => $_POST['zip'], 'usrname' => $username, 'domain' => $domain]);
         }
         if ($requestMethod == 'GET' && !empty($username) && !empty($domain)) {
             if ($GLOBALS['debug'] == true) {