Skip to content

Commit f2fb46b

Browse files
committed
refactor: PresignedUrlProvider에서 S3 URL 생성 로직을 CDN URL로 수정
1 parent 34577d8 commit f2fb46b

1 file changed

Lines changed: 40 additions & 9 deletions

File tree

global/src/main/kotlin/zipbap/global/global/cloud/service/PresignedUrlProvider.kt

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,37 @@ import com.amazonaws.HttpMethod
44
import com.amazonaws.services.s3.AmazonS3
55
import org.springframework.beans.factory.annotation.Value
66
import org.springframework.stereotype.Service
7+
import java.net.URL
78
import java.util.*
89

910
@Service
1011
class PresignedUrlProvider(
1112
private val amazonS3: AmazonS3,
12-
@Value("\${cloud.aws.s3.bucket}") private val bucket: String
13+
14+
@Value("\${cloud.aws.s3.bucket}")
15+
private val bucket: String,
16+
17+
@Value("\${cloud.cdn.domain}")
18+
private val cdnDomain: String
1319
) {
1420

1521
/**
16-
* Presigned URL 생성 (임시 업로드 전용)
22+
* Presigned URL 생성 (업로드는 S3에, 조회는 CDN으로!)
1723
*/
18-
fun generateUploadUrl(userId: Long, fileName: String, expirationMinutes: Int = 5): Map<String, String> {
24+
fun generateUploadUrl(
25+
userId: Long,
26+
fileName: String,
27+
expirationMinutes: Int = 5
28+
): Map<String, String> {
29+
1930
val key = "temp/$userId/${UUID.randomUUID()}-$fileName"
2031
val expiration = Date(System.currentTimeMillis() + expirationMinutes * 60 * 1000)
2132

33+
// 1) 업로드 URL (S3 PUT 용) 그대로 유지
2234
val uploadUrl = amazonS3.generatePresignedUrl(bucket, key, expiration, HttpMethod.PUT)
23-
val fileUrl = amazonS3.getUrl(bucket, key).toString()
35+
36+
// 2) 조회 URL은 CloudFront CDN 도메인으로 생성
37+
val fileUrl = buildCdnUrl(key)
2438

2539
return mapOf(
2640
"uploadUrl" to uploadUrl.toString(),
@@ -34,19 +48,36 @@ class PresignedUrlProvider(
3448
*/
3549
fun copyTempToRecipe(fileUrl: String, recipeId: String): String {
3650
val sourceKey = extractKeyFromUrl(fileUrl)
51+
3752
if (!sourceKey.startsWith("temp/")) {
3853
throw IllegalArgumentException("Source key must start with temp/: $sourceKey")
3954
}
4055

4156
val targetKey = sourceKey.replaceFirst("temp/", "recipes/$recipeId/")
42-
4357
amazonS3.copyObject(bucket, sourceKey, bucket, targetKey)
4458

45-
return amazonS3.getUrl(bucket, targetKey).toString()
59+
// CloudFront URL 반환
60+
return buildCdnUrl(targetKey)
61+
}
62+
63+
/**
64+
* CloudFront URL 또는 S3 URL에서 key 추출
65+
*/
66+
private fun extractKeyFromUrl(url: String): String {
67+
return when {
68+
url.contains(cdnDomain) -> {
69+
// ex: https://dxxxxxxx.cloudfront.net/temp/1/xxx.jpg
70+
URL(url).path.removePrefix("/")
71+
}
72+
else -> {
73+
// 기존 S3 URL fallback
74+
val bucketUrlPrefix = amazonS3.getUrl(bucket, "").toString()
75+
url.removePrefix(bucketUrlPrefix)
76+
}
77+
}
4678
}
4779

48-
private fun extractKeyFromUrl(fileUrl: String): String {
49-
val urlPrefix = amazonS3.getUrl(bucket, "").toString()
50-
return fileUrl.removePrefix(urlPrefix)
80+
private fun buildCdnUrl(key: String): String {
81+
return "https://$cdnDomain/$key"
5182
}
5283
}

0 commit comments

Comments
 (0)