Jelajahi Sumber

use HTTP exceptions/error codes

Piotr Labudda 11 tahun lalu
induk
melakukan
c102f622f3
6 mengubah file dengan 141 tambahan dan 37 penghapusan
  1. 2 0
      SE/index-ajax.php
  2. 18 14
      SE/index-file.php
  3. 2 0
      SE/index.php
  4. 86 0
      SE/se-lib/Http.php
  5. 5 0
      SE/se-lib/HttpException.php
  6. 28 23
      SE/se-lib/TableAjax.php

+ 2 - 0
SE/index-ajax.php

@@ -33,6 +33,8 @@ require_once APP_PATH_LIB . '/' . 'Lib.php';
 Lib::loadClass('V');
 Lib::loadClass('DB');
 Lib::loadClass('User');
+Lib::loadClass('Http');
+Lib::loadClass('HttpException');
 
 if (!User::logged()) {
 	die('NotAuthenticated');

+ 18 - 14
SE/index-file.php

@@ -34,8 +34,13 @@ Lib::loadClass('V');
 Lib::loadClass('DB');
 Lib::loadClass('User');
 Lib::loadClass('S');
+Lib::loadClass('Http');
+Lib::loadClass('HttpException');
 
-User::auth();// die if not logged in
+if (!User::logged()) {
+	Http::sendHeaderByCode(401);
+	exit;
+}
 
 /* example:
     [zasobID] => 636
@@ -48,25 +53,25 @@ $recordID = V::get('id', 0, $_GET, 'int');
 $fileName = V::get('file', '', $_GET);
 
 if (!$zasobID || !$recordID || empty($fileName)) {
-	header('HTTP/1.0 406 Not Acceptable');
+	Http::sendHeaderByCode(406);
 	exit;
 }
 if (false !== strpos($fileName, '../')) {
-	header('HTTP/1.0 403 Forbidden');
-	echo '..';
-	exit;
+	Http::sendHeaderByCode(403);
+	die('..');
 }
 
 $userAcl = User::getAcl();
 $tblAcl = $userAcl->getTableAcl($zasobID);
 
 if (!$tblAcl->isInitialized()) {
-	echo'<p class="red">'."Brak konfiguracji dla ".$tblAcl->getName()."!".'</p>';
-	return;
+	Http::sendHeaderByCode(404);
+	die("Brak konfiguracji dla ".$tblAcl->getName()."!");
 }
 
 Lib::loadClass('TableAjax');
 if (!class_exists('TableAjax')) {
+	Http::sendHeaderByCode(404);
 	die('Error: cls not exists TableAjax');
 }
 
@@ -74,13 +79,12 @@ $tblObj = new TableAjax($tblAcl);
 try {
 	$tblObj->sendFileContent($recordID, $fileName);
 }
-catch (Exception $e) {
-	switch ($e->getCode()) {
-		case 404: header('HTTP/1.0 404 Not Found'); break;
-		case 403: header('HTTP/1.0 403 Forbidden'); break;
-		case 4033: header('HTTP/1.0 403.3 - Write access forbidden'); break;
-		default:
-	}
+catch (HttpException $e) {
+	Http::sendHeaderByCode($e->getCode());
 	header('Content-Type: text/html; charset=utf-8');
 	echo $e->getMessage();
 }
+catch (Exception $e) {
+	header('Content-Type: text/html; charset=utf-8');
+	echo 'Error ' . $e->getCode() . ':' . $e->getMessage();
+}

+ 2 - 0
SE/index.php

@@ -36,6 +36,8 @@ Lib::loadClass('DB');
 Lib::loadClass('User');
 Lib::loadClass('SE_Layout');
 Lib::loadClass('S');
+Lib::loadClass('Http');
+Lib::loadClass('HttpException');
 
 S::init();// init session variables if not exists
 User::auth();// die if not logged in

+ 86 - 0
SE/se-lib/Http.php

@@ -0,0 +1,86 @@
+<?php
+
+Lib::loadClass('HttpException');
+
+/**
+ * Http::sendHeaderByCode(404) -> header('HTTP/1.0 404 Not Found');
+ */
+class Http {
+
+	public static $statusTexts = array(
+		100 => 'Continue',
+		101 => 'Switching Protocols',
+		102 => 'Processing',
+		200 => 'OK',
+		201 => 'Created',
+		202 => 'Accepted',
+		203 => 'Non-Authoritative Information',
+		204 => 'No Content',
+		205 => 'Reset Content',
+		206 => 'Partial Content',
+		207 => 'Multi-Status',
+		208 => 'Already Reported',
+		226 => 'IM Used',
+		300 => 'Multiple Choices',
+		301 => 'Moved Permanently',
+		302 => 'Found',
+		303 => 'See Other',
+		304 => 'Not Modified',
+		305 => 'Use Proxy',
+		306 => 'Reserved',
+		307 => 'Temporary Redirect',
+		308 => 'Permanent Redirect',
+		400 => 'Bad Request',
+		401 => 'Unauthorized',
+		402 => 'Payment Required',
+		403 => 'Forbidden',
+		404 => 'Not Found',
+		405 => 'Method Not Allowed',
+		406 => 'Not Acceptable',
+		407 => 'Proxy Authentication Required',
+		408 => 'Request Timeout',
+		409 => 'Conflict',
+		410 => 'Gone',
+		411 => 'Length Required',
+		412 => 'Precondition Failed',
+		413 => 'Request Entity Too Large',
+		414 => 'Request-URI Too Long',
+		415 => 'Unsupported Media Type',
+		416 => 'Requested Range Not Satisfiable',
+		417 => 'Expectation Failed',
+		418 => 'I\'m a teapot',
+		422 => 'Unprocessable Entity',
+		423 => 'Locked',
+		424 => 'Failed Dependency',
+		425 => 'Reserved for WebDAV advanced collections expired proposal',
+		426 => 'Upgrade Required',
+		428 => 'Precondition Required',
+		429 => 'Too Many Requests',
+		431 => 'Request Header Fields Too Large',
+		500 => 'Internal Server Error',
+		501 => 'Not Implemented',
+		502 => 'Bad Gateway',
+		503 => 'Service Unavailable',
+		504 => 'Gateway Timeout',
+		505 => 'HTTP Version Not Supported',
+		506 => 'Variant Also Negotiates (Experimental)',
+		507 => 'Insufficient Storage',
+		508 => 'Loop Detected',
+		510 => 'Not Extended',
+		511 => 'Network Authentication Required'
+	);
+
+	/**
+	 * @param $code
+	 * 
+	 * examples:
+	 *   404 -> HTTP/1.0 404 Not Found
+	 *   403 -> HTTP/1.0 403 Forbidden
+	 */
+	public static function sendHeaderByCode($code) {
+		if (array_key_exists($code, self::$statusTexts)) {
+			header("HTTP/1.0 {$code} " . self::$statusTexts[$code]);
+		}
+	}
+
+}

+ 5 - 0
SE/se-lib/HttpException.php

@@ -0,0 +1,5 @@
+<?php
+
+class HttpException extends Exception {
+
+}

+ 28 - 23
SE/se-lib/TableAjax.php

@@ -4688,14 +4688,14 @@ jQuery(document).ready(function(){
 		$db = DB::getDB();
 		$record = $db->get_by_id($tblName, $id);
 		if (!$this->_acl->canWriteRecord($record) && !$this->_acl->hasPermSuperWrite()) {
-			header('HTTP/1.0 403.3 - Write access forbidden');
+			header('HTTP/1.0 403 Forbidden');
 			echo "Brak dostępu do rekordu";
 			exit;
 		}
 
 		$theGeomFieldId = $this->_acl->getFieldIdByName($geomFieldName);
 		if (!$this->_acl->isAllowed($theGeomFieldId, 'W', $record)) {
-			header('HTTP/1.0 403.3 - Write access forbidden');
+			header('HTTP/1.0 403 Forbidden');
 			echo "Brak dostępu do zapisu dla pola {$geomFieldName}";
 			exit;
 		}
@@ -4733,6 +4733,14 @@ jQuery(document).ready(function(){
 		try {
 			$response = $this->{$method}($args);
 		}
+		catch (HttpException $e) {
+			$response = new stdClass();
+			$response->type = 'error';
+			$response->msg = $e->getMessage();
+			$response->errorCode = $e->getCode();
+
+			Http::sendHeaderByCode($e->getCode());
+		}
 		catch (Exception $e) {
 			$response = new stdClass();
 			$response->type = 'error';
@@ -4740,12 +4748,6 @@ jQuery(document).ready(function(){
 			$response->errorCode = $e->getCode();
 		}
 
-		switch ($response->errorCode) {
-			case 404: header('HTTP/1.0 404 Not Found'); break;
-			case 403: header('HTTP/1.0 403 Forbidden'); break;
-			case 4033: header('HTTP/1.0 403.3 - Write access forbidden'); break;
-			default:
-		}
 		header('Content-type: application/json');
 		echo json_encode($response);
 		exit;
@@ -4757,22 +4759,22 @@ jQuery(document).ready(function(){
 		$response = new stdClass();
 
 		if ($id <= 0) {
-			throw new Exception("Wrong param ID", 404);
+			throw new HttpException("Wrong param ID", 404);
 		}
 
 		$tblName = $this->_acl->getName();
 
 		$record = $this->_dataSource->getItem($id);
 		if (!$record) {
-			throw new Exception("Nie odnaleziono rekordu nr {$id}", 404);
+			throw new HttpException("Nie odnaleziono rekordu nr {$id}", 404);
 		}
 		if (!$this->_acl->canWriteRecord($record) && !$this->_acl->hasPermSuperWrite()) {
-			throw new Exception("Brak dostępu do rekordu nr {$id}", 403);
+			throw new HttpException("Brak dostępu do rekordu nr {$id}", 403);
 		}
 
 		$theGeomFieldId = $this->_acl->getFieldIdByName($geomFieldName);
 		if (!$this->_acl->isAllowed($theGeomFieldId, 'W', $record)) {
-			throw new Exception("Brak dostępu do zapisu dla pola {$geomFieldName}", 403);
+			throw new HttpException("Brak dostępu do zapisu dla pola {$geomFieldName}", 403);
 		}
 
 		if (empty($record->{$geomFieldName})) {
@@ -4804,23 +4806,22 @@ jQuery(document).ready(function(){
 		return $response;
 	}
 
-	// TODO: check read access
 	public function sendFileContent($id, $fileName) {
 		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
 
 		$dbID = $this->_acl->getDB();
 		$db = DB::getDB($dbID);
 		if (!$db) {
-			throw new Exception('No DB', 406);
+			throw new HttpException('No DB', 406);
 		}
 
 		$record = $this->_dataSource->getItem($id);
 		if (!$record) {
-			throw new Exception("No item ID({$rowID})", 404);
+			throw new HttpException("No item ID({$rowID})", 404);
 		}
 
-		if (!$this->_acl->canReadRecord($record)) {
-			throw new Exception("Brak dostępu do rekordu", 406);
+		if (!$this->_acl->canReadRecord($record)) {// TODO: Write, Super Write?
+			throw new HttpException("Brak dostępu do rekordu", 406);
 		}
 
 		$tblName = $this->_acl->getName();
@@ -4828,7 +4829,7 @@ jQuery(document).ready(function(){
 		Lib::loadClass('FoldersConfig');
 		$folderConfAll = FoldersConfig::getRawData();
 		if (!FoldersConfig::hasConfig($confTblName)) {
-			throw new Exception("Brak danych konfiguracyjnych", 404);
+			throw new HttpException("Brak danych konfiguracyjnych", 404);
 		}
 
 		$folderConf = FoldersConfig::getAll($confTblName);
@@ -4838,7 +4839,7 @@ jQuery(document).ready(function(){
 		$uploader = new FileUploader($confTblName, $record);
 		$errMsg = '';
 		if (!$uploader->setConfig($folderConf, $errMsg)) {
-			throw new Exception("Błąd danych konfiguracyjnych ({$tblName})\n". $errMsg, 404);
+			throw new HttpException("Błąd danych konfiguracyjnych ({$tblName})\n". $errMsg, 404);
 		}
 		$uploader->findFolder();
 		if($DBG){ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">uploader (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($uploader);echo'</pre>'; }
@@ -4849,7 +4850,7 @@ jQuery(document).ready(function(){
 		$localPath = $uploader->getLocalPath();
 		$filePath = "{$localPath}/{$mainFolder}/{$fileName}";
 		if (!file_exists($filePath)) {
-			throw new Exception("Plik nie istnieje", 404);
+			throw new HttpException("Plik nie istnieje", 404);
 		}
 
 		if (function_exists('http_send_file')) {
@@ -4865,12 +4866,16 @@ jQuery(document).ready(function(){
 			header('Content-Length: ' . filesize($filePath));
 
 			set_time_limit(0);
-			$file = @fopen($filePath, "rb");
-			while (!feof($file)) {
-				print(@fread($file, 1024*8));
+			$filePointer = @fopen($filePath, "rb");
+			if (!$filePointer) {
+				throw new HttpException('Problem z odczytem pliku', 500);
+			}
+			while (!feof($filePointer)) {
+				print(@fread($filePointer, 1024*8));
 				ob_flush();
 				flush();
 			}
+			fclose($filePointer);
 		}
 	}