mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
Merge pull request #40105 from nextcloud/sftp-known-mtime
don't believe sftp when it tells us the mtime is less than we know it is
This commit is contained in:
commit
72e0bb779d
1 changed files with 22 additions and 3 deletions
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -87,6 +91,9 @@ class SFTP extends Common {
|
|||
|
||||
$this->root = '/' . ltrim($this->root, '/');
|
||||
$this->root = rtrim($this->root, '/') . '/';
|
||||
|
||||
$this->knownMTimes = new CappedMemoryCache();
|
||||
|
||||
$this->mimeTypeDetector = \OC::$server->get(IMimeTypeDetector::class);
|
||||
}
|
||||
|
||||
|
|
@ -297,6 +304,7 @@ class SFTP extends Common {
|
|||
}
|
||||
|
||||
public function fopen(string $path, string $mode) {
|
||||
$path = $this->cleanPath($path);
|
||||
try {
|
||||
$absPath = $this->absPath($path);
|
||||
$connection = $this->getConnection();
|
||||
|
|
@ -317,7 +325,13 @@ class SFTP extends Common {
|
|||
// 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+':
|
||||
|
|
@ -343,14 +357,13 @@ class SFTP extends Common {
|
|||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -379,11 +392,17 @@ class SFTP extends Common {
|
|||
*/
|
||||
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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue