fix(s3): use presigned request uri to serve static files

This commit is contained in:
Yassine Doghri 2023-06-05 11:48:29 +00:00
parent 548a11d501
commit cb92dc73f1

View File

@ -9,6 +9,7 @@ use Aws\S3\S3Client;
use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\Files\File; use CodeIgniter\Files\File;
use CodeIgniter\HTTP\Response; use CodeIgniter\HTTP\Response;
use DateTime;
use Exception; use Exception;
use Modules\Media\Config\Media as MediaConfig; use Modules\Media\Config\Media as MediaConfig;
@ -37,6 +38,7 @@ class S3 implements FileManagerInterface
'Key' => $this->prefixKey($key), 'Key' => $this->prefixKey($key),
'SourceFile' => $file, 'SourceFile' => $file,
'ContentType' => $file->getMimeType(), 'ContentType' => $file->getMimeType(),
'CacheControl' => 'max-age=' . YEAR,
]); ]);
} catch (Exception) { } catch (Exception) {
return false; return false;
@ -185,10 +187,10 @@ class S3 implements FileManagerInterface
public function serve(string $key): Response public function serve(string $key): Response
{ {
$response = service('response'); $cacheName = 'object_presigned_uri_' . str_replace('/', '-', $key) . '_' . $this->config->s3['bucket'];
if (! $found = cache($cacheName)) {
try { try {
$result = $this->s3->getObject([ $cmd = $this->s3->getCommand('GetObject', [
'Bucket' => $this->config->s3['bucket'], 'Bucket' => $this->config->s3['bucket'],
'Key' => $this->prefixKey($key), 'Key' => $this->prefixKey($key),
]); ]);
@ -196,16 +198,31 @@ class S3 implements FileManagerInterface
throw new PageNotFoundException(); throw new PageNotFoundException();
} }
$request = $this->s3->createPresignedRequest($cmd, '+1 day');
$found = (string) $request->getUri();
cache()
->save($cacheName, $found, DAY);
}
$lastModifiedTimestamp = cache()
->getMetaData($cacheName)['mtime'];
$lastModified = new DateTime();
$lastModified->setTimestamp($lastModifiedTimestamp);
/** @var Response $response */
$response = service('response');
// Remove Cache-Control header before redefining it // Remove Cache-Control header before redefining it
header_remove('Cache-Control'); header_remove('Cache-Control');
return $response->setCache([ return $response->setCache([
'max-age' => DECADE, 'max-age' => DAY,
'last-modified' => $result->get('LastModified'), 'last-modified' => $lastModified->format(DATE_RFC7231),
'etag' => $result->get('ETag'), 'etag' => md5($cacheName),
'public' => true, 'public' => true,
])->setContentType($result->get('ContentType')) ])->redirect($found);
->setBody((string) $result->get('Body')->getContents());
} }
private function prefixKey(string $key): string private function prefixKey(string $key): string