Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 53 additions & 18 deletions apps/dav/lib/Connector/Sabre/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use OC\Files\Filesystem;
use OC\Files\Stream\HashWrapper;
use OC\Files\View;
use OCA\DAV\AppInfo\Application;
use OCA\DAV\Connector\Sabre\Exception\EntityTooLarge;
use OCA\DAV\Connector\Sabre\Exception\FileLocked;
use OCA\DAV\Connector\Sabre\Exception\Forbidden as DAVForbiddenException;
Expand All @@ -60,7 +61,9 @@
use OCP\Files\NotPermittedException;
use OCP\Files\Storage;
use OCP\Files\StorageNotAvailableException;
use OCP\IL10N;
use OCP\ILogger;
use OCP\L10N\IFactory as IL10NFactory;
use OCP\Lock\ILockingProvider;
use OCP\Lock\LockedException;
use OCP\Share\IManager;
Expand All @@ -75,6 +78,9 @@
class File extends Node implements IFile {
protected $request;

/** @var IL10N */
protected $l10n;

/**
* Sets up the node, expects a full path name
*
Expand All @@ -86,6 +92,11 @@ class File extends Node implements IFile {
public function __construct(View $view, FileInfo $info, IManager $shareManager = null, Request $request = null) {
parent::__construct($view, $info, $shareManager);

// Querying IL10N directly results in a dependency loop
/** @var IL10NFactory $l10nFactory */
$l10nFactory = \OC::$server->get(IL10NFactory::class);
$this->l10n = $l10nFactory->get(Application::APP_ID);

if (isset($request)) {
$this->request = $request;
} else {
Expand Down Expand Up @@ -128,7 +139,7 @@ public function put($data) {
throw new Forbidden();
}
} catch (StorageNotAvailableException $e) {
throw new ServiceUnavailable("File is not updatable: " . $e->getMessage());
throw new ServiceUnavailable($this->l10n->t('File is not updatable: %1$s', [$e->getMessage()]));
}

// verify path of the target
Expand Down Expand Up @@ -162,7 +173,7 @@ public function put($data) {
$partFilePath = $this->path;

if ($view && !$this->emitPreHooks($exists)) {
throw new Exception('Could not write to final file, canceled by hook');
throw new Exception($this->l10n->t('Could not write to final file, canceled by hook'));
}
}

Expand Down Expand Up @@ -223,7 +234,7 @@ public function put($data) {
if ($target === false) {
\OC::$server->getLogger()->error('\OC\Files\Filesystem::fopen() failed', ['app' => 'webdav']);
// because we have no clue about the cause we can only throw back a 500/Internal Server Error
throw new Exception('Could not write file contents');
throw new Exception($this->l10n->t('Could not write file contents'));
}
[$count, $result] = \OC_Helper::streamCopy($data, $target);
fclose($target);
Expand All @@ -235,7 +246,15 @@ public function put($data) {
$expected = $_SERVER['CONTENT_LENGTH'];
}
if ($expected !== "0") {
throw new Exception('Error while copying file to target location (copied bytes: ' . $count . ', expected filesize: ' . $expected . ' )');
throw new Exception(
$this->l10n->t(
'Error while copying file to target location (copied: %1$s, expected filesize: %2$s)',
[
$this->l10n->n('%n byte', '%n bytes', $count),
$this->l10n->n('%n byte', '%n bytes', $expected),
],
)
);
}
}

Expand All @@ -245,7 +264,15 @@ public function put($data) {
if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] === 'PUT') {
$expected = (int)$_SERVER['CONTENT_LENGTH'];
if ($count !== $expected) {
throw new BadRequest('Expected filesize of ' . $expected . ' bytes but read (from Nextcloud client) and wrote (to Nextcloud storage) ' . $count . ' bytes. Could either be a network problem on the sending side or a problem writing to the storage on the server side.');
throw new BadRequest(
$this->l10n->t(
'Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side.',
[
$this->l10n->n('%n byte', '%n bytes', $expected),
$this->l10n->n('%n byte', '%n bytes', $count),
],
)
);
}
}
} catch (\Exception $e) {
Expand All @@ -266,7 +293,7 @@ public function put($data) {
if ($needsPartFile) {
if ($view && !$this->emitPreHooks($exists)) {
$partStorage->unlink($internalPartPath);
throw new Exception('Could not rename part file to final file, canceled by hook');
throw new Exception($this->l10n->t('Could not rename part file to final file, canceled by hook'));
}
try {
$this->changeLock(ILockingProvider::LOCK_EXCLUSIVE);
Expand Down Expand Up @@ -295,7 +322,7 @@ public function put($data) {
$fileExists = $storage->file_exists($internalPath);
if ($renameOkay === false || $fileExists === false) {
\OC::$server->getLogger()->error('renaming part file to final file failed $renameOkay: ' . ($renameOkay ? 'true' : 'false') . ', $fileExists: ' . ($fileExists ? 'true' : 'false') . ')', ['app' => 'webdav']);
throw new Exception('Could not rename part file to final file');
throw new Exception($this->l10n->t('Could not rename part file to final file'));
}
} catch (ForbiddenException $ex) {
if (!$ex->getRetry()) {
Expand Down Expand Up @@ -353,7 +380,7 @@ public function put($data) {
$this->refreshInfo();
}
} catch (StorageNotAvailableException $e) {
throw new ServiceUnavailable("Failed to check file size: " . $e->getMessage(), 0, $e);
throw new ServiceUnavailable($this->l10n->t('Failed to check file size: %1$s', [$e->getMessage()]), 0, $e);
}

return '"' . $this->info->getEtag() . '"';
Expand Down Expand Up @@ -438,14 +465,14 @@ public function get() {
$this->convertToSabreException($e);
}
if ($res === false) {
throw new ServiceUnavailable("Could not open file");
throw new ServiceUnavailable($this->l10n->t('Could not open file'));
}
return $res;
} catch (GenericEncryptionException $e) {
// returning 503 will allow retry of the operation at a later point in time
throw new ServiceUnavailable("Encryption not ready: " . $e->getMessage());
throw new ServiceUnavailable($this->l10n->t('Encryption not ready: %1$s', [$e->getMessage()]));
} catch (StorageNotAvailableException $e) {
throw new ServiceUnavailable("Failed to open file: " . $e->getMessage());
throw new ServiceUnavailable($this->l10n->t('Failed to open file: %1$s', [$e->getMessage()]));
} catch (ForbiddenException $ex) {
throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
} catch (LockedException $e) {
Expand All @@ -470,7 +497,7 @@ public function delete() {
throw new Forbidden();
}
} catch (StorageNotAvailableException $e) {
throw new ServiceUnavailable("Failed to unlink: " . $e->getMessage());
throw new ServiceUnavailable($this->l10n->t('Failed to unlink: %1$s', [$e->getMessage()]));
} catch (ForbiddenException $ex) {
throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
} catch (LockedException $e) {
Expand Down Expand Up @@ -524,7 +551,7 @@ private function createFileChunked($data) {

$info = \OC_FileChunking::decodeName($name);
if (empty($info)) {
throw new NotImplemented('Invalid chunk name');
throw new NotImplemented($this->l10n->t('Invalid chunk name'));
}

$chunk_handler = new \OC_FileChunking($info);
Expand All @@ -536,7 +563,15 @@ private function createFileChunked($data) {
$expected = (int)$_SERVER['CONTENT_LENGTH'];
if ($bytesWritten !== $expected) {
$chunk_handler->remove($info['index']);
throw new BadRequest('Expected filesize of ' . $expected . ' bytes but read (from Nextcloud client) and wrote (to Nextcloud storage) ' . $bytesWritten . ' bytes. Could either be a network problem on the sending side or a problem writing to the storage on the server side.');
throw new BadRequest(
$this->l10n->t(
'Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side.',
[
$this->l10n->n('%n byte', '%n bytes', $expected),
$this->l10n->n('%n byte', '%n bytes', $bytesWritten),
],
)
);
}
}
}
Expand Down Expand Up @@ -583,7 +618,7 @@ private function createFileChunked($data) {
$targetStorage->unlink($targetInternalPath);
}
$this->fileView->changeLock($targetPath, ILockingProvider::LOCK_SHARED);
throw new Exception('Could not rename part file assembled from chunks');
throw new Exception($this->l10n->t('Could not rename part file assembled from chunks'));
}
} else {
// assemble directly into the final file
Expand Down Expand Up @@ -667,13 +702,13 @@ private function convertToSabreException(\Exception $e) {
}
if ($e instanceof GenericEncryptionException) {
// returning 503 will allow retry of the operation at a later point in time
throw new ServiceUnavailable('Encryption not ready: ' . $e->getMessage(), 0, $e);
throw new ServiceUnavailable($this->l10n->t('Encryption not ready: %1$s', [$e->getMessage()]), 0, $e);
}
if ($e instanceof StorageNotAvailableException) {
throw new ServiceUnavailable('Failed to write file contents: ' . $e->getMessage(), 0, $e);
throw new ServiceUnavailable($this->l10n->t('Failed to write file contents: %1$s', [$e->getMessage()]), 0, $e);
}
if ($e instanceof NotFoundException) {
throw new NotFound('File not found: ' . $e->getMessage(), 0, $e);
throw new NotFound($this->l10n->t('File not found: %1$s', [$e->getMessage()]), 0, $e);
}

throw new \Sabre\DAV\Exception($e->getMessage(), 0, $e);
Expand Down