Skip to content

Commit cda568a

Browse files
committed
buble up the stream size trough the seekable wrapper instead of using an exception
Signed-off-by: Robin Appelman <[email protected]>
1 parent 29eceae commit cda568a

12 files changed

Lines changed: 27 additions & 120 deletions

File tree

lib/composer/composer/autoload_classmap.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,6 @@
301301
'OCP\\Files\\Events\\Node\\NodeRenamedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeRenamedEvent.php',
302302
'OCP\\Files\\Events\\Node\\NodeTouchedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeTouchedEvent.php',
303303
'OCP\\Files\\Events\\Node\\NodeWrittenEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeWrittenEvent.php',
304-
'OCP\\Files\\ExpectedFileSizeException' => $baseDir . '/lib/public/Files/ExpectedFileSizeException.php',
305304
'OCP\\Files\\File' => $baseDir . '/lib/public/Files/File.php',
306305
'OCP\\Files\\FileInfo' => $baseDir . '/lib/public/Files/FileInfo.php',
307306
'OCP\\Files\\FileNameTooLongException' => $baseDir . '/lib/public/Files/FileNameTooLongException.php',

lib/composer/composer/autoload_static.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
334334
'OCP\\Files\\Events\\Node\\NodeRenamedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeRenamedEvent.php',
335335
'OCP\\Files\\Events\\Node\\NodeTouchedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeTouchedEvent.php',
336336
'OCP\\Files\\Events\\Node\\NodeWrittenEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeWrittenEvent.php',
337-
'OCP\\Files\\ExpectedFileSizeException' => __DIR__ . '/../../..' . '/lib/public/Files/ExpectedFileSizeException.php',
338337
'OCP\\Files\\File' => __DIR__ . '/../../..' . '/lib/public/Files/File.php',
339338
'OCP\\Files\\FileInfo' => __DIR__ . '/../../..' . '/lib/public/Files/FileInfo.php',
340339
'OCP\\Files\\FileNameTooLongException' => __DIR__ . '/../../..' . '/lib/public/Files/FileNameTooLongException.php',

lib/private/Files/ObjectStore/Azure.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public function getStorageId() {
9595
* @return resource stream with the read data
9696
* @throws \Exception when something goes wrong, message will be logged
9797
*/
98-
public function readObject($urn, int $expectedFileSize = -1) {
98+
public function readObject($urn) {
9999
$blob = $this->getBlobClient()->getBlob($this->containerName, $urn);
100100
return $blob->getContentStream();
101101
}

lib/private/Files/ObjectStore/ObjectStoreStorage.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,10 +311,13 @@ public function fopen($path, $mode) {
311311
}
312312

313313
try {
314-
return $this->objectStore->readObject($this->getURN($stat['fileid']), $filesize);
315-
} catch (ExpectedFileSizeException $e) {
316-
$this->getCache()->update((int)$stat['fileid'], ['size' => $e->getActualFileSize()]);
317-
return $this->objectStore->readObject($this->getURN($stat['fileid']));
314+
$handle = $this->objectStore->readObject($this->getURN($stat['fileid']), $filesize);
315+
$streamStat = fstat($handle);
316+
$actualSize = (int)$streamStat['size'] ?? -1;
317+
if ($actualSize > -1 && $actualSize != $filesize) {
318+
$this->getCache()->update((int)$stat['fileid'], ['size' => $actualSize]);
319+
}
320+
return $handle;
318321
} catch (NotFoundException $e) {
319322
$this->logger->logException($e, [
320323
'app' => 'objectstore',

lib/private/Files/ObjectStore/S3ObjectTrait.php

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
use GuzzleHttp\Psr7;
3333
use GuzzleHttp\Psr7\Utils;
3434
use OC\Files\Stream\SeekableHttpStream;
35-
use OCP\Files\ExpectedFileSizeException;
3635
use Psr\Http\Message\StreamInterface;
3736

3837
trait S3ObjectTrait {
@@ -53,8 +52,8 @@ abstract protected function getCertificateBundlePath(): ?string;
5352
* @throws \Exception when something goes wrong, message will be logged
5453
* @since 7.0.0
5554
*/
56-
public function readObject($urn, int $expectedFileSize = -1) {
57-
return SeekableHttpStream::open(function ($range) use ($urn, $expectedFileSize) {
55+
public function readObject($urn) {
56+
return SeekableHttpStream::open(function ($range) use ($urn) {
5857
$command = $this->getConnection()->getCommand('GetObject', [
5958
'Bucket' => $this->bucket,
6059
'Key' => $urn,
@@ -86,50 +85,11 @@ public function readObject($urn, int $expectedFileSize = -1) {
8685
}
8786

8887
$context = stream_context_create($opts);
89-
$res = fopen($request->getUri(), 'r', false, $context);
90-
91-
if (substr($range, 0, 2) !== '0-') {
92-
return $res;
93-
}
94-
95-
$actualContentLength = $this->extractDataContentLength($res);
96-
if ($actualContentLength > -1
97-
&& $expectedFileSize > -1
98-
&& $actualContentLength !== $expectedFileSize) {
99-
throw new ExpectedFileSizeException(
100-
'cached file size conflict',
101-
$actualContentLength
102-
);
103-
}
104-
105-
return $res;
88+
return fopen($request->getUri(), 'r', false, $context);
10689
});
10790
}
10891

10992

110-
/**
111-
* will return -1 if $res is a bool (not a resource)
112-
*
113-
* @param resource $res
114-
*
115-
* @return int
116-
*/
117-
private function extractDataContentLength($res): int {
118-
if (is_bool($res)) {
119-
return -1;
120-
}
121-
122-
$data = stream_get_meta_data($res)['wrapper_data'];
123-
foreach ($data as $entry) {
124-
if (strtolower(substr($entry, 0, 16)) === 'content-length: ') {
125-
return (int)substr($entry, 16);
126-
}
127-
}
128-
129-
return -1;
130-
}
131-
132-
13393
/**
13494
* Single object put helper
13595
*

lib/private/Files/ObjectStore/StorageObjectStore.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function getStorageId() {
5555
* @throws \Exception when something goes wrong, message will be logged
5656
* @since 7.0.0
5757
*/
58-
public function readObject($urn, int $expectedFileSize = -1) {
58+
public function readObject($urn) {
5959
$handle = $this->storage->fopen($urn, 'r');
6060
if (is_resource($handle)) {
6161
return $handle;

lib/private/Files/ObjectStore/Swift.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public function writeObject($urn, $stream, string $mimetype = null) {
101101
* @throws \Exception from openstack or GuzzleHttp libs when something goes wrong
102102
* @throws NotFoundException if file does not exist
103103
*/
104-
public function readObject($urn, int $expectedFileSize = -1) {
104+
public function readObject($urn) {
105105
try {
106106
$publicUri = $this->getContainer()->getObject($urn)->getPublicUri();
107107
$tokenId = $this->swiftFactory->getCachedTokenId();

lib/private/Files/Stream/SeekableHttpStream.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ public static function open(callable $callback) {
7575

7676
/** @var ?resource|closed-resource */
7777
private $current;
78-
private int $offset = 0;
79-
private int $length = 0;
78+
private int $offset = 0; // offset of the current chunk
79+
private int $length = 0; // length of the current chunk
80+
private int $totalSize = 0; // size of the full stream
8081
private bool $needReconnect = false;
8182

8283
private function reconnect(int $start): bool {
@@ -128,6 +129,9 @@ private function reconnect(int $start): bool {
128129

129130
$this->offset = $begin;
130131
$this->length = $length;
132+
if ($start === 0) {
133+
$this->totalSize = $length;
134+
}
131135

132136
return true;
133137
}
@@ -211,7 +215,9 @@ public function stream_tell() {
211215

212216
public function stream_stat() {
213217
if ($this->getCurrent()) {
214-
return fstat($this->getCurrent());
218+
$stat = fstat($this->getCurrent());
219+
$stat['size'] = $this->totalSize;
220+
return $stat;
215221
} else {
216222
return false;
217223
}

lib/public/Files/ExpectedFileSizeException.php

Lines changed: 0 additions & 59 deletions
This file was deleted.

lib/public/Files/ObjectStore/IObjectStore.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,12 @@ public function getStorageId();
4141

4242
/**
4343
* @param string $urn the unified resource name used to identify the object
44-
* @param int $expectedFileSize the expectedFileSize to compare the current real filesize
4544
* @return resource stream with the read data
4645
* @throws \Exception when something goes wrong, message will be logged
4746
* @throws NotFoundException if file does not exist
4847
* @since 7.0.0
4948
*/
50-
public function readObject($urn, int $expectedFileSize = -1);
49+
public function readObject($urn);
5150

5251
/**
5352
* @param string $urn the unified resource name used to identify the object

0 commit comments

Comments
 (0)