Skip to content

Commit

Permalink
don't believe sftp when it tells us the mtime is less than we know it is
Browse files Browse the repository at this point in the history
Signed-off-by: Robin Appelman <[email protected]>
  • Loading branch information
icewind1991 committed Dec 6, 2024
1 parent 5ee4c9e commit cdc4fa4
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions apps/files_external/lib/Lib/Storage/SFTP.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
*/
namespace OCA\Files_External\Lib\Storage;

use Icewind\Streams\CallbackWrapper;
use Icewind\Streams\CountWrapper;
use Icewind\Streams\IteratorDirectory;
use Icewind\Streams\RetryWrapper;
use OC\Files\Storage\Common;
use OC\Files\View;
use OCP\Cache\CappedMemoryCache;
use OCP\Constants;
use OCP\Files\FileInfo;
use OCP\Files\IMimeTypeDetector;
Expand All @@ -32,6 +34,8 @@ class SFTP extends Common {
* @var \phpseclib\Net\SFTP
*/
protected $client;
private CappedMemoryCache $knownMTimes;

private IMimeTypeDetector $mimeTypeDetector;

public const COPY_CHUNK_SIZE = 8 * 1024 * 1024;
Expand Down Expand Up @@ -87,6 +91,9 @@ public function __construct(array $parameters) {

$this->root = '/' . ltrim($this->root, '/');
$this->root = rtrim($this->root, '/') . '/';

$this->knownMTimes = new CappedMemoryCache();

$this->mimeTypeDetector = \OC::$server->get(IMimeTypeDetector::class);
}

Expand Down Expand Up @@ -297,6 +304,7 @@ public function unlink(string $path): bool {
}

public function fopen(string $path, string $mode) {
$path = $this->cleanPath($path);
try {
$absPath = $this->absPath($path);
$connection = $this->getConnection();
Expand All @@ -317,7 +325,13 @@ public function fopen(string $path, string $mode) {
// the SFTPWriteStream doesn't go through the "normal" methods so it doesn't clear the stat cache.
$connection->_remove_from_stat_cache($absPath);
$context = stream_context_create(['sftp' => ['session' => $connection]]);
return fopen('sftpwrite://' . trim($absPath, '/'), 'w', false, $context);
$fh = fopen('sftpwrite://' . trim($absPath, '/'), 'w', false, $context);
if ($fh) {
$fh = CallbackWrapper::wrap($fh, null, null, function () use ($path) {
$this->knownMTimes->set($path, time());
});
}
return $fh;
case 'a':
case 'ab':
case 'r+':
Expand All @@ -343,14 +357,13 @@ public function touch(string $path, ?int $mtime = null): bool {
return false;
}
if (!$this->file_exists($path)) {
$this->getConnection()->put($this->absPath($path), '');
return $this->getConnection()->put($this->absPath($path), '');
} else {
return false;
}
} catch (\Exception $e) {
return false;
}
return true;
}

/**
Expand Down Expand Up @@ -379,11 +392,17 @@ public function rename(string $source, string $target): bool {
*/
public function stat(string $path): array|false {
try {
$path = $this->cleanPath($path);
$stat = $this->getConnection()->stat($this->absPath($path));

$mtime = isset($stat['mtime']) ? (int)$stat['mtime'] : -1;
$size = isset($stat['size']) ? (int)$stat['size'] : 0;

// the mtime can't be less than when we last touched it
if ($knownMTime = $this->knownMTimes->get($path)) {
$mtime = max($mtime, $knownMTime);
}

return [
'mtime' => $mtime,
'size' => $size,
Expand Down

0 comments on commit cdc4fa4

Please sign in to comment.