Skip to content

Commit

Permalink
compare cached filesize on download
Browse files Browse the repository at this point in the history
Signed-off-by: Maxence Lange <[email protected]>
  • Loading branch information
ArtificialOwl authored and icewind1991 committed Sep 20, 2023
1 parent dbab6a6 commit a658135
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 9 deletions.
14 changes: 13 additions & 1 deletion apps/dav/lib/Connector/Sabre/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@
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;
Expand Down Expand Up @@ -492,9 +492,21 @@ public function get() {
} 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
Expand Down
14 changes: 12 additions & 2 deletions lib/private/Files/ObjectStore/ObjectStoreStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,23 @@ public function fopen($path, $mode) {
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',
Expand Down
4 changes: 3 additions & 1 deletion lib/private/Files/ObjectStore/S3ObjectTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
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 {
Expand All @@ -47,6 +47,7 @@ abstract protected function getCertificateBundlePath(): ?string;

/**
* @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
Expand Down Expand Up @@ -88,6 +89,7 @@ public function readObject($urn) {
});
}


/**
* Single object put helper
*
Expand Down
18 changes: 13 additions & 5 deletions lib/private/Files/Stream/SeekableHttpStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@ public static function open(callable $callback) {

/** @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 . '-';
Expand Down Expand Up @@ -124,6 +127,9 @@ private function reconnect(int $start) {

$this->offset = $begin;
$this->length = $length;
if ($start === 0) {
$this->totalSize = $length;
}

return true;
}
Expand Down Expand Up @@ -173,7 +179,9 @@ public function stream_tell() {

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;
}
Expand Down

0 comments on commit a658135

Please sign in to comment.