Merge pull request #3654 from owncloud/clean_up_exceptions

Introduce more robust SQL execution and exception handling
This commit is contained in:
Thomas Müller 2013-06-12 04:13:12 -07:00
commit 1abce78cb8
9 changed files with 293 additions and 181 deletions

124
cron.php
View File

@ -44,75 +44,81 @@ function handleUnexpectedShutdown() {
} }
} }
require_once 'lib/base.php'; try {
session_write_close(); require_once 'lib/base.php';
// Don't do anything if ownCloud has not been installed session_write_close();
if (!OC_Config::getValue('installed', false)) {
exit(0);
}
// Handle unexpected errors // Don't do anything if ownCloud has not been installed
register_shutdown_function('handleUnexpectedShutdown'); if (!OC_Config::getValue('installed', false)) {
exit(0);
// Delete temp folder
OC_Helper::cleanTmpNoClean();
// Exit if background jobs are disabled!
$appmode = OC_BackgroundJob::getExecutionType();
if ($appmode == 'none') {
TemporaryCronClass::$sent = true;
if (OC::$CLI) {
echo 'Background Jobs are disabled!' . PHP_EOL;
} else {
OC_JSON::error(array('data' => array('message' => 'Background jobs disabled!')));
}
exit(1);
}
if (OC::$CLI) {
// Create lock file first
TemporaryCronClass::$lockfile = OC_Config::getValue("datadirectory", OC::$SERVERROOT . '/data') . '/cron.lock';
// We call ownCloud from the CLI (aka cron)
if ($appmode != 'cron') {
// Use cron in feature!
OC_BackgroundJob::setExecutionType('cron');
} }
// check if backgroundjobs is still running // Handle unexpected errors
if (file_exists(TemporaryCronClass::$lockfile)) { register_shutdown_function('handleUnexpectedShutdown');
TemporaryCronClass::$keeplock = true;
// Delete temp folder
OC_Helper::cleanTmpNoClean();
// Exit if background jobs are disabled!
$appmode = OC_BackgroundJob::getExecutionType();
if ($appmode == 'none') {
TemporaryCronClass::$sent = true; TemporaryCronClass::$sent = true;
echo "Another instance of cron.php is still running!"; if (OC::$CLI) {
echo 'Background Jobs are disabled!' . PHP_EOL;
} else {
OC_JSON::error(array('data' => array('message' => 'Background jobs disabled!')));
}
exit(1); exit(1);
} }
// Create a lock file if (OC::$CLI) {
touch(TemporaryCronClass::$lockfile); // Create lock file first
TemporaryCronClass::$lockfile = OC_Config::getValue("datadirectory", OC::$SERVERROOT . '/data') . '/cron.lock';
// Work // We call ownCloud from the CLI (aka cron)
$jobList = new \OC\BackgroundJob\JobList(); if ($appmode != 'cron') {
$jobs = $jobList->getAll(); // Use cron in feature!
foreach ($jobs as $job) { OC_BackgroundJob::setExecutionType('cron');
$job->execute($jobList); }
}
} else { // check if backgroundjobs is still running
// We call cron.php from some website if (file_exists(TemporaryCronClass::$lockfile)) {
if ($appmode == 'cron') { TemporaryCronClass::$keeplock = true;
// Cron is cron :-P TemporaryCronClass::$sent = true;
OC_JSON::error(array('data' => array('message' => 'Backgroundjobs are using system cron!'))); echo "Another instance of cron.php is still running!";
} else { exit(1);
// Work and success :-) }
// Create a lock file
touch(TemporaryCronClass::$lockfile);
// Work
$jobList = new \OC\BackgroundJob\JobList(); $jobList = new \OC\BackgroundJob\JobList();
$job = $jobList->getNext(); $jobs = $jobList->getAll();
$job->execute($jobList); foreach ($jobs as $job) {
$jobList->setLastJob($job); $job->execute($jobList);
OC_JSON::success(); }
} else {
// We call cron.php from some website
if ($appmode == 'cron') {
// Cron is cron :-P
OC_JSON::error(array('data' => array('message' => 'Backgroundjobs are using system cron!')));
} else {
// Work and success :-)
$jobList = new \OC\BackgroundJob\JobList();
$job = $jobList->getNext();
$job->execute($jobList);
$jobList->setLastJob($job);
OC_JSON::success();
}
} }
}
// done! // done!
TemporaryCronClass::$sent = true; TemporaryCronClass::$sent = true;
exit(); exit();
} catch (Exception $ex) {
\OCP\Util::writeLog('cron', $ex->getMessage(), \OCP\Util::FATAL);
}

View File

@ -23,6 +23,15 @@
$RUNTIME_NOAPPS = true; //no apps, yet $RUNTIME_NOAPPS = true; //no apps, yet
require_once 'lib/base.php'; try {
require_once 'lib/base.php';
OC::handleRequest(); OC::handleRequest();
} catch (Exception $ex) {
//show the user a detailed error page
OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
\OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
OC_Template::printExceptionErrorPage($ex);
}

View File

@ -23,7 +23,8 @@
class DatabaseException extends Exception{ class DatabaseException extends Exception{
private $query; private $query;
public function __construct($message, $query){ //FIXME getQuery seems to be unused, maybe use parent constructor with $message, $code and $previous
public function __construct($message, $query = null){
parent::__construct($message); parent::__construct($message);
$this->query = $query; $this->query = $query;
} }
@ -391,10 +392,60 @@ class OC_DB {
return $result; return $result;
} }
/**
* @brief execute a prepared statement, on error write log and throw exception
* @param mixed $stmt PDOStatementWrapper | MDB2_Statement_Common ,
* an array with 'sql' and optionally 'limit' and 'offset' keys
* .. or a simple sql query string
* @param array $parameters
* @return result
* @throws DatabaseException
*/
static public function executeAudited( $stmt, array $parameters = null) {
if (is_string($stmt)) {
// convert to an array with 'sql'
if (stripos($stmt,'LIMIT') !== false) { //OFFSET requires LIMIT, se we only neet to check for LIMIT
// TODO try to convert LIMIT OFFSET notation to parameters, see fixLimitClauseForMSSQL
$message = 'LIMIT and OFFSET are forbidden for portability reasons,'
. ' pass an array with \'limit\' and \'offset\' instead';
throw new DatabaseException($message);
}
$stmt = array('sql' => $stmt, 'limit' => null, 'offset' => null);
}
if (is_array($stmt)){
// convert to prepared statement
if ( ! array_key_exists('sql', $stmt) ) {
$message = 'statement array must at least contain key \'sql\'';
throw new DatabaseException($message);
}
if ( ! array_key_exists('limit', $stmt) ) {
$stmt['limit'] = null;
}
if ( ! array_key_exists('limit', $stmt) ) {
$stmt['offset'] = null;
}
$stmt = self::prepare($stmt['sql'], $stmt['limit'], $stmt['offset']);
}
self::raiseExceptionOnError($stmt, 'Could not prepare statement');
if ($stmt instanceof PDOStatementWrapper || $stmt instanceof MDB2_Statement_Common) {
$result = $stmt->execute($parameters);
self::raiseExceptionOnError($result, 'Could not execute statement');
} else {
if (is_object($stmt)) {
$message = 'Expected a prepared statement or array got ' . get_class($stmt);
} else {
$message = 'Expected a prepared statement or array got ' . gettype($stmt);
}
throw new DatabaseException($message);
}
return $result;
}
/** /**
* @brief gets last value of autoincrement * @brief gets last value of autoincrement
* @param string $table The optional table name (will replace *PREFIX*) and add sequence suffix * @param string $table The optional table name (will replace *PREFIX*) and add sequence suffix
* @return int id * @return int id
* @throws DatabaseException
* *
* MDB2 lastInsertID() * MDB2 lastInsertID()
* *
@ -404,25 +455,27 @@ class OC_DB {
public static function insertid($table=null) { public static function insertid($table=null) {
self::connect(); self::connect();
$type = OC_Config::getValue( "dbtype", "sqlite" ); $type = OC_Config::getValue( "dbtype", "sqlite" );
if( $type == 'pgsql' ) { if( $type === 'pgsql' ) {
$query = self::prepare('SELECT lastval() AS id'); $result = self::executeAudited('SELECT lastval() AS id');
$row = $query->execute()->fetchRow(); $row = $result->fetchRow();
self::raiseExceptionOnError($row, 'fetching row for insertid failed');
return $row['id']; return $row['id'];
} } else if( $type === 'mssql') {
if( $type == 'mssql' ) {
if($table !== null) { if($table !== null) {
$prefix = OC_Config::getValue( "dbtableprefix", "oc_" ); $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
$table = str_replace( '*PREFIX*', $prefix, $table ); $table = str_replace( '*PREFIX*', $prefix, $table );
} }
return self::$connection->lastInsertId($table); $result = self::$connection->lastInsertId($table);
}else{ } else {
if($table !== null) { if($table !== null) {
$prefix = OC_Config::getValue( "dbtableprefix", "oc_" ); $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
$suffix = OC_Config::getValue( "dbsequencesuffix", "_id_seq" ); $suffix = OC_Config::getValue( "dbsequencesuffix", "_id_seq" );
$table = str_replace( '*PREFIX*', $prefix, $table ).$suffix; $table = str_replace( '*PREFIX*', $prefix, $table ).$suffix;
} }
return self::$connection->lastInsertId($table); $result = self::$connection->lastInsertId($table);
} }
self::raiseExceptionOnError($result, 'insertid failed');
return $result;
} }
/** /**
@ -512,6 +565,8 @@ class OC_DB {
//clean up memory //clean up memory
unlink( $file2 ); unlink( $file2 );
self::raiseExceptionOnError($definition,'Failed to parse the database definition');
// Die in case something went wrong // Die in case something went wrong
if( $definition instanceof MDB2_Schema_Error ) { if( $definition instanceof MDB2_Schema_Error ) {
@ -528,11 +583,7 @@ class OC_DB {
$ret=self::$schema->createDatabase( $definition ); $ret=self::$schema->createDatabase( $definition );
// Die in case something went wrong self::raiseExceptionOnError($ret,'Failed to create the database structure');
if( $ret instanceof MDB2_Error ) {
OC_Template::printErrorPage( self::$MDB2->getDebugOutput().' '.$ret->getMessage() . ': '
. $ret->getUserInfo() );
}
return true; return true;
} }
@ -552,13 +603,7 @@ class OC_DB {
$content = file_get_contents( $file ); $content = file_get_contents( $file );
$previousSchema = self::$schema->getDefinitionFromDatabase(); $previousSchema = self::$schema->getDefinitionFromDatabase();
if (PEAR::isError($previousSchema)) { self::raiseExceptionOnError($previousSchema,'Failed to get existing database structure for updating');
$error = $previousSchema->getMessage();
$detail = $previousSchema->getDebugInfo();
$message = 'Failed to get existing database structure for updating ('.$error.', '.$detail.')';
OC_Log::write('core', $message, OC_Log::FATAL);
throw new Exception($message);
}
// Make changes and save them to an in-memory file // Make changes and save them to an in-memory file
$file2 = 'static://db_scheme'; $file2 = 'static://db_scheme';
@ -582,13 +627,7 @@ class OC_DB {
//clean up memory //clean up memory
unlink( $file2 ); unlink( $file2 );
if (PEAR::isError($op)) { self::raiseExceptionOnError($op,'Failed to update database structure');
$error = $op->getMessage();
$detail = $op->getDebugInfo();
$message = 'Failed to update database structure ('.$error.', '.$detail.')';
OC_Log::write('core', $message, OC_Log::FATAL);
throw new Exception($message);
}
return true; return true;
} }
@ -641,15 +680,9 @@ class OC_DB {
} }
$query = substr($query, 0, strlen($query) - 5); $query = substr($query, 0, strlen($query) - 5);
try { try {
$stmt = self::prepare($query); $result = self::executeAudited($query, $inserts);
$result = $stmt->execute($inserts); } catch(DatabaseException $e) {
OC_Template::printExceptionErrorPage( $e );
} catch(PDOException $e) {
$entry = 'DB Error: "'.$e->getMessage() . '"<br />';
$entry .= 'Offending command was: ' . $query . '<br />';
OC_Log::write('core', $entry, OC_Log::FATAL);
error_log('DB error: '.$entry);
OC_Template::printErrorPage( $entry );
} }
if((int)$result->numRows() === 0) { if((int)$result->numRows() === 0) {
@ -674,16 +707,12 @@ class OC_DB {
} }
try { try {
$result = self::prepare($query); $result = self::executeAudited($query, $inserts);
} catch(PDOException $e) { } catch(PDOException $e) {
$entry = 'DB Error: "'.$e->getMessage() . '"<br />'; OC_Template::printExceptionErrorPage( $e );
$entry .= 'Offending command was: ' . $query.'<br />';
OC_Log::write('core', $entry, OC_Log::FATAL);
error_log('DB error: ' . $entry);
OC_Template::printErrorPage( $entry );
} }
return $result->execute($inserts); return $result;
} }
/** /**
@ -891,7 +920,32 @@ class OC_DB {
return false; return false;
} }
} }
/**
* check if a result is an error, writes a log entry and throws an exception, works with MDB2 and PDOException
* @param mixed $result
* @param string message
* @return void
* @throws DatabaseException
*/
public static function raiseExceptionOnError($result, $message = null) {
if(self::isError($result)) {
if ($message === null) {
$message = self::getErrorMessage($result);
} else {
$message .= ', Root cause:' . self::getErrorMessage($result);
}
throw new DatabaseException($message, getErrorCode($result));
}
}
public static function getErrorCode($error) {
if ( self::$backend==self::BACKEND_MDB2 and PEAR::isError($error) ) {
$code = $error->getCode();
} elseif ( self::$backend==self::BACKEND_PDO and self::$PDO ) {
$code = self::$PDO->errorCode();
}
return $code;
}
/** /**
* returns the error code and message as a string for logging * returns the error code and message as a string for logging
* works with MDB2 and PDOException * works with MDB2 and PDOException
@ -901,9 +955,7 @@ class OC_DB {
public static function getErrorMessage($error) { public static function getErrorMessage($error) {
if ( self::$backend==self::BACKEND_MDB2 and PEAR::isError($error) ) { if ( self::$backend==self::BACKEND_MDB2 and PEAR::isError($error) ) {
$msg = $error->getCode() . ': ' . $error->getMessage(); $msg = $error->getCode() . ': ' . $error->getMessage();
if (defined('DEBUG') && DEBUG) { $msg .= ' (' . $error->getDebugInfo() . ')';
$msg .= '(' . $error->getDebugInfo() . ')';
}
} elseif (self::$backend==self::BACKEND_PDO and self::$PDO) { } elseif (self::$backend==self::BACKEND_PDO and self::$PDO) {
$msg = self::$PDO->errorCode() . ': '; $msg = self::$PDO->errorCode() . ': ';
$errorInfo = self::$PDO->errorInfo(); $errorInfo = self::$PDO->errorInfo();

View File

@ -11,6 +11,7 @@ class OC_Response {
const STATUS_NOT_MODIFIED = 304; const STATUS_NOT_MODIFIED = 304;
const STATUS_TEMPORARY_REDIRECT = 307; const STATUS_TEMPORARY_REDIRECT = 307;
const STATUS_NOT_FOUND = 404; const STATUS_NOT_FOUND = 404;
const STATUS_INTERNAL_SERVER_ERROR = 500;
/** /**
* @brief Enable response caching by sending correct HTTP headers * @brief Enable response caching by sending correct HTTP headers
@ -70,6 +71,9 @@ class OC_Response {
case self::STATUS_NOT_FOUND; case self::STATUS_NOT_FOUND;
$status = $status . ' Not Found'; $status = $status . ' Not Found';
break; break;
case self::STATUS_INTERNAL_SERVER_ERROR;
$status = $status . ' Internal Server Error';
break;
} }
header($protocol.' '.$status); header($protocol.' '.$status);
} }

View File

@ -106,12 +106,6 @@ class OC_Setup {
'hint' => $e->getHint() 'hint' => $e->getHint()
); );
return($error); return($error);
} catch (Exception $e) {
$error[] = array(
'error' => $e->getMessage(),
'hint' => ''
);
return($error);
} }
} }
elseif($dbtype == 'pgsql') { elseif($dbtype == 'pgsql') {
@ -127,7 +121,7 @@ class OC_Setup {
try { try {
self::setupPostgreSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username); self::setupPostgreSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username);
} catch (Exception $e) { } catch (DatabaseSetupException $e) {
$error[] = array( $error[] = array(
'error' => $l->t('PostgreSQL username and/or password not valid'), 'error' => $l->t('PostgreSQL username and/or password not valid'),
'hint' => $l->t('You need to enter either an existing account or the administrator.') 'hint' => $l->t('You need to enter either an existing account or the administrator.')
@ -150,7 +144,7 @@ class OC_Setup {
try { try {
self::setupOCIDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, $username); self::setupOCIDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, $username);
} catch (Exception $e) { } catch (DatabaseSetupException $e) {
$error[] = array( $error[] = array(
'error' => $l->t('Oracle connection could not be established'), 'error' => $l->t('Oracle connection could not be established'),
'hint' => $e->getMessage().' Check environment: ORACLE_HOME='.getenv('ORACLE_HOME') 'hint' => $e->getMessage().' Check environment: ORACLE_HOME='.getenv('ORACLE_HOME')
@ -177,7 +171,7 @@ class OC_Setup {
try { try {
self::setupMSSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix); self::setupMSSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix);
} catch (Exception $e) { } catch (DatabaseSetupException $e) {
$error[] = array( $error[] = array(
'error' => 'MS SQL username and/or password not valid', 'error' => 'MS SQL username and/or password not valid',
'hint' => 'You need to enter either an existing account or the administrator.' 'hint' => 'You need to enter either an existing account or the administrator.'
@ -326,7 +320,7 @@ class OC_Setup {
$connection_string = "host='$e_host' dbname=postgres user='$e_user' password='$e_password'"; $connection_string = "host='$e_host' dbname=postgres user='$e_user' password='$e_password'";
$connection = @pg_connect($connection_string); $connection = @pg_connect($connection_string);
if(!$connection) { if(!$connection) {
throw new Exception($l->t('PostgreSQL username and/or password not valid')); throw new DatabaseSetupException($l->t('PostgreSQL username and/or password not valid'));
} }
$e_user = pg_escape_string($dbuser); $e_user = pg_escape_string($dbuser);
//check for roles creation rights in postgresql //check for roles creation rights in postgresql
@ -371,7 +365,7 @@ class OC_Setup {
$connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'"; $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'";
$connection = @pg_connect($connection_string); $connection = @pg_connect($connection_string);
if(!$connection) { if(!$connection) {
throw new Exception($l->t('PostgreSQL username and/or password not valid')); throw new DatabaseSetupException($l->t('PostgreSQL username and/or password not valid'));
} }
$query = "select count(*) FROM pg_class WHERE relname='{$dbtableprefix}users' limit 1"; $query = "select count(*) FROM pg_class WHERE relname='{$dbtableprefix}users' limit 1";
$result = pg_query($connection, $query); $result = pg_query($connection, $query);
@ -461,9 +455,9 @@ class OC_Setup {
if(!$connection) { if(!$connection) {
$e = oci_error(); $e = oci_error();
if (is_array ($e) && isset ($e['message'])) { if (is_array ($e) && isset ($e['message'])) {
throw new Exception($e['message']); throw new DatabaseSetupException($e['message']);
} }
throw new Exception($l->t('Oracle username and/or password not valid')); throw new DatabaseSetupException($l->t('Oracle username and/or password not valid'));
} }
//check for roles creation rights in oracle //check for roles creation rights in oracle
@ -530,7 +524,7 @@ class OC_Setup {
} }
$connection = @oci_connect($dbuser, $dbpass, $easy_connect_string); $connection = @oci_connect($dbuser, $dbpass, $easy_connect_string);
if(!$connection) { if(!$connection) {
throw new Exception($l->t('Oracle username and/or password not valid')); throw new DatabaseSetupException($l->t('Oracle username and/or password not valid'));
} }
$query = "SELECT count(*) FROM user_tables WHERE table_name = :un"; $query = "SELECT count(*) FROM user_tables WHERE table_name = :un";
$stmt = oci_parse($connection, $query); $stmt = oci_parse($connection, $query);
@ -641,7 +635,7 @@ class OC_Setup {
} else { } else {
$entry = ''; $entry = '';
} }
throw new Exception($l->t('MS SQL username and/or password not valid: %s', array($entry))); throw new DatabaseSetupException($l->t('MS SQL username and/or password not valid: %s', array($entry)));
} }
OC_Config::setValue('dbuser', $dbuser); OC_Config::setValue('dbuser', $dbuser);

View File

@ -535,4 +535,25 @@ class OC_Template{
$content->printPage(); $content->printPage();
die(); die();
} }
/**
* print error page using Exception details
* @param Exception $exception
*/
public static function printExceptionErrorPage(Exception $exception) {
$error_msg = $exception->getMessage();
if ($exception->getCode()) {
$error_msg = '['.$exception->getCode().'] '.$error_msg;
}
$hint = $exception->getTraceAsString();
while ($exception = $exception->previous()) {
$error_msg .= '<br/>Caused by: ';
if ($exception->getCode()) {
$error_msg .= '['.$exception->getCode().'] ';
}
$error_msg .= $exception->getMessage();
};
self::printErrorPage($error_msg, $hint);
}
} }

View File

@ -1,21 +1,31 @@
<?php <?php
$RUNTIME_NOAPPS = true; $RUNTIME_NOAPPS = true;
require_once 'lib/base.php';
OC::checkMaintenanceMode();
if (!isset($_GET['service'])) {
header('HTTP/1.0 404 Not Found');
exit;
}
$file = OCP\CONFIG::getAppValue('core', 'public_' . strip_tags($_GET['service']));
if(is_null($file)) {
header('HTTP/1.0 404 Not Found');
exit;
}
$parts=explode('/', $file, 2); try {
$app=$parts[0];
OC_Util::checkAppEnabled($app); require_once 'lib/base.php';
OC_App::loadApp($app); OC::checkMaintenanceMode();
if (!isset($_GET['service'])) {
header('HTTP/1.0 404 Not Found');
exit;
}
$file = OCP\CONFIG::getAppValue('core', 'public_' . strip_tags($_GET['service']));
if(is_null($file)) {
header('HTTP/1.0 404 Not Found');
exit;
}
require_once OC_App::getAppPath($app) .'/'. $parts[1]; $parts=explode('/', $file, 2);
$app=$parts[0];
OC_Util::checkAppEnabled($app);
OC_App::loadApp($app);
require_once OC_App::getAppPath($app) .'/'. $parts[1];
} catch (Exception $ex) {
//show the user a detailed error page
OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
\OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
OC_Template::printExceptionErrorPage($ex);
}

View File

@ -1,40 +1,49 @@
<?php <?php
$RUNTIME_NOAPPS = true; $RUNTIME_NOAPPS = true;
require_once 'lib/base.php';
$path_info = OC_Request::getPathInfo();
if ($path_info === false || $path_info === '') {
OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
exit;
}
if (!$pos = strpos($path_info, '/', 1)) {
$pos = strlen($path_info);
}
$service=substr($path_info, 1, $pos-1);
$file = OC_AppConfig::getValue('core', 'remote_' . $service); try {
if(is_null($file)) { require_once 'lib/base.php';
OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND); $path_info = OC_Request::getPathInfo();
exit; if ($path_info === false || $path_info === '') {
} OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
exit;
}
if (!$pos = strpos($path_info, '/', 1)) {
$pos = strlen($path_info);
}
$service=substr($path_info, 1, $pos-1);
$file=ltrim($file, '/'); $file = OC_AppConfig::getValue('core', 'remote_' . $service);
$parts=explode('/', $file, 2); if(is_null($file)) {
$app=$parts[0]; OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
switch ($app) { exit;
case 'core': }
$file = OC::$SERVERROOT .'/'. $file;
break; $file=ltrim($file, '/');
default:
OC_Util::checkAppEnabled($app); $parts=explode('/', $file, 2);
OC_App::loadApp($app); $app=$parts[0];
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { switch ($app) {
$file = OC_App::getAppPath($app) .'/'. $parts[1]; case 'core':
}else{ $file = OC::$SERVERROOT .'/'. $file;
$file = '/' . OC_App::getAppPath($app) .'/'. $parts[1]; break;
} default:
break; OC_Util::checkAppEnabled($app);
} OC_App::loadApp($app);
$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/'; if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
require_once $file; $file = OC_App::getAppPath($app) .'/'. $parts[1];
}else{
$file = '/' . OC_App::getAppPath($app) .'/'. $parts[1];
}
break;
}
$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/';
require_once $file;
} catch (Exception $ex) {
OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
\OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
OC_Template::printExceptionErrorPage($ex);
}

View File

@ -23,13 +23,20 @@
$RUNTIME_NOAPPS = true; //no apps, yet $RUNTIME_NOAPPS = true; //no apps, yet
require_once 'lib/base.php'; try {
if(OC_Config::getValue('installed')==1) $installed='true'; else $installed='false'; require_once 'lib/base.php';
$values=array(
'installed'=>$installed,
'version'=>implode('.', OC_Util::getVersion()),
'versionstring'=>OC_Util::getVersionString(),
'edition'=>OC_Util::getEditionString());
echo(json_encode($values)); if(OC_Config::getValue('installed')==1) $installed='true'; else $installed='false';
$values=array(
'installed'=>$installed,
'version'=>implode('.', OC_Util::getVersion()),
'versionstring'=>OC_Util::getVersionString(),
'edition'=>OC_Util::getEditionString());
echo(json_encode($values));
} catch (Exception $ex) {
OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
\OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
}