Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2016-03-01 22:43:54 +0300
committerVincent Petry <pvince81@owncloud.com>2016-03-01 22:43:54 +0300
commit5200baa9668f9cbbb5f5f693ba5038c55aed56e7 (patch)
tree63f9cbd95a9518c56d366ffcebc8976198312c29
parentee4d57660d6563440fdd61eb9997d0463df136a3 (diff)
parentd32fc2d7718db89e30c636889ebed522db82e5cc (diff)
Merge pull request #22752 from owncloud/part-file-root-82
[stable8.2] allow putting the part file in the view root
-rw-r--r--apps/dav/tests/unit/connector/sabre/requesttest/partfileinrootupload.php56
-rw-r--r--config/config.sample.php10
-rw-r--r--lib/private/connector/sabre/file.php23
-rw-r--r--lib/private/files/storage/wrapper/quota.php27
4 files changed, 104 insertions, 12 deletions
diff --git a/apps/dav/tests/unit/connector/sabre/requesttest/partfileinrootupload.php b/apps/dav/tests/unit/connector/sabre/requesttest/partfileinrootupload.php
new file mode 100644
index 00000000000..52790c5b00b
--- /dev/null
+++ b/apps/dav/tests/unit/connector/sabre/requesttest/partfileinrootupload.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\DAV\Tests\Unit\Connector\Sabre\RequestTest;
+
+use OC\Files\View;
+use Test\Traits\EncryptionTrait;
+
+/**
+ * Class EncryptionUploadTest
+ *
+ * @group DB
+ *
+ * @package OCA\DAV\Tests\Unit\Connector\Sabre\RequestTest
+ */
+class PartFileInRootUpload extends UploadTest {
+ protected function setUp() {
+ $config = \OC::$server->getConfig();
+ $mockConfig = $this->getMock('\OCP\IConfig');
+ $mockConfig->expects($this->any())
+ ->method('getSystemValue')
+ ->will($this->returnCallback(function ($key, $default) use ($config) {
+ if ($key === 'part_file_in_storage') {
+ return false;
+ } else {
+ return $config->getSystemValue($key, $default);
+ }
+ }));
+ $this->overwriteService('AllConfig', $mockConfig);
+ parent::setUp();
+ }
+
+ protected function tearDown() {
+ $this->restoreService('AllConfig');
+ return parent::tearDown();
+ }
+}
diff --git a/config/config.sample.php b/config/config.sample.php
index d572adf1a05..31ebd2d0321 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -406,7 +406,7 @@ $CONFIG = array(
* delete all files in the trash bin that are older than D days
* automatically, delete other files anytime if space needed
* * ``D1, D2``
- * keep files and folders the in trash bin for at least D1 days and
+ * keep files and folders the in trash bin for at least D1 days and
* delete when exceeds D2 days
* * ``disabled``
* trash bin auto clean disabled, files and folders will be kept forever
@@ -1060,6 +1060,14 @@ $CONFIG = array(
'filesystem_check_changes' => 0,
/**
+ * On default ownCloud will store the part files created during upload in the
+ * same storage as the upload target. Setting this to false will store the part
+ * files in the root of the users folder which might be required to work with certain
+ * external storage setups that have limited rename capabilities.
+ */
+'part_file_in_storage' => true,
+
+/**
* All css and js files will be served by the web server statically in one js
* file and one css file if this is set to ``true``. This improves performance.
*/
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 50c9bbf5bc4..76a82e49416 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -109,7 +109,7 @@ class File extends Node implements IFile {
if ($needsPartFile) {
// mark file as partial while uploading (ignored by the scanner)
- $partFilePath = $this->path . '.ocTransferId' . rand() . '.part';
+ $partFilePath = $this->getPartFileBasePath($this->path) . '.ocTransferId' . rand() . '.part';
} else {
// upload file directly as the final path
$partFilePath = $this->path;
@@ -130,12 +130,12 @@ class File extends Node implements IFile {
list($count, $result) = \OC_Helper::streamCopy($data, $target);
fclose($target);
- if($result === false) {
+ if ($result === false) {
$expected = -1;
if (isset($_SERVER['CONTENT_LENGTH'])) {
$expected = $_SERVER['CONTENT_LENGTH'];
}
- throw new Exception('Error while copying file to target location (copied bytes: ' . $count . ', expected filesize: '. $expected .' )');
+ throw new Exception('Error while copying file to target location (copied bytes: ' . $count . ', expected filesize: ' . $expected . ' )');
}
// if content length is sent by client:
@@ -217,6 +217,18 @@ class File extends Node implements IFile {
return '"' . $this->info->getEtag() . '"';
}
+ private function getPartFileBasePath($path) {
+ $partFileInStorage = \OC::$server->getConfig()->getSystemValue('part_file_in_storage', true);
+ if ($partFileInStorage) {
+ return $path;
+ } else {
+ return md5($path); // will place it in the root of the view with a unique name
+ }
+ }
+
+ /**
+ * @param string $path
+ */
private function emitPreHooks($exists, $path = null) {
if (is_null($path)) {
$path = $this->path;
@@ -390,9 +402,8 @@ class File extends Node implements IFile {
if ($needsPartFile) {
// we first assembly the target file as a part file
- $partFile = $path . '/' . $info['name'] . '.ocTransferId' . $info['transferid'] . '.part';
-
-
+ $partFile = $this->getPartFileBasePath($path . '/' . $info['name']) . '.ocTransferId' . $info['transferid'] . '.part';
+ /** @var \OC\Files\Storage\Storage $targetStorage */
list($partStorage, $partInternalPath) = $this->fileView->resolvePath($partFile);
diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php
index 98664e27e2d..00680841b2a 100644
--- a/lib/private/files/storage/wrapper/quota.php
+++ b/lib/private/files/storage/wrapper/quota.php
@@ -139,17 +139,34 @@ class Quota extends Wrapper {
*/
public function fopen($path, $mode) {
$source = $this->storage->fopen($path, $mode);
- $free = $this->free_space('');
- if ($source && $free >= 0 && $mode !== 'r' && $mode !== 'rb') {
- // only apply quota for files, not metadata, trash or others
- if (strpos(ltrim($path, '/'), 'files/') === 0) {
- return \OC\Files\Stream\Quota::wrap($source, $free);
+
+ // don't apply quota for part files
+ if (!$this->isPartFile($path)) {
+ $free = $this->free_space('');
+ if ($source && $free >= 0 && $mode !== 'r' && $mode !== 'rb') {
+ // only apply quota for files, not metadata, trash or others
+ if (strpos(ltrim($path, '/'), 'files/') === 0) {
+ return \OC\Files\Stream\Quota::wrap($source, $free);
+ }
}
}
return $source;
}
/**
+ * Checks whether the given path is a part file
+ *
+ * @param string $path Path that may identify a .part file
+ * @return string File path without .part extension
+ * @note this is needed for reusing keys
+ */
+ private function isPartFile($path) {
+ $extension = pathinfo($path, PATHINFO_EXTENSION);
+
+ return ($extension === 'part');
+ }
+
+ /**
* @param \OCP\Files\Storage $sourceStorage
* @param string $sourceInternalPath
* @param string $targetInternalPath