aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/base.php17
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/Cache/File.php24
-rw-r--r--lib/private/Server.php1
-rw-r--r--lib/private/legacy/OC_FileChunking.php184
6 files changed, 210 insertions, 18 deletions
diff --git a/lib/base.php b/lib/base.php
index 452d6ecc05d..b5c5845b5a0 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -855,6 +855,23 @@ class OC {
$throttler = Server::get(\OC\Security\Bruteforce\Throttler::class);
$throttler->resetDelay($request->getRemoteAddress(), 'login', ['user' => $uid]);
}
+
+ try {
+ $cache = new \OC\Cache\File();
+ $cache->gc();
+ } catch (\OC\ServerNotAvailableException $e) {
+ // not a GC exception, pass it on
+ throw $e;
+ } catch (\OC\ForbiddenException $e) {
+ // filesystem blocked for this request, ignore
+ } catch (\Exception $e) {
+ // a GC exception should not prevent users from using OC,
+ // so log the exception
+ Server::get(LoggerInterface::class)->warning('Exception when running cache gc.', [
+ 'app' => 'core',
+ 'exception' => $e,
+ ]);
+ }
});
}
}
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 8a32b3bd262..62f66dca67b 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1620,6 +1620,7 @@ return array(
'OC_App' => $baseDir . '/lib/private/legacy/OC_App.php',
'OC_Defaults' => $baseDir . '/lib/private/legacy/OC_Defaults.php',
'OC_EventSource' => $baseDir . '/lib/private/legacy/OC_EventSource.php',
+ 'OC_FileChunking' => $baseDir . '/lib/private/legacy/OC_FileChunking.php',
'OC_Files' => $baseDir . '/lib/private/legacy/OC_Files.php',
'OC_Helper' => $baseDir . '/lib/private/legacy/OC_Helper.php',
'OC_Hook' => $baseDir . '/lib/private/legacy/OC_Hook.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 09a4c92a08f..33d63a26e3e 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1653,6 +1653,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC_App' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_App.php',
'OC_Defaults' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Defaults.php',
'OC_EventSource' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_EventSource.php',
+ 'OC_FileChunking' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_FileChunking.php',
'OC_Files' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Files.php',
'OC_Helper' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Helper.php',
'OC_Hook' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Hook.php',
diff --git a/lib/private/Cache/File.php b/lib/private/Cache/File.php
index 56200bda6fa..1f63e462bb5 100644
--- a/lib/private/Cache/File.php
+++ b/lib/private/Cache/File.php
@@ -35,27 +35,11 @@ use OCP\ICache;
use OCP\Security\ISecureRandom;
use Psr\Log\LoggerInterface;
-/**
- * @deprecated 26.0.0
- */
class File implements ICache {
/** @var View */
protected $storage;
/**
- * Set the cache storage for a user
- */
- public function setUpStorage(string $userId) {
- Filesystem::initMountPoints($userId);
- $rootView = new View();
- if (!$rootView->file_exists('/' . $userId . '/cache')) {
- $rootView->mkdir('/' . $userId . '/cache');
- }
- $this->storage = new View('/' . $userId . '/cache');
- return $this->storage;
- }
-
- /**
* Returns the cache storage for the logged in user
*
* @return \OC\Files\View cache storage
@@ -67,8 +51,14 @@ class File implements ICache {
return $this->storage;
}
if (\OC::$server->getUserSession()->isLoggedIn()) {
+ $rootView = new View();
$user = \OC::$server->getUserSession()->getUser();
- return $this->setUpStorage($user->getUID());
+ Filesystem::initMountPoints($user->getUID());
+ if (!$rootView->file_exists('/' . $user->getUID() . '/cache')) {
+ $rootView->mkdir('/' . $user->getUID() . '/cache');
+ }
+ $this->storage = new View('/' . $user->getUID() . '/cache');
+ return $this->storage;
} else {
\OC::$server->get(LoggerInterface::class)->error('Can\'t get cache storage, user not logged in', ['app' => 'core']);
throw new \OC\ForbiddenException('Can\t get cache storage, user not logged in');
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 6ef805a4d85..35f63686457 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -708,7 +708,6 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerService(ICache::class, function ($c) {
return new Cache\File();
});
-
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('UserCache', ICache::class);
diff --git a/lib/private/legacy/OC_FileChunking.php b/lib/private/legacy/OC_FileChunking.php
new file mode 100644
index 00000000000..e3782cabb4a
--- /dev/null
+++ b/lib/private/legacy/OC_FileChunking.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ *
+ * @author Bart Visscher <bartv@thisnet.nl>
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
+ * @author Felix Moeller <mail@felixmoeller.de>
+ * @author Jörn Friedrich Dreyer <jfd@butonic.de>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin Appelman <robin@icewind.nl>
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Thomas Tanghus <thomas@tanghus.net>
+ * @author Vincent Petry <vincent@nextcloud.com>
+ *
+ * @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/>
+ *
+ */
+class OC_FileChunking {
+ protected $info;
+ protected $cache;
+
+ /**
+ * TTL of chunks
+ *
+ * @var int
+ */
+ protected $ttl;
+
+ public static function decodeName($name) {
+ preg_match('/(?P<name>.*)-chunking-(?P<transferid>\d+)-(?P<chunkcount>\d+)-(?P<index>\d+)/', $name, $matches);
+ return $matches;
+ }
+
+ /**
+ * @param string[] $info
+ */
+ public function __construct($info) {
+ $this->info = $info;
+ $this->ttl = \OC::$server->getConfig()->getSystemValue('cache_chunk_gc_ttl', 86400);
+ }
+
+ public function getPrefix() {
+ $name = $this->info['name'];
+ $transferid = $this->info['transferid'];
+
+ return $name.'-chunking-'.$transferid.'-';
+ }
+
+ protected function getCache() {
+ if (!isset($this->cache)) {
+ $this->cache = new \OC\Cache\File();
+ }
+ return $this->cache;
+ }
+
+ /**
+ * Stores the given $data under the given $key - the number of stored bytes is returned
+ *
+ * @param string $index
+ * @param resource $data
+ * @return int
+ */
+ public function store($index, $data) {
+ $cache = $this->getCache();
+ $name = $this->getPrefix().$index;
+ $cache->set($name, $data, $this->ttl);
+
+ return $cache->size($name);
+ }
+
+ public function isComplete() {
+ $prefix = $this->getPrefix();
+ $cache = $this->getCache();
+ $chunkcount = (int)$this->info['chunkcount'];
+
+ for ($i = ($chunkcount - 1); $i >= 0; $i--) {
+ if (!$cache->hasKey($prefix.$i)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Assembles the chunks into the file specified by the path.
+ * Chunks are deleted afterwards.
+ *
+ * @param resource $f target path
+ *
+ * @return integer assembled file size
+ *
+ * @throws \OC\InsufficientStorageException when file could not be fully
+ * assembled due to lack of free space
+ */
+ public function assemble($f) {
+ $cache = $this->getCache();
+ $prefix = $this->getPrefix();
+ $count = 0;
+ for ($i = 0; $i < $this->info['chunkcount']; $i++) {
+ $chunk = $cache->get($prefix.$i);
+ // remove after reading to directly save space
+ $cache->remove($prefix.$i);
+ $count += fwrite($f, $chunk);
+ // let php release the memory to work around memory exhausted error with php 5.6
+ $chunk = null;
+ }
+
+ return $count;
+ }
+
+ /**
+ * Returns the size of the chunks already present
+ * @return integer size in bytes
+ */
+ public function getCurrentSize() {
+ $cache = $this->getCache();
+ $prefix = $this->getPrefix();
+ $total = 0;
+ for ($i = 0; $i < $this->info['chunkcount']; $i++) {
+ $total += $cache->size($prefix.$i);
+ }
+ return $total;
+ }
+
+ /**
+ * Removes all chunks which belong to this transmission
+ */
+ public function cleanup() {
+ $cache = $this->getCache();
+ $prefix = $this->getPrefix();
+ for ($i = 0; $i < $this->info['chunkcount']; $i++) {
+ $cache->remove($prefix.$i);
+ }
+ }
+
+ /**
+ * Removes one specific chunk
+ * @param string $index
+ */
+ public function remove($index) {
+ $cache = $this->getCache();
+ $prefix = $this->getPrefix();
+ $cache->remove($prefix.$index);
+ }
+
+ /**
+ * Assembles the chunks into the file specified by the path.
+ * Also triggers the relevant hooks and proxies.
+ *
+ * @param \OC\Files\Storage\Storage $storage storage
+ * @param string $path target path relative to the storage
+ * @return bool true on success or false if file could not be created
+ *
+ * @throws \OC\ServerNotAvailableException
+ */
+ public function file_assemble($storage, $path) {
+ // use file_put_contents as method because that best matches what this function does
+ if (\OC\Files\Filesystem::isValidPath($path)) {
+ $target = $storage->fopen($path, 'w');
+ if ($target) {
+ $count = $this->assemble($target);
+ fclose($target);
+ return $count > 0;
+ } else {
+ return false;
+ }
+ }
+ return false;
+ }
+}