Commit cb92dc73 authored by Yassine Doghri's avatar Yassine Doghri
Browse files

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

parent 548a11d5
Loading
Loading
Loading
Loading
Loading
+30 −13
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ use Aws\S3\S3Client;
use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\Files\File;
use CodeIgniter\HTTP\Response;
use DateTime;
use Exception;
use Modules\Media\Config\Media as MediaConfig;

@@ -37,6 +38,7 @@ class S3 implements FileManagerInterface
                'Key' => $this->prefixKey($key),
                'SourceFile' => $file,
                'ContentType' => $file->getMimeType(),
                'CacheControl' => 'max-age=' . YEAR,
            ]);
        } catch (Exception) {
            return false;
@@ -185,10 +187,10 @@ class S3 implements FileManagerInterface

    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 {
            $result = $this->s3->getObject([
                $cmd = $this->s3->getCommand('GetObject', [
                    'Bucket' => $this->config->s3['bucket'],
                    'Key' => $this->prefixKey($key),
                ]);
@@ -196,16 +198,31 @@ class S3 implements FileManagerInterface
                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
        header_remove('Cache-Control');

        return $response->setCache([
            'max-age' => DECADE,
            'last-modified' => $result->get('LastModified'),
            'etag' => $result->get('ETag'),
            'max-age' => DAY,
            'last-modified' => $lastModified->format(DATE_RFC7231),
            'etag' => md5($cacheName),
            'public' => true,
        ])->setContentType($result->get('ContentType'))
            ->setBody((string) $result->get('Body')->getContents());
        ])->redirect($found);
    }

    private function prefixKey(string $key): string