diff options
author | Robin Appelman <robin@icewind.nl> | 2023-08-29 22:15:12 +0200 |
---|---|---|
committer | backportbot-nextcloud[bot] <backportbot-nextcloud[bot]@users.noreply.github.com> | 2023-09-18 17:33:43 +0000 |
commit | 6ab32b00ee236394008572ce2aa48b9bd1051dd8 (patch) | |
tree | afe3819c2dfb1ee3b28cfeb501bed429dc411f08 /apps/files_external/lib/Lib/Storage | |
parent | 0a219b1dc04278430274c53be1810b9da56f0f21 (diff) | |
download | nextcloud-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.php | 56 |
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; + } + } } |