summaryrefslogtreecommitdiffstats
path: root/apps/files_external/lib/Lib/Storage
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2023-08-29 22:15:12 +0200
committerbackportbot-nextcloud[bot] <backportbot-nextcloud[bot]@users.noreply.github.com>2023-09-18 17:33:43 +0000
commit6ab32b00ee236394008572ce2aa48b9bd1051dd8 (patch)
treeafe3819c2dfb1ee3b28cfeb501bed429dc411f08 /apps/files_external/lib/Lib/Storage
parent0a219b1dc04278430274c53be1810b9da56f0f21 (diff)
downloadnextcloud-server-6ab32b00ee236394008572ce2aa48b9bd1051dd8.tar.gz
nextcloud-server-6ab32b00ee236394008572ce2aa48b9bd1051dd8.zip
sftp optimize file_put_contents, writeStream and copy
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'apps/files_external/lib/Lib/Storage')
-rw-r--r--apps/files_external/lib/Lib/Storage/SFTP.php56
1 files changed, 55 insertions, 1 deletions
diff --git a/apps/files_external/lib/Lib/Storage/SFTP.php b/apps/files_external/lib/Lib/Storage/SFTP.php
index e2f8480756c..c5a77d25a6d 100644
--- a/apps/files_external/lib/Lib/Storage/SFTP.php
+++ b/apps/files_external/lib/Lib/Storage/SFTP.php
@@ -36,15 +36,18 @@
*/
namespace OCA\Files_External\Lib\Storage;
+use Icewind\Streams\CountWrapper;
use Icewind\Streams\IteratorDirectory;
use Icewind\Streams\RetryWrapper;
+use OC\Files\Filesystem;
+use OC\Files\Storage\Common;
use phpseclib\Net\SFTP\Stream;
/**
* Uses phpseclib's Net\SFTP class and the Net\SFTP\Stream stream wrapper to
* provide access to SFTP servers.
*/
-class SFTP extends \OC\Files\Storage\Common {
+class SFTP extends Common {
private $host;
private $user;
private $root;
@@ -57,6 +60,8 @@ class SFTP extends \OC\Files\Storage\Common {
*/
protected $client;
+ const COPY_CHUNK_SIZE = 8 * 1024 * 1024;
+
/**
* @param string $host protocol://server:port
* @return array [$server, $port]
@@ -478,4 +483,53 @@ class SFTP extends \OC\Files\Storage\Common {
$url = 'sftp://' . urlencode($this->user) . '@' . $this->host . ':' . $this->port . $this->root . $path;
return $url;
}
+
+ public function file_put_contents($path, $data) {
+ $result = $this->getConnection()->put($this->absPath($path), $data);
+ if ($result) {
+ return strlen($data);
+ } else {
+ return false;
+ }
+ }
+
+ public function writeStream(string $path, $stream, int $size = null): int {
+ if ($size === null) {
+ $stream = CountWrapper::wrap($stream, function ($writtenSize) use (&$size) {
+ $size = $writtenSize;
+ });
+ }
+ $result = $this->getConnection()->put($this->absPath($path), $stream);
+ fclose($stream);
+ if ($result) {
+ return $size;
+ } else {
+ throw new \Exception("Failed to write steam to sftp storage");
+ }
+ }
+
+ public function copy($source, $target) {
+ if ($this->is_dir($source) || $this->is_dir($target)) {
+ return parent::copy($source, $target);
+ } else {
+ $absSource = $this->absPath($source);
+ $absTarget = $this->absPath($target);
+
+ $connection = $this->getConnection();
+ $size = $connection->size($absSource);
+ if ($size === false) {
+ return false;
+ }
+ for ($i = 0; $i < $size; $i += self::COPY_CHUNK_SIZE) {
+ $chunk = $connection->get($absSource, false, $i, self::COPY_CHUNK_SIZE);
+ if ($chunk === false) {
+ return false;
+ }
+ if (!$connection->put($absTarget, $chunk, \phpseclib\Net\SFTP::SOURCE_STRING, $i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
}