updated file reader to curl-easy
This commit is contained in:
		
				
					committed by
					
						 Steffen Schröder
						Steffen Schröder
					
				
			
			
				
	
			
			
			
						parent
						
							d1948f4142
						
					
				
				
					commit
					15f0164287
				
			| @@ -1,6 +1,9 @@ | ||||
| <?php | ||||
| namespace ManiaControl\Files; | ||||
|  | ||||
| use cURL\Exception; | ||||
| use cURL\Request; | ||||
| use cURL\Response; | ||||
| use ManiaControl\ManiaControl; | ||||
|  | ||||
| /** | ||||
| @@ -9,21 +12,11 @@ use ManiaControl\ManiaControl; | ||||
|  * @author kremsy & steeffeen | ||||
|  */ | ||||
| class AsynchronousFileReader { | ||||
| 	/** | ||||
| 	 * Constants | ||||
| 	 */ | ||||
| 	const TIMEOUT_ERROR        = 'Timed out while reading data'; | ||||
| 	const RESPONSE_ERROR       = 'Connection or response error'; | ||||
| 	const NO_DATA_ERROR        = 'No data returned'; | ||||
| 	const INVALID_RESULT_ERROR = 'Invalid Result'; | ||||
| 	const SOCKET_TIMEOUT       = 10; | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Private Properties | ||||
| 	 */ | ||||
| 	private $sockets = array(); | ||||
| 	private $maniaControl = null; | ||||
| 	private $requests = array(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Construct | ||||
| @@ -38,141 +31,69 @@ class AsynchronousFileReader { | ||||
| 	 * Appends the Data | ||||
| 	 */ | ||||
| 	public function appendData() { | ||||
| 		foreach($this->sockets as $key => &$socket) { | ||||
| 			/** @var SocketStructure $socket */ | ||||
| 			do { | ||||
| 				$line = fgets($socket->socket, 4096); | ||||
| 				if (empty($socket->header) && $line == "\r\n") { | ||||
| 					$socket->header       = $this->parseHeader($socket->streamBuffer); | ||||
| 					$socket->streamBuffer = ""; | ||||
| 					$line                 = ""; | ||||
| 		foreach($this->requests as $key => $request) { | ||||
| 			/** @var Request $request */ | ||||
| 			try { | ||||
| 				if ($request->socketPerform()) { | ||||
| 					$request->socketSelect(); | ||||
| 				} | ||||
| 				$socket->streamBuffer .= $line; | ||||
|  | ||||
| 				$chunked = isset($socket->header["transfer-encoding"]) && $socket->header["transfer-encoding"] == "chunked" && $line == "0"; | ||||
| 				if ($chunked || isset($socket->header["content-length"]) && strlen($socket->streamBuffer) >= $socket->header["content-length"]) { | ||||
| 					fclose($socket->socket); | ||||
| 					unset($this->sockets[$key]); | ||||
| 					$this->handleContent($socket); | ||||
| 					continue 2; | ||||
| 			} catch(Exception $e) { | ||||
| 				if ($e->getMessage() == "Cannot perform if there are no requests in queue.") { | ||||
| 					unset($this->requests[$key]); | ||||
| 				} else { | ||||
| 					throw $e; | ||||
| 				} | ||||
|  | ||||
| 				$meta = stream_get_meta_data($socket->socket); | ||||
| 			} while($meta["unread_bytes"] > 0); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Handles the Content | ||||
| 	 * | ||||
| 	 * @param $socket | ||||
| 	 */ | ||||
| 	private function handleContent(SocketStructure $socket) { //TODO timeout handling | ||||
| 		//if (feof($socket->socket) || time() > ($socket->creationTime + self::SOCKET_TIMEOUT)) { | ||||
| 		$result = ""; | ||||
| 		$error  = 0; | ||||
| 		/*if (time() > ($socket->creationTime + self::SOCKET_TIMEOUT)) { | ||||
| 			$error = self::TIMEOUT_ERROR; | ||||
| 		} else*/ | ||||
| 		if ($socket->header["status"] != "200") { | ||||
| 			$error  = self::RESPONSE_ERROR; | ||||
| 			$result = $this->parseResult($socket); | ||||
|  | ||||
| 			if (intval($socket->header["status"]) > 300 && intval($socket->header["status"]) < 310) { | ||||
| 				$this->maniaControl->errorHandler->triggerDebugNotice("HTTP Error, Code:" . $socket->header["status"] . "URL: " . $socket->url); | ||||
| 			} | ||||
|  | ||||
| 		} else if ($socket->streamBuffer == '') { | ||||
| 			$error = self::NO_DATA_ERROR; | ||||
| 		} else { | ||||
| 			$result = $this->parseResult($socket); | ||||
| 			if ($result == self::INVALID_RESULT_ERROR) { | ||||
| 				$error = self::INVALID_RESULT_ERROR; | ||||
| 			} | ||||
| 		} | ||||
| 		call_user_func($socket->function, $result, $error); | ||||
| 		//} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Parse the Stream Result | ||||
| 	 * Load a remote file | ||||
| 	 * | ||||
| 	 * @param SocketStructure $socket | ||||
| 	 * @internal param $streamBuffer | ||||
| 	 * @return string | ||||
| 	 * @param string $url | ||||
| 	 * @param        $function | ||||
| 	 * @param string $contentType | ||||
| 	 * @param string $customHeader | ||||
| 	 * @return bool | ||||
| 	 */ | ||||
| 	private function parseResult(SocketStructure $socket) { | ||||
|  | ||||
| 		if (isset($socket->header["transfer-encoding"]) && $socket->header["transfer-encoding"] == "chunked") { | ||||
| 			$result = $this->decode_chunked($socket->streamBuffer); | ||||
| 		} else { | ||||
| 			$result = $socket->streamBuffer; | ||||
| 	public function loadFile($url, $function, $contentType = 'UTF-8', $customHeader = '') { | ||||
| 		if (!is_callable($function)) { | ||||
| 			$this->maniaControl->log("Function is not callable"); | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		return $this->decompressData($socket->header, $result); | ||||
| 	} | ||||
| 		if (!$url) { | ||||
| 			return null; | ||||
| 		} | ||||
|  | ||||
| 	/** | ||||
| 	 * Checks if the data is Compressed and uncompress it | ||||
| 	 * | ||||
| 	 * @param $header | ||||
| 	 * @param $data | ||||
| 	 * @return string | ||||
| 	 */ | ||||
| 	private function decompressData($header, $data) { | ||||
| 		if (isset($header["content-encoding"])) { | ||||
| 			switch($header["content-encoding"]) { | ||||
| 				case "gzip": | ||||
| 				case "gzip;": | ||||
| 					return gzdecode($data); | ||||
| 				case "deflate": | ||||
| 				case "deflate;": | ||||
| 					return gzinflate($data); | ||||
| 		$request = new \cURL\Request($url); | ||||
|  | ||||
| 		$request->getOptions()->set(CURLOPT_TIMEOUT, 5) // | ||||
| 			->set(CURLOPT_HEADER, false) // | ||||
| 			->set(CURLOPT_CRLF, true) // | ||||
| 			//->set(CURLOPT_HTTPHEADER, array("Content-Type: " . $contentType)) | ||||
| 			->set(CURLOPT_USERAGENT, 'User-Agent: ManiaControl v' . ManiaControl::VERSION) // | ||||
| 			->set(CURLOPT_RETURNTRANSFER, true); | ||||
|  | ||||
|  | ||||
| 		$request->addListener('complete', function (\cURL\Event $event) use (&$function) { | ||||
| 			/** @var Response $response */ | ||||
| 			$response = $event->response; | ||||
|  | ||||
| 			$error   = ""; | ||||
| 			$content = ""; | ||||
| 			if ($response->hasError()) { | ||||
| 				$error = $response->getError()->getMessage(); | ||||
| 			} else { | ||||
| 				$content = $response->getContent(); | ||||
| 			} | ||||
| 		} | ||||
| 		return $data; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Decode Chunks | ||||
| 	 * | ||||
| 	 * @param $str | ||||
| 	 * @return string | ||||
| 	 */ | ||||
| 	private function decode_chunked($str) { | ||||
| 		for($res = ''; !empty($str); $str = trim($str)) { | ||||
| 			$pos = strpos($str, "\r\n"); | ||||
| 			$len = hexdec(substr($str, 0, $pos)); | ||||
| 			$res .= substr($str, $pos + 2, $len); | ||||
| 			$str = substr($str, $pos + 2 + $len); | ||||
| 		} | ||||
| 		return $res; | ||||
| 	} | ||||
| 			call_user_func($function, $content, $error); | ||||
| 		}); | ||||
|  | ||||
| 	/** | ||||
| 	 * Parse the Header | ||||
| 	 * | ||||
| 	 * @param $header | ||||
| 	 * @return array | ||||
| 	 */ | ||||
| 	function parseHeader($header) { | ||||
| 		$headers = explode("\r\n", $header); | ||||
| 		$output  = array(); | ||||
| 		array_push($this->requests, $request); | ||||
|  | ||||
| 		if ('HTTP' === substr($headers[0], 0, 4)) { | ||||
| 			list(, $output['status'], $output['status_text']) = explode(' ', $headers[0]); | ||||
| 			unset($headers[0]); | ||||
| 		} | ||||
|  | ||||
| 		foreach($headers as $v) { | ||||
| 			if ($v == "") { | ||||
| 				break; | ||||
| 			} | ||||
| 			$h                         = preg_split('/:\s*/', $v); | ||||
| 			$output[strtolower($h[0])] = $h[1]; | ||||
| 		} | ||||
|  | ||||
| 		return $output; | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @@ -186,7 +107,7 @@ class AsynchronousFileReader { | ||||
| 	 * @return bool|null | ||||
| 	 */ | ||||
| 	public function postData($url, $function, $content, $compressed = false, $contentType = 'UTF-8') { | ||||
| 		if (!is_callable($function)) { | ||||
| 		/*if (!is_callable($function)) { | ||||
| 			$this->maniaControl->log("Function is not callable"); | ||||
| 			return false; | ||||
| 		} | ||||
| @@ -225,57 +146,6 @@ class AsynchronousFileReader { | ||||
| 		$socketStructure = new SocketStructure($url, $socket, $function); | ||||
| 		array_push($this->sockets, $socketStructure); | ||||
|  | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Load a remote file | ||||
| 	 * | ||||
| 	 * @param string $url | ||||
| 	 * @param        $function | ||||
| 	 * @param string $contentType | ||||
| 	 * @param string $customHeader | ||||
| 	 * @return bool | ||||
| 	 */ | ||||
| 	public function loadFile($url, $function, $contentType = 'UTF-8', $customHeader = '') { | ||||
| 		if (!is_callable($function)) { | ||||
| 			$this->maniaControl->log("Function is not callable"); | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		if (!$url) { | ||||
| 			return null; | ||||
| 		} | ||||
| 		$urlData  = parse_url($url); | ||||
| 		$port     = (isset($urlData['port']) ? $urlData['port'] : 80); | ||||
| 		$urlQuery = isset($urlData['query']) ? "?" . $urlData['query'] : ""; | ||||
|  | ||||
| 		$socket = @fsockopen($urlData['host'], $port, $errno, $errstr, 4); | ||||
| 		if (!$socket) { | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		if ($customHeader == '') { | ||||
| 			$query = 'GET ' . $urlData['path'] . $urlQuery . ' HTTP/1.1' . PHP_EOL; | ||||
| 			$query .= 'Host: ' . $urlData['host'] . PHP_EOL; | ||||
| 			$query .= 'Content-Type: ' . $contentType . PHP_EOL; | ||||
| 			$query .= 'Connection: close' . PHP_EOL; | ||||
| 			$query .= 'User-Agent: ManiaControl v' . ManiaControl::VERSION . PHP_EOL; | ||||
| 			$query .= PHP_EOL; | ||||
| 		} else { | ||||
| 			$query = $customHeader; | ||||
| 		} | ||||
|  | ||||
| 		fwrite($socket, $query); | ||||
|  | ||||
| 		$success = stream_set_blocking($socket, 0); | ||||
| 		if (!$success) { | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		$socketStructure = new SocketStructure($url, $socket, $function); | ||||
| 		array_push($this->sockets, $socketStructure); | ||||
|  | ||||
| 		return true; | ||||
| 		return true;*/ | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										15
									
								
								application/core/Libs/Symfony/autoload.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								application/core/Libs/Symfony/autoload.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| <?php | ||||
|  | ||||
| if (!defined('EVENT_DISPATCHER_PATH')) { | ||||
| 	define('EVENT_DISPATCHER_PATH', __DIR__); | ||||
| } | ||||
|  | ||||
|  | ||||
| spl_autoload_register( | ||||
| 	function ($className) { | ||||
| 		$classPath = str_replace('\\', DIRECTORY_SEPARATOR, $className); | ||||
| 		$filePath = EVENT_DISPATCHER_PATH . DIRECTORY_SEPARATOR . $classPath . '.php'; | ||||
| 		if (file_exists($filePath)) { | ||||
| 			require_once $filePath; | ||||
| 		} | ||||
| 	}); | ||||
							
								
								
									
										14
									
								
								application/core/Libs/curl-easy/autoload.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								application/core/Libs/curl-easy/autoload.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| if (!defined('cURL_PATH')) { | ||||
| 	define('cURL_PATH', __DIR__); | ||||
| } | ||||
|  | ||||
| spl_autoload_register( | ||||
| 	function ($className) { | ||||
| 		$classPath = str_replace('\\', DIRECTORY_SEPARATOR, $className); | ||||
| 		$filePath = cURL_PATH . DIRECTORY_SEPARATOR . $classPath . '.php'; | ||||
| 		if (file_exists($filePath)) { | ||||
| 			require_once $filePath; | ||||
| 		} | ||||
| 	}); | ||||
| @@ -26,6 +26,9 @@ use Maniaplanet\DedicatedServer\Xmlrpc\Exception; | ||||
| require_once __DIR__ . '/Libs/Maniaplanet/DedicatedServer/Connection.php'; | ||||
| require_once __DIR__ . '/Libs/GbxDataFetcher/gbxdatafetcher.inc.php'; | ||||
| require_once __DIR__ . '/Libs/FML/autoload.php'; | ||||
| require_once __DIR__ . '/Libs/Symfony/autoload.php'; | ||||
| require_once __DIR__ . '/Libs/curl-easy/autoload.php'; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * ManiaControl Server Controller for ManiaPlanet Server | ||||
|   | ||||
		Reference in New Issue
	
	Block a user