]> source.dussan.org Git - nextcloud-server.git/commitdiff
add basic tests for s3 seeking and add some error handling if reopen return the wrong...
authorRobin Appelman <robin@icewind.nl>
Thu, 19 Mar 2020 14:28:02 +0000 (15:28 +0100)
committerMorris Jobke <hey@morrisjobke.de>
Fri, 22 May 2020 13:31:10 +0000 (15:31 +0200)
Signed-off-by: Robin Appelman <robin@icewind.nl>
lib/private/Files/Stream/SeekableHttpStream.php
tests/lib/Files/ObjectStore/ObjectStoreTest.php
tests/lib/Files/ObjectStore/S3Test.php

index 80f05f7ea0999f3d526719c1d83b36f1dd2c1df1..8fe54839e2580c30d075cd5e92cc58afdb9baedf 100644 (file)
@@ -76,7 +76,8 @@ class SeekableHttpStream implements File {
        /** @var int */
        private $offset = 0;
 
-       private function reconnect($range) {
+       private function reconnect(int $start) {
+               $range = $start . '-';
                if ($this->current != null) {
                        fclose($this->current);
                }
@@ -88,14 +89,23 @@ class SeekableHttpStream implements File {
                }
 
                $responseHead = stream_get_meta_data($this->current)['wrapper_data'];
-               $contentRange = array_values(array_filter($responseHead, function ($v) {
+               $rangeHeaders = array_values(array_filter($responseHead, function ($v) {
                        return preg_match('#^content-range:#i', $v) === 1;
-               }))[0];
+               }));
+               if (!$rangeHeaders) {
+                       return false;
+               }
+               $contentRange = $rangeHeaders[0];
 
                $content = trim(explode(':', $contentRange)[1]);
                $range = trim(explode(' ', $content)[1]);
-               $begin = explode('-', $range)[0];
-               $this->offset = intval($begin);
+               $begin = intval(explode('-', $range)[0]);
+
+               if ($begin !== $start) {
+                       return false;
+               }
+
+               $this->offset = $begin;
 
                return true;
        }
@@ -104,7 +114,7 @@ class SeekableHttpStream implements File {
                $options = stream_context_get_options($this->context)[self::PROTOCOL];
                $this->openCallback = $options['callback'];
 
-               return $this->reconnect('0-');
+               return $this->reconnect(0);
        }
 
        function stream_read($count) {
@@ -122,12 +132,12 @@ class SeekableHttpStream implements File {
                                if ($offset === $this->offset) {
                                        return true;
                                }
-                               return $this->reconnect($offset . '-');
+                               return $this->reconnect($offset);
                        case SEEK_CUR:
                                if ($offset === 0) {
                                        return true;
                                }
-                               return $this->reconnect(($this->offset + $offset) . '-');
+                               return $this->reconnect($this->offset + $offset);
                        case SEEK_END:
                                return false;
                }
index 1383c0149a22bc0be0555eb4d2961c570d2715df..67c41eb7ccc2eb4a48ba3cfaa5e1a2d347ba44e8 100644 (file)
@@ -31,7 +31,7 @@ abstract class ObjectStoreTest extends TestCase {
         */
        abstract protected function getInstance();
 
-       private function stringToStream($data) {
+       protected function stringToStream($data) {
                $stream = fopen('php://temp', 'w+');
                fwrite($stream, $data);
                rewind($stream);
index 91b24d8b6150fc0f61dcfe62857a1b6680fd2477..b3d65d9eff403ef15400355c458545784ef48e7d 100644 (file)
@@ -27,7 +27,7 @@ use OC\Files\ObjectStore\S3;
 class MultiPartUploadS3 extends S3 {
        function writeObject($urn, $stream) {
                $this->getConnection()->upload($this->bucket, $urn, $stream, 'private', [
-                       'mup_threshold' => 1
+                       'mup_threshold' => 1,
                ]);
        }
 }
@@ -83,4 +83,20 @@ class S3Test extends ObjectStoreTest {
 
                $this->assertEquals(file_get_contents(__FILE__), stream_get_contents($result));
        }
+
+       public function testSeek() {
+               $data = file_get_contents(__FILE__);
+
+               $instance = $this->getInstance();
+               $instance->writeObject('seek', $this->stringToStream($data));
+
+               $read = $instance->readObject('seek');
+               $this->assertEquals(substr($data, 0, 100), fread($read, 100));
+
+               fseek($read, 10);
+               $this->assertEquals(substr($data, 10, 100), fread($read, 100));
+
+               fseek($read, 100, SEEK_CUR);
+               $this->assertEquals(substr($data, 210, 100), fread($read, 100));
+       }
 }