Skip to content

Commit

Permalink
fix using FSEEK_END with SeekableHttpStream to get file size
Browse files Browse the repository at this point in the history
Signed-off-by: Robin Appelman <robin@icewind.nl>
  • Loading branch information
icewind1991 committed Aug 26, 2022
1 parent aa150b9 commit 66a5067
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
43 changes: 32 additions & 11 deletions lib/private/Files/Stream/SeekableHttpStream.php
Expand Up @@ -79,10 +79,12 @@ public static function open(callable $callback) {
private $offset = 0;
/** @var int */
private $length = 0;
private $needReconnect = false;

private function reconnect(int $start) {
$this->needReconnect = false;
$range = $start . '-';
if ($this->current != null) {
if (is_resource($this->current)) {
fclose($this->current);
}

Expand Down Expand Up @@ -128,6 +130,13 @@ private function reconnect(int $start) {
return true;
}

private function getCurrent() {
if ($this->needReconnect) {
$this->reconnect($this->offset);
}
return $this->current;
}

public function stream_open($path, $mode, $options, &$opened_path) {
$options = stream_context_get_options($this->context)[self::PROTOCOL];
$this->openCallback = $options['callback'];
Expand All @@ -136,10 +145,10 @@ public function stream_open($path, $mode, $options, &$opened_path) {
}

public function stream_read($count) {
if (!$this->current) {
if (!$this->getCurrent()) {
return false;
}
$ret = fread($this->current, $count);
$ret = fread($this->getCurrent(), $count);
$this->offset += strlen($ret);
return $ret;
}
Expand All @@ -149,39 +158,51 @@ public function stream_seek($offset, $whence = SEEK_SET) {
case SEEK_SET:
if ($offset === $this->offset) {
return true;
} else {
$this->offset = $offset;
break;
}
return $this->reconnect($offset);
case SEEK_CUR:
if ($offset === 0) {
return true;
} else {
$this->offset += $offset;
break;
}
return $this->reconnect($this->offset + $offset);
case SEEK_END:
if ($this->length === 0) {
return false;
} elseif ($this->length + $offset === $this->offset) {
return true;
} else {
$this->offset = $this->length + $offset;
break;
}
return $this->reconnect($this->length + $offset);
}
return false;

if (is_resource($this->current)) {
fclose($this->current);
}
$this->current = null;
$this->needReconnect = true;
return true;
}

public function stream_tell() {
return $this->offset;
}

public function stream_stat() {
if (is_resource($this->current)) {
return fstat($this->current);
if (is_resource($this->getCurrent())) {
return fstat($this->getCurrent());
} else {
return false;
}
}

public function stream_eof() {
if (is_resource($this->current)) {
return feof($this->current);
if (is_resource($this->getCurrent())) {
return feof($this->getCurrent());
} else {
return true;
}
Expand Down
15 changes: 15 additions & 0 deletions tests/lib/Files/ObjectStore/ObjectStoreTest.php
Expand Up @@ -143,4 +143,19 @@ public function testCopy() {

$this->assertEquals('foobar', stream_get_contents($instance->readObject('target')));
}

public function testFseekSize() {
$instance = $this->getInstance();

$textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt';
$size = filesize($textFile);
$instance->writeObject('source', fopen($textFile, 'r'));

$fh = $instance->readObject('source');

fseek($fh, 0, SEEK_END);
$pos = ftell($fh);

$this->assertEquals($size, $pos);
}
}
13 changes: 13 additions & 0 deletions tests/lib/Files/Storage/Storage.php
Expand Up @@ -664,4 +664,17 @@ public function testWriteStream() {
$this->assertStringEqualsFile($textFile, $storage->file_get_contents('test.txt'));
$this->assertEquals('resource (closed)', gettype($source));
}

public function testFseekSize() {
$textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt';
$this->instance->file_put_contents('bar.txt', fopen($textFile, 'r'));

$size = $this->instance->filesize('bar.txt');
$fh = $this->instance->fopen('bar.txt', 'r');

fseek($fh, 0, SEEK_END);
$pos = ftell($fh);

$this->assertEquals($size, $pos + 1);
}
}

0 comments on commit 66a5067

Please sign in to comment.