From a6768bdc32f60323b56c1248cfd1aad389fcb533 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 31 May 2023 14:41:56 +0300 Subject: [PATCH] saving file output to cache instead of decoding data to json --- app/config/collections.php | 22 ++++++++++++++++++++++ app/controllers/api/storage.php | 4 ++-- app/controllers/shared/api.php | 31 ++++++++++++------------------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index 85a279faa..e8a317697 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -3206,6 +3206,28 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'resourceType', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 255, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('mimeType'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 255, // https://tools.ietf.org/html/rfc4288#section-4.2 + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => 'accessedAt', 'type' => Database::VAR_DATETIME, diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index d59d950d9..82cba1ab4 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -945,6 +945,8 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $data = $image->output($output, $quality); + unset($image); + $contentType = (\array_key_exists($output, $outputs)) ? $outputs[$output] : $outputs['jpg']; $response @@ -952,8 +954,6 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') ->setContentType($contentType) ->file($data) ; - - unset($image); }); App::get('/v1/storage/buckets/:bucketId/files/:fileId/download') diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 289fbca8f..56fc02bbb 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -195,28 +195,25 @@ App::init() $database->setProject($project); $dbForProject->on(Database::EVENT_DOCUMENT_CREATE, fn ($event, Document $document) => $databaseListener($event, $document, $usage)); - $dbForProject->on(Database::EVENT_DOCUMENT_DELETE, fn ($event, Document $document) => $databaseListener($event, $document, $usage)); $useCache = $route->getLabel('cache', false); - if ($useCache) { $key = md5($request->getURI() . implode('*', $request->getParams())) . '*' . APP_CACHE_BUSTER; + $cacheLog = $dbForProject->getDocument('cache', $key); $cache = new Cache( new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId()) ); $timestamp = 60 * 60 * 24 * 30; $data = $cache->load($key, $timestamp); - if (!empty($data)) { - $data = json_decode($data, true); - $parts = explode('/', $data['resourceType']); + if (!empty($data) && !empty($cacheLog)) { + $parts = explode('/', $cacheLog->getAttribute('resourceType')); $type = $parts[0] ?? null; if ($type === 'bucket') { $bucketId = $parts[1] ?? null; - - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -225,11 +222,12 @@ App::init() $fileSecurity = $bucket->getAttribute('fileSecurity', false); $validator = new Authorization(Database::PERMISSION_READ); $valid = $validator->isValid($bucket->getRead()); + if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } - $parts = explode('/', $data['resource']); + $parts = explode('/', $cacheLog->getAttribute('resource')); $fileId = $parts[1] ?? null; if ($fileSecurity && !$valid) { @@ -246,8 +244,8 @@ App::init() $response ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $timestamp) . ' GMT') ->addHeader('X-Appwrite-Cache', 'hit') - ->setContentType($data['contentType']) - ->send(base64_decode($data['payload'])) + ->setContentType($cacheLog->getAttribute('mimeType')) + ->send($data) ; $route->setIsActive(false); @@ -475,7 +473,6 @@ App::shutdown() if ($useCache) { $resource = $resourceType = null; $data = $response->getPayload(); - if (!empty($data['payload'])) { $pattern = $route->getLabel('cache.resource', null); if (!empty($pattern)) { @@ -488,14 +485,8 @@ App::shutdown() } $key = md5($request->getURI() . implode('*', $request->getParams())) . '*' . APP_CACHE_BUSTER; - $data = json_encode([ - 'resourceType' => $resourceType, - 'resource' => $resource, - 'contentType' => $response->getContentType(), - 'payload' => base64_encode($data['payload']), - ]) ; - $signature = md5($data); + $signature = md5($data['payload']); $cacheLog = $dbForProject->getDocument('cache', $key); $accessedAt = $cacheLog->getAttribute('accessedAt', ''); $now = DateTime::now(); @@ -503,6 +494,8 @@ App::shutdown() Authorization::skip(fn () => $dbForProject->createDocument('cache', new Document([ '$id' => $key, 'resource' => $resource, + 'resourceType' => $resourceType, + 'mimeType' => $response->getContentType(), 'accessedAt' => $now, 'signature' => $signature, ]))); @@ -515,7 +508,7 @@ App::shutdown() $cache = new Cache( new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId()) ); - $cache->save($key, $data); + $cache->save($key, $data['payload']); } } }