aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2015-07-01 07:18:36 +0200
committerVincent Petry <pvince81@owncloud.com>2015-07-01 07:18:36 +0200
commitb921748e61a05b65e9d58221bb2c44b02befb64d (patch)
treede822e6a7a5af2683c2bb0b8c62288f26f366716
parentf76773bd4c7816ffedf3e7b09029367ad82e3093 (diff)
parent134dc136e66f7ead2e4ffc7d74711e1d9a8dc58d (diff)
downloadnextcloud-server-b921748e61a05b65e9d58221bb2c44b02befb64d.tar.gz
nextcloud-server-b921748e61a05b65e9d58221bb2c44b02befb64d.zip
Merge pull request #17224 from owncloud/webdav-handle-ServerNotAvailableException
Adding exception handling for ServerNotAvailableException
-rw-r--r--lib/private/connector/sabre/auth.php44
-rw-r--r--remote.php71
2 files changed, 86 insertions, 29 deletions
diff --git a/lib/private/connector/sabre/auth.php b/lib/private/connector/sabre/auth.php
index 5a32a9112ba..8a6eaab5bf8 100644
--- a/lib/private/connector/sabre/auth.php
+++ b/lib/private/connector/sabre/auth.php
@@ -30,7 +30,12 @@
*/
namespace OC\Connector\Sabre;
-class Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
+use Exception;
+use Sabre\DAV\Auth\Backend\AbstractBasic;
+use Sabre\DAV\Exception\NotAuthenticated;
+use Sabre\DAV\Exception\ServiceUnavailable;
+
+class Auth extends AbstractBasic {
const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';
/**
@@ -69,7 +74,7 @@ class Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
} else {
\OC_Util::setUpFS(); //login hooks may need early access to the filesystem
if(\OC_User::login($username, $password)) {
- // make sure we use owncloud's internal username here
+ // make sure we use ownCloud's internal username here
// and not the HTTP auth supplied one, see issue #14048
$ocUser = \OC_User::getUser();
\OC_Util::setUpFS($ocUser);
@@ -99,21 +104,30 @@ class Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
}
/**
- * Override function here. We want to cache authentication cookies
- * in the syncing client to avoid HTTP-401 roundtrips.
- * If the sync client supplies the cookies, then OC_User::isLoggedIn()
- * will return true and we can see this WebDAV request as already authenticated,
- * even if there are no HTTP Basic Auth headers.
- * In other case, just fallback to the parent implementation.
- *
- * @param \Sabre\DAV\Server $server
- * @param $realm
- * @return bool
- */
+ * Override function here. We want to cache authentication cookies
+ * in the syncing client to avoid HTTP-401 roundtrips.
+ * If the sync client supplies the cookies, then OC_User::isLoggedIn()
+ * will return true and we can see this WebDAV request as already authenticated,
+ * even if there are no HTTP Basic Auth headers.
+ * In other case, just fallback to the parent implementation.
+ *
+ * @param \Sabre\DAV\Server $server
+ * @param string $realm
+ * @return bool
+ * @throws ServiceUnavailable
+ */
public function authenticate(\Sabre\DAV\Server $server, $realm) {
- $result = $this->auth($server, $realm);
- return $result;
+ try {
+ $result = $this->auth($server, $realm);
+ return $result;
+ } catch (NotAuthenticated $e) {
+ throw $e;
+ } catch (Exception $e) {
+ $class = get_class($e);
+ $msg = $e->getMessage();
+ throw new ServiceUnavailable("$class: $msg");
+ }
}
/**
diff --git a/remote.php b/remote.php
index c1077e42672..0b43f949ad4 100644
--- a/remote.php
+++ b/remote.php
@@ -25,22 +25,72 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
+use OC\Connector\Sabre\ExceptionLoggerPlugin;
+use Sabre\DAV\Exception\ServiceUnavailable;
+use Sabre\DAV\Server;
+
+/**
+ * Class RemoteException
+ * Dummy exception class to be use locally to identify certain conditions
+ */
+class RemoteException extends Exception {
+}
+
+/**
+ * @param Exception $e
+ */
+function handleException(Exception $e) {
+ $request = \OC::$server->getRequest();
+ // in case the request content type is text/xml - we assume it's a WebDAV request
+ $isXmlContentType = strpos($request->getHeader('Content-Type'), 'text/xml');
+ if ($isXmlContentType === 0) {
+ // fire up a simple server to properly process the exception
+ $server = new Server();
+ $server->addPlugin(new ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
+ $server->on('beforeMethod', function () use ($e) {
+ if ($e instanceof RemoteException) {
+ switch ($e->getCode()) {
+ case OC_Response::STATUS_SERVICE_UNAVAILABLE:
+ throw new ServiceUnavailable($e->getMessage());
+ case OC_Response::STATUS_NOT_FOUND:
+ throw new \Sabre\DAV\Exception\NotFound($e->getMessage());
+ }
+ }
+ $class = get_class($e);
+ $msg = $e->getMessage();
+ throw new ServiceUnavailable("$class: $msg");
+ });
+ $server->exec();
+ } else {
+ $statusCode = OC_Response::STATUS_INTERNAL_SERVER_ERROR;
+ if ($e instanceof \OC\ServiceUnavailableException ) {
+ $statusCode = OC_Response::STATUS_SERVICE_UNAVAILABLE;
+ }
+ \OCP\Util::writeLog('remote', $e->getMessage(), \OCP\Util::FATAL);
+ if ($e instanceof RemoteException) {
+ OC_Response::setStatus($e->getCode());
+ OC_Template::printErrorPage($e->getMessage());
+ } else {
+ OC_Response::setStatus($statusCode);
+ OC_Template::printExceptionErrorPage($e);
+ }
+ }
+}
+
try {
require_once 'lib/base.php';
if (\OCP\Util::needUpgrade()) {
// since the behavior of apps or remotes are unpredictable during
// an upgrade, return a 503 directly
- OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
- OC_Template::printErrorPage('Service unavailable');
- exit;
+ throw new RemoteException('Service unavailable', OC_Response::STATUS_SERVICE_UNAVAILABLE);
}
$request = \OC::$server->getRequest();
$pathInfo = $request->getPathInfo();
if ($pathInfo === false || $pathInfo === '') {
- OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
- exit;
+ throw new RemoteException('Path not found', OC_Response::STATUS_NOT_FOUND);
}
if (!$pos = strpos($pathInfo, '/', 1)) {
$pos = strlen($pathInfo);
@@ -50,8 +100,7 @@ try {
$file = \OC::$server->getConfig()->getAppValue('core', 'remote_' . $service);
if(is_null($file)) {
- OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
- exit;
+ throw new RemoteException('Path not found', OC_Response::STATUS_NOT_FOUND);
}
// force language as given in the http request
@@ -82,12 +131,6 @@ try {
$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/';
require_once $file;
-} catch (\OC\ServiceUnavailableException $ex) {
- OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
- \OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
- OC_Template::printExceptionErrorPage($ex);
} 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);
+ handleException($ex);
}