Use presigned urls when statically pre-rendering
This commit is contained in:
parent
44550824e7
commit
d11cf6f62d
@ -1,5 +1,5 @@
|
||||
import { auth } from '@/auth/server';
|
||||
import { getSignedUrl } from '@/platforms/storage';
|
||||
import { getSignedUrlForKey } from '@/platforms/storage';
|
||||
|
||||
export async function GET(
|
||||
_: Request,
|
||||
@ -10,7 +10,7 @@ export async function GET(
|
||||
const session = await auth();
|
||||
|
||||
if (session?.user && key) {
|
||||
const url = await getSignedUrl(key, 'PUT');
|
||||
const url = await getSignedUrlForKey(key, 'PUT');
|
||||
return new Response(
|
||||
url,
|
||||
{ headers: { 'content-type': 'text/plain' } },
|
||||
|
||||
@ -7,6 +7,8 @@ import {
|
||||
doAllPhotosHaveOptimizedFiles,
|
||||
getOptimizedPhotoUrl,
|
||||
} from '@/photo/storage';
|
||||
import { fetchBase64ImageFromUrl } from '@/utility/image';
|
||||
import { getSignedUrlForUrl } from '@/platforms/storage';
|
||||
|
||||
export default async function ImagePhotoGrid({
|
||||
photos,
|
||||
@ -53,7 +55,23 @@ export default async function ImagePhotoGrid({
|
||||
|
||||
const doOptimizedFilesExist = await doAllPhotosHaveOptimizedFiles(photos);
|
||||
|
||||
const renderPhoto = ({ id, url }: Photo, width: number, height: number) =>
|
||||
const photoDataUrls = await Promise.all(photos.map(async({ id, url }) => {
|
||||
const optimizedUrl = getOptimizedPhotoUrl({
|
||||
imageUrl: url,
|
||||
size: nextImageWidth,
|
||||
addBypassSecret: IS_PREVIEW,
|
||||
compatibilityMode: !doOptimizedFilesExist,
|
||||
});
|
||||
const presignedUrl = await getSignedUrlForUrl(optimizedUrl, 'GET');
|
||||
const data = await fetchBase64ImageFromUrl(presignedUrl);
|
||||
return { id, data };
|
||||
}));
|
||||
|
||||
const renderPhoto = (
|
||||
{ id, data }: typeof photoDataUrls[number],
|
||||
width: number,
|
||||
height: number,
|
||||
) =>
|
||||
<div
|
||||
key={id}
|
||||
style={{
|
||||
@ -65,12 +83,7 @@ export default async function ImagePhotoGrid({
|
||||
}}
|
||||
>
|
||||
<img {...{
|
||||
src: getOptimizedPhotoUrl({
|
||||
imageUrl: url,
|
||||
size: nextImageWidth,
|
||||
addBypassSecret: IS_PREVIEW,
|
||||
compatibilityMode: !doOptimizedFilesExist,
|
||||
}),
|
||||
src: data,
|
||||
style: {
|
||||
...imageStyle,
|
||||
width: '100%',
|
||||
@ -100,7 +113,7 @@ export default async function ImagePhotoGrid({
|
||||
width: cellWidth,
|
||||
height: cellHeight * 2,
|
||||
}}>
|
||||
{renderPhoto(photos[0], cellWidth, cellHeight * 2)}
|
||||
{renderPhoto(photoDataUrls[0], cellWidth, cellHeight * 2)}
|
||||
</div>
|
||||
{/* Small images (R) */}
|
||||
<div style={{
|
||||
@ -109,12 +122,12 @@ export default async function ImagePhotoGrid({
|
||||
width: cellWidth,
|
||||
height: cellHeight,
|
||||
}}>
|
||||
{photos.slice(1).map(photo =>
|
||||
{photoDataUrls.slice(1).map(photo =>
|
||||
renderPhoto(photo, cellWidth, cellHeight),
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
: photos.slice(0, count).map(photo =>
|
||||
: photoDataUrls.slice(0, count).map(photo =>
|
||||
renderPhoto(photo, cellWidth, cellHeight),
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -84,7 +84,7 @@ export const awsS3Delete = async (Key: string) => {
|
||||
}));
|
||||
};
|
||||
|
||||
export const awsS3GetSignedUrl = async (
|
||||
export const awsS3GetSignedUrl = (
|
||||
Key: string,
|
||||
method: 'GET' | 'PUT',
|
||||
expiresIn: number,
|
||||
|
||||
@ -104,7 +104,7 @@ export const cloudflareR2Delete = async (Key: string) => {
|
||||
}));
|
||||
};
|
||||
|
||||
export const cloudflareR2GetSignedUrl = async (
|
||||
export const cloudflareR2GetSignedUrl = (
|
||||
Key: string,
|
||||
method: 'GET' | 'PUT',
|
||||
expiresIn: number,
|
||||
|
||||
@ -251,7 +251,8 @@ export const getStorageUrlsForPrefix = async (prefix = '') => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getSignedUrl = async (
|
||||
// Used primarily for uploading files
|
||||
export const getSignedUrlForKey = async (
|
||||
key: string,
|
||||
method: 'GET' | 'PUT',
|
||||
expiresIn = 3600,
|
||||
@ -266,5 +267,24 @@ export const getSignedUrl = async (
|
||||
}
|
||||
};
|
||||
|
||||
// Used for safely fetching files via presigned URLs
|
||||
export const getSignedUrlForUrl = (
|
||||
url: string,
|
||||
method: 'GET' | 'PUT',
|
||||
expiresIn = 3600,
|
||||
) => {
|
||||
const { fileName } = getFileNamePartsFromStorageUrl(url);
|
||||
switch (storageTypeFromUrl(url)) {
|
||||
case 'cloudflare-r2':
|
||||
return cloudflareR2GetSignedUrl(fileName, method, expiresIn);
|
||||
case 'minio':
|
||||
return minioGetSignedUrl(fileName, method, expiresIn);
|
||||
case 'aws-s3':
|
||||
return awsS3GetSignedUrl(fileName, method, expiresIn);
|
||||
default:
|
||||
return url;
|
||||
}
|
||||
};
|
||||
|
||||
export const testStorageConnection = () =>
|
||||
getStorageUrlsForPrefix();
|
||||
|
||||
@ -93,7 +93,7 @@ export const minioDelete = async (Key: string): Promise<void> => {
|
||||
await minioClient().send(deleteObjectCommand);
|
||||
};
|
||||
|
||||
export const minioGetSignedUrl = async (
|
||||
export const minioGetSignedUrl = (
|
||||
Key: string,
|
||||
method: 'GET' | 'PUT',
|
||||
expiresIn: number,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user