feat: Add dynamic S3 Cache-Control headers based on upload folder type to S3 upload operations.
This commit is contained in:
@@ -56,6 +56,20 @@ export class UploadService {
|
|||||||
return parts.length > 1 ? parts.pop()!.toLowerCase() : '';
|
return parts.length > 1 ? parts.pop()!.toLowerCase() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Cache-Control header value based on folder type
|
||||||
|
* Since file IDs change on re-upload, we can use long cache times
|
||||||
|
*/
|
||||||
|
private getCacheControl(folder: UploadFolder): string {
|
||||||
|
const cacheDurations: Record<UploadFolder, number> = {
|
||||||
|
[UploadFolder.AVATARS]: 30 * 24 * 60 * 60, // 30 days
|
||||||
|
[UploadFolder.DOCUMENTS]: 7 * 24 * 60 * 60, // 7 days
|
||||||
|
[UploadFolder.PROPERTIES]: 30 * 24 * 60 * 60, // 30 days
|
||||||
|
[UploadFolder.VERIFICATION]: 1 * 24 * 60 * 60, // 1 day
|
||||||
|
};
|
||||||
|
return `public, max-age=${cacheDurations[folder] || 86400}`;
|
||||||
|
}
|
||||||
|
|
||||||
private validateContentType(contentType: string, folder: UploadFolder): void {
|
private validateContentType(contentType: string, folder: UploadFolder): void {
|
||||||
const allowedTypes: Record<UploadFolder, string[]> = {
|
const allowedTypes: Record<UploadFolder, string[]> = {
|
||||||
[UploadFolder.AVATARS]: ['image/jpeg', 'image/png', 'image/webp'],
|
[UploadFolder.AVATARS]: ['image/jpeg', 'image/png', 'image/webp'],
|
||||||
@@ -100,6 +114,7 @@ export class UploadService {
|
|||||||
Bucket: this.bucket,
|
Bucket: this.bucket,
|
||||||
Key: key,
|
Key: key,
|
||||||
ContentType: dto.contentType,
|
ContentType: dto.contentType,
|
||||||
|
CacheControl: this.getCacheControl(dto.folder),
|
||||||
});
|
});
|
||||||
|
|
||||||
const uploadUrl = await getSignedUrl(this.s3Client, command, {
|
const uploadUrl = await getSignedUrl(this.s3Client, command, {
|
||||||
@@ -165,6 +180,7 @@ export class UploadService {
|
|||||||
Key: key,
|
Key: key,
|
||||||
Body: buffer,
|
Body: buffer,
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
|
CacheControl: this.getCacheControl(folder),
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.s3Client.send(command);
|
await this.s3Client.send(command);
|
||||||
@@ -198,6 +214,7 @@ export class UploadService {
|
|||||||
Bucket: this.bucket,
|
Bucket: this.bucket,
|
||||||
Key: key,
|
Key: key,
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
|
CacheControl: this.getCacheControl(UploadFolder.AVATARS),
|
||||||
});
|
});
|
||||||
|
|
||||||
const uploadUrl = await getSignedUrl(this.s3Client, command, {
|
const uploadUrl = await getSignedUrl(this.s3Client, command, {
|
||||||
@@ -234,6 +251,7 @@ export class UploadService {
|
|||||||
Bucket: this.bucket,
|
Bucket: this.bucket,
|
||||||
Key: key,
|
Key: key,
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
|
CacheControl: this.getCacheControl(UploadFolder.AVATARS),
|
||||||
});
|
});
|
||||||
|
|
||||||
const uploadUrl = await getSignedUrl(this.s3Client, command, {
|
const uploadUrl = await getSignedUrl(this.s3Client, command, {
|
||||||
|
|||||||
Reference in New Issue
Block a user