diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2022-12-01 15:42:07 -0100 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2023-09-20 15:18:43 +0200 |
commit | a658135c679889b686affe021ef84d81b142db54 (patch) | |
tree | 0917d2c84705fa98286373c3ecf4a81ad6416c10 | |
parent | dbab6a648b79a51898ff22bae9ae9c3ff9d7b9bf (diff) | |
download | nextcloud-server-fix/noid/refresh-filesize-on-conflict-24.tar.gz nextcloud-server-fix/noid/refresh-filesize-on-conflict-24.zip |
compare cached filesize on downloadfix/noid/refresh-filesize-on-conflict-24
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
-rw-r--r-- | apps/dav/lib/Connector/Sabre/File.php | 14 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/ObjectStoreStorage.php | 14 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/S3ObjectTrait.php | 4 | ||||
-rw-r--r-- | lib/private/Files/Stream/SeekableHttpStream.php | 18 |
4 files changed, 41 insertions, 9 deletions
diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php index 00c7c779eee..27fc17c008b 100644 --- a/apps/dav/lib/Connector/Sabre/File.php +++ b/apps/dav/lib/Connector/Sabre/File.php @@ -45,11 +45,11 @@ use OC\Files\Stream\HashWrapper; use OC\Files\View; use OC\Metadata\FileMetadata; use OCA\DAV\AppInfo\Application; +use OCA\DAV\Connector\Sabre\Exception\BadGateway; use OCA\DAV\Connector\Sabre\Exception\EntityTooLarge; use OCA\DAV\Connector\Sabre\Exception\FileLocked; use OCA\DAV\Connector\Sabre\Exception\Forbidden as DAVForbiddenException; use OCA\DAV\Connector\Sabre\Exception\UnsupportedMediaType; -use OCA\DAV\Connector\Sabre\Exception\BadGateway; use OCP\Encryption\Exceptions\GenericEncryptionException; use OCP\Files\EntityTooLargeException; use OCP\Files\FileInfo; @@ -492,9 +492,21 @@ class File extends Node implements IFile { } catch (\Exception $e) { $this->convertToSabreException($e); } + if ($res === false) { throw new ServiceUnavailable($this->l10n->t('Could not open file')); } + + // comparing current file size with the one in DB + // if different, fix DB and refresh cache. + if ($this->getSize() !== $this->fileView->filesize($this->getPath())) { + $logger = \OC::$server->get(ILogger::class); + $logger->warning('fixing cached size of file id=' . $this->getId()); + + $this->getFileInfo()->getStorage()->getUpdater()->update($this->getFileInfo()->getInternalPath()); + $this->refreshInfo(); + } + return $res; } catch (GenericEncryptionException $e) { // returning 503 will allow retry of the operation at a later point in time diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php index 898f64d97c2..c9210992a3e 100644 --- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php @@ -303,13 +303,23 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { case 'rb': $stat = $this->stat($path); if (is_array($stat)) { + $filesize = $stat['size'] ?? 0; // Reading 0 sized files is a waste of time - if (isset($stat['size']) && $stat['size'] === 0) { + if ($filesize === 0) { return fopen('php://memory', $mode); } try { - return $this->objectStore->readObject($this->getURN($stat['fileid'])); + $handle = $this->objectStore->readObject($this->getURN($stat['fileid'])); + if ($handle === false) { + return false; // keep backward compatibility + } + $streamStat = fstat($handle); + $actualSize = $streamStat['size'] ?? -1; + if ($actualSize > -1 && $actualSize !== $filesize) { + $this->getCache()->update((int)$stat['fileid'], ['size' => $actualSize]); + } + return $handle; } catch (NotFoundException $e) { $this->logger->logException($e, [ 'app' => 'objectstore', diff --git a/lib/private/Files/ObjectStore/S3ObjectTrait.php b/lib/private/Files/ObjectStore/S3ObjectTrait.php index 9d692e01a23..65ef0725973 100644 --- a/lib/private/Files/ObjectStore/S3ObjectTrait.php +++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php @@ -29,9 +29,9 @@ namespace OC\Files\ObjectStore; use Aws\S3\Exception\S3MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client; +use GuzzleHttp\Psr7; use GuzzleHttp\Psr7\Utils; use OC\Files\Stream\SeekableHttpStream; -use GuzzleHttp\Psr7; use Psr\Http\Message\StreamInterface; trait S3ObjectTrait { @@ -47,6 +47,7 @@ trait S3ObjectTrait { /** * @param string $urn the unified resource name used to identify the object + * * @return resource stream with the read data * @throws \Exception when something goes wrong, message will be logged * @since 7.0.0 @@ -88,6 +89,7 @@ trait S3ObjectTrait { }); } + /** * Single object put helper * diff --git a/lib/private/Files/Stream/SeekableHttpStream.php b/lib/private/Files/Stream/SeekableHttpStream.php index 820a681bd07..cf504f46568 100644 --- a/lib/private/Files/Stream/SeekableHttpStream.php +++ b/lib/private/Files/Stream/SeekableHttpStream.php @@ -75,10 +75,13 @@ class SeekableHttpStream implements File { /** @var resource */ private $current; - /** @var int */ - private $offset = 0; - /** @var int */ - private $length = 0; + /** @var int $offset offset of the current chunk */ + private int $offset = 0; + /** @var int $length length of the current chunk */ + private int $length = 0; + /** @var int $totalSize size of the full stream */ + private int $totalSize = 0; + private bool $needReconnect = false; private function reconnect(int $start) { $range = $start . '-'; @@ -124,6 +127,9 @@ class SeekableHttpStream implements File { $this->offset = $begin; $this->length = $length; + if ($start === 0) { + $this->totalSize = $length; + } return true; } @@ -173,7 +179,9 @@ class SeekableHttpStream implements File { public function stream_stat() { if (is_resource($this->current)) { - return fstat($this->current); + $stat = fstat($this->current); + $stat['size'] = $this->totalSize; + return $stat; } else { return false; } |