From eff78f96701daea2add807da52a0c8c6411b1d71 Mon Sep 17 00:00:00 2001 From: Everly Precia Suresh Date: Thu, 8 Sep 2022 16:40:57 +0000 Subject: [PATCH 1/7] trim root --- src/Storage/Device/S3.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storage/Device/S3.php b/src/Storage/Device/S3.php index 13080282..f4fb9ac3 100644 --- a/src/Storage/Device/S3.php +++ b/src/Storage/Device/S3.php @@ -112,7 +112,7 @@ public function __construct(string $root, string $accessKey, string $secretKey, $this->secretKey = $secretKey; $this->bucket = $bucket; $this->region = $region; - $this->root = $root; + $this->root = trim( $root,"/" ); $this->acl = $acl; $this->headers['host'] = $this->bucket . '.s3.'.$this->region.'.amazonaws.com'; $this->amzHeaders = []; From 8ef6fa7b52e6a692df8df185dbe7d3d5bed5b321 Mon Sep 17 00:00:00 2001 From: Everly Precia Suresh Date: Tue, 13 Sep 2022 12:56:32 +0000 Subject: [PATCH 2/7] Modify tests --- src/Storage/Device/S3.php | 2 +- tests/Storage/Device/LinodeTest.php | 2 +- tests/Storage/S3Base.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Storage/Device/S3.php b/src/Storage/Device/S3.php index f4fb9ac3..bfd59a82 100644 --- a/src/Storage/Device/S3.php +++ b/src/Storage/Device/S3.php @@ -112,7 +112,7 @@ public function __construct(string $root, string $accessKey, string $secretKey, $this->secretKey = $secretKey; $this->bucket = $bucket; $this->region = $region; - $this->root = trim( $root,"/" ); + $this->root = trim($root, "/"); $this->acl = $acl; $this->headers['host'] = $this->bucket . '.s3.'.$this->region.'.amazonaws.com'; $this->amzHeaders = []; diff --git a/tests/Storage/Device/LinodeTest.php b/tests/Storage/Device/LinodeTest.php index e5808fe5..cfc0131c 100644 --- a/tests/Storage/Device/LinodeTest.php +++ b/tests/Storage/Device/LinodeTest.php @@ -9,7 +9,7 @@ class LinodeTest extends S3Base { protected function init(): void { - $this->root = 'root'; + $this->root = '/root'; $key = $_SERVER['LINODE_ACCESS_KEY'] ?? ''; $secret = $_SERVER['LINODE_SECRET'] ?? ''; $bucket = 'everly-test'; diff --git a/tests/Storage/S3Base.php b/tests/Storage/S3Base.php index 30a27b2b..5c83cc84 100644 --- a/tests/Storage/S3Base.php +++ b/tests/Storage/S3Base.php @@ -68,12 +68,12 @@ public function testDescription() public function testRoot() { - $this->assertEquals($this->root, $this->object->getRoot()); + $this->assertEquals( trim($this->root, "/"), $this->object->getRoot()); } public function testPath() { - $this->assertEquals($this->root . '/image.png', $this->object->getPath('image.png')); + $this->assertEquals(trim($this->root, "/") . '/image.png', $this->object->getPath('image.png')); } public function testWrite() From 242a614a1fbeeb58d9e04078027fa15a8c30bbe9 Mon Sep 17 00:00:00 2001 From: Everly Precia Suresh Date: Fri, 14 Oct 2022 14:22:59 +0000 Subject: [PATCH 3/7] retrigger build From 44f0c4a74814225f883e72fc2dd83e7e7b436b51 Mon Sep 17 00:00:00 2001 From: Everly Precia Suresh Date: Tue, 18 Oct 2022 16:39:19 +0000 Subject: [PATCH 4/7] rerun build --- src/Storage/Device/S3.php | 68 ++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/Storage/Device/S3.php b/src/Storage/Device/S3.php index bfd59a82..d6eda455 100644 --- a/src/Storage/Device/S3.php +++ b/src/Storage/Device/S3.php @@ -68,22 +68,22 @@ class S3 extends Device * @var string */ protected $bucket; - + /** * @var string */ protected $region; - + /** * @var string */ protected $acl = self::ACL_PRIVATE; - + /** * @var string */ protected $root = 'temp'; - + /** * @var array */ @@ -114,7 +114,7 @@ public function __construct(string $root, string $accessKey, string $secretKey, $this->region = $region; $this->root = trim($root, "/"); $this->acl = $acl; - $this->headers['host'] = $this->bucket . '.s3.'.$this->region.'.amazonaws.com'; + $this->headers['host'] = $this->bucket . '.s3.' . $this->region . '.amazonaws.com'; $this->amzHeaders = []; } @@ -171,11 +171,11 @@ public function getPath(string $filename, string $prefix = null): string */ public function upload(string $source, string $path, int $chunk = 1, int $chunks = 1, array &$metadata = []): int { - if($chunk == 1 && $chunks == 1) { + if ($chunk == 1 && $chunks == 1) { return $this->write($path, \file_get_contents($source), \mime_content_type($source)); } $uploadId = $metadata['uploadId'] ?? null; - if(empty($uploadId)) { + if (empty($uploadId)) { $uploadId = $this->createMultipartUpload($path, $metadata['content_type']); $metadata['uploadId'] = $uploadId; } @@ -185,7 +185,7 @@ public function upload(string $source, string $path, int $chunk = 1, int $chunks $metadata['parts'][] = ['partNumber' => $chunk, 'etag' => $etag]; $metadata['chunks'] ??= 0; $metadata['chunks']++; - if($metadata['chunks'] == $chunks) { + if ($metadata['chunks'] == $chunks) { $this->completeMultipartUpload($path, $uploadId, $metadata['parts']); } return $metadata['chunks']; @@ -227,10 +227,10 @@ protected function createMultipartUpload(string $path, string $contentType): str * * @return string */ - protected function uploadPart(string $source, string $path, int $chunk, string $uploadId) : string + protected function uploadPart(string $source, string $path, int $chunk, string $uploadId): string { $uri = $path !== '' ? '/' . \str_replace(['%2F', '%3F'], ['/', '?'], \rawurlencode($path)) : '/'; - + $data = \file_get_contents($source); $this->headers['content-type'] = \mime_content_type($source); $this->headers['content-md5'] = \base64_encode(md5($data, true)); @@ -238,7 +238,7 @@ protected function uploadPart(string $source, string $path, int $chunk, string $ unset($this->amzHeaders['x-amz-acl']); // ACL header is not allowed in parts, only createMultipartUpload accepts this header. $response = $this->call(self::METHOD_PUT, $uri, $data, [ - 'partNumber'=>$chunk, + 'partNumber' => $chunk, 'uploadId' => $uploadId ]); @@ -268,7 +268,7 @@ protected function completeMultipartUpload(string $path, string $uploadId, array $this->amzHeaders['x-amz-content-sha256'] = \hash('sha256', $body); $this->headers['content-md5'] = \base64_encode(md5($body, true)); - $this->call(self::METHOD_POST, $uri, $body , ['uploadId' => $uploadId]); + $this->call(self::METHOD_POST, $uri, $body, ['uploadId' => $uploadId]); return true; } @@ -309,7 +309,7 @@ public function read(string $path, int $offset = 0, int $length = null): string unset($this->headers['content-type']); $this->headers['content-md5'] = \base64_encode(md5('', true)); $uri = ($path !== '') ? '/' . \str_replace('%2F', '/', \rawurlencode($path)) : '/'; - if($length !== null) { + if ($length !== null) { $end = $offset + $length - 1; $this->headers['range'] = "bytes=$offset-$end"; } @@ -330,7 +330,7 @@ public function read(string $path, int $offset = 0, int $length = null): string public function write(string $path, string $data, string $contentType = ''): bool { $uri = $path !== '' ? '/' . \str_replace(['%2F', '%3F'], ['/', '?'], \rawurlencode($path)) : '/'; - + $this->headers['content-type'] = $contentType; $this->headers['content-md5'] = \base64_encode(md5($data, true)); //TODO whould this work well with big file? can we skip it? $this->amzHeaders['x-amz-content-sha256'] = \hash('sha256', $data); @@ -378,7 +378,7 @@ public function move(string $source, string $target): bool public function delete(string $path, bool $recursive = false): bool { $uri = ($path !== '') ? '/' . \str_replace('%2F', '/', \rawurlencode($path)) : '/'; - + unset($this->headers['content-type']); unset($this->amzHeaders['x-amz-acl']); unset($this->amzHeaders['x-amz-content-sha256']); @@ -408,7 +408,7 @@ private function listObjects($prefix = '', $maxKeys = 1000, $continuationToken = 'prefix' => $prefix, 'max-keys' => $maxKeys, ]; - if(!empty($continuationToken)) { + if (!empty($continuationToken)) { $parameters['continuation-token'] = $continuationToken; } $response = $this->call(self::METHOD_GET, $uri, '', $parameters); @@ -432,24 +432,24 @@ public function deletePath(string $path): bool do { $objects = $this->listObjects($path, continuationToken: $continuationToken); $count = (int) ($objects['KeyCount'] ?? 1); - if($count < 1) { + if ($count < 1) { break; } $continuationToken = $objects['NextContinuationToken'] ?? ''; $body = ''; - if($count > 1) { + if ($count > 1) { foreach ($objects['Contents'] as $object) { $body .= "{$object['Key']}"; } } else { - $body .= "{$objects['Contents']['Key']}"; + $body .= "{$objects['Contents']['Key']}"; } $body .= 'true'; $body .= ''; $this->amzHeaders['x-amz-content-sha256'] = \hash('sha256', $body); $this->headers['content-md5'] = \base64_encode(md5($body, true)); - $this->call(self::METHOD_POST, $uri, $body, ['delete'=>'']); - } while(!empty($continuationToken)); + $this->call(self::METHOD_POST, $uri, $body, ['delete' => '']); + } while (!empty($continuationToken)); return true; } @@ -514,7 +514,7 @@ public function getFileMimeType(string $path): string public function getFileHash(string $path): string { $etag = $this->getInfo($path)['etag'] ?? ''; - return (!empty($etag)) ? substr($etag, 1, -1) : $etag; + return (!empty($etag)) ? substr($etag, 1, -1) : $etag; } /** @@ -600,10 +600,10 @@ private function getSignatureV4(string $method, string $uri, array $parameters = $combinedHeaders[\strtolower($k)] = \trim($v); } - uksort($combinedHeaders, [ & $this, 'sortMetaHeadersCmp']); + uksort($combinedHeaders, [&$this, 'sortMetaHeadersCmp']); // Convert null query string parameters to strings and sort - uksort($parameters, [ & $this, 'sortMetaHeadersCmp']); + uksort($parameters, [&$this, 'sortMetaHeadersCmp']); $queryString = \http_build_query($parameters, '', '&', PHP_QUERY_RFC3986); // Payload @@ -613,23 +613,25 @@ private function getSignatureV4(string $method, string $uri, array $parameters = $amzPayload[] = ($qsPos === false ? $uri : \substr($uri, 0, $qsPos)); $amzPayload[] = $queryString; - + foreach ($combinedHeaders as $k => $v) { // add header as string to requests $amzPayload[] = $k . ':' . $v; } - + $amzPayload[] = ''; // add a blank entry so we end up with an extra line break $amzPayload[] = \implode(';', \array_keys($combinedHeaders)); // SignedHeaders $amzPayload[] = $this->amzHeaders['x-amz-content-sha256']; // payload hash - + $amzPayloadStr = \implode("\n", $amzPayload); // request as string // CredentialScope $credentialScope = [$amzDateStamp, $region, $service, 'aws4_request']; // stringToSign - $stringToSignStr = \implode("\n", [$algorithm, $this->amzHeaders['x-amz-date'], - \implode('/', $credentialScope), \hash('sha256', $amzPayloadStr)]); + $stringToSignStr = \implode("\n", [ + $algorithm, $this->amzHeaders['x-amz-date'], + \implode('/', $credentialScope), \hash('sha256', $amzPayloadStr) + ]); // Make Signature $kSecret = 'AWS4' . $this->secretKey; @@ -659,7 +661,7 @@ private function getSignatureV4(string $method, string $uri, array $parameters = * * @return object */ - private function call(string $method, string $uri, string $data = '', array $parameters=[]) + private function call(string $method, string $uri, string $data = '', array $parameters = []) { $url = 'https://' . $this->headers['host'] . $uri . '?' . \http_build_query($parameters, '', '&', PHP_QUERY_RFC3986); $response = new \stdClass; @@ -715,7 +717,7 @@ private function call(string $method, string $uri, string $data = '', array $par }); \curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); \curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); - + // Request types switch ($method) { case self::METHOD_PUT: @@ -729,11 +731,11 @@ private function call(string $method, string $uri, string $data = '', array $par } $result = \curl_exec($curl); - + if (!$result) { throw new Exception(\curl_error($curl)); } - + $response->code = \curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($response->code >= 400) { throw new Exception($response->body, $response->code); From dacb9538b107fd0cf5b3652a7b2c9c3ee23f80f0 Mon Sep 17 00:00:00 2001 From: Everly Precia Suresh Date: Tue, 25 Oct 2022 20:31:00 +0000 Subject: [PATCH 5/7] update tests --- tests/Storage/Device/BackblazeTest.php | 2 +- tests/Storage/Device/WasabiTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Storage/Device/BackblazeTest.php b/tests/Storage/Device/BackblazeTest.php index 4d92af18..2862fdb3 100644 --- a/tests/Storage/Device/BackblazeTest.php +++ b/tests/Storage/Device/BackblazeTest.php @@ -9,7 +9,7 @@ class BackblazeTest extends S3Base { protected function init(): void { - $this->root = 'root'; + $this->root = '/root'; $key = $_SERVER['BACKBLAZE_ACCESS_KEY'] ?? ''; $secret = $_SERVER['BACKBLAZE_SECRET'] ?? ''; $bucket = "backblaze-demo"; diff --git a/tests/Storage/Device/WasabiTest.php b/tests/Storage/Device/WasabiTest.php index 264ee3c9..56e8f7fa 100644 --- a/tests/Storage/Device/WasabiTest.php +++ b/tests/Storage/Device/WasabiTest.php @@ -9,7 +9,7 @@ class WasabiTest extends S3Base { protected function init(): void { - $this->root = 'root'; + $this->root = '/root'; $key = $_SERVER['WASABI_ACCESS_KEY'] ?? ''; $secret = $_SERVER['WASABI_SECRET'] ?? ''; $bucket = 'utopia-storage-tests'; From 371b48b97ebe502c12cae2105eee9cbca4fd66cb Mon Sep 17 00:00:00 2001 From: Everly Precia Suresh Date: Tue, 25 Oct 2022 21:01:18 +0000 Subject: [PATCH 6/7] Trigger Build From 8e8a4963a9c08a44e8400dff3fd4427f71899c75 Mon Sep 17 00:00:00 2001 From: Everly Precia Suresh Date: Tue, 6 Dec 2022 18:26:19 +0000 Subject: [PATCH 7/7] update storage --- src/Storage/Device/Local.php | 2 +- tests/Storage/Device/LocalTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Storage/Device/Local.php b/src/Storage/Device/Local.php index f8db1f95..20ba084e 100644 --- a/src/Storage/Device/Local.php +++ b/src/Storage/Device/Local.php @@ -19,7 +19,7 @@ class Local extends Device */ public function __construct($root = '') { - $this->root = $root; + $this->root = trim($root,"/"); } /** diff --git a/tests/Storage/Device/LocalTest.php b/tests/Storage/Device/LocalTest.php index 42cae407..1c1db72b 100644 --- a/tests/Storage/Device/LocalTest.php +++ b/tests/Storage/Device/LocalTest.php @@ -33,12 +33,12 @@ public function testDescription() public function testRoot() { - $this->assertEquals($this->object->getRoot(),realpath( __DIR__ . '/../../resources/disk-a')); + $this->assertEquals($this->object->getRoot(),trim(realpath( __DIR__ . '/../../resources/disk-a'),"/")); } public function testPath() { - $this->assertEquals($this->object->getPath('image.png'), realpath(__DIR__ . '/../../resources/disk-a').'/image.png'); + $this->assertEquals($this->object->getPath('image.png'), trim(realpath(__DIR__ . '/../../resources/disk-a').'/image.png',"/")); } public function testWrite()