fix:GCS 서명 URL 경로 중복 버그 수정 (gs:// prefix 제거)

upload()이 gs://bucket/path 형식으로 저장하지만 getSignedUrl()과
delete()는 path만 기대하여 URL에 경로가 중복됨 → 404 발생
stripGsPrefix()로 자동 변환하여 해결

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-15 16:50:20 +09:00
parent 7651aebcfc
commit cf56285805

View File

@@ -169,7 +169,7 @@ public function upload(string $filePath, string $objectName): ?string
/**
* GCS에서 서명된 다운로드 URL 생성
*
* @param string $objectName GCS 객체 이름
* @param string $objectName GCS 객체 이름 또는 gs:// URI
* @param int $expiresInMinutes URL 유효 시간 (분)
* @return string|null 서명된 URL 또는 실패 시 null
*/
@@ -179,6 +179,8 @@ public function getSignedUrl(string $objectName, int $expiresInMinutes = 60): ?s
return null;
}
$objectName = $this->stripGsPrefix($objectName);
$expiration = time() + ($expiresInMinutes * 60);
$stringToSign = "GET\n\n\n{$expiration}\n/{$this->bucketName}/{$objectName}";
@@ -205,7 +207,7 @@ public function getSignedUrl(string $objectName, int $expiresInMinutes = 60): ?s
/**
* GCS에서 파일 삭제
*
* @param string $objectName GCS 객체 이름
* @param string $objectName GCS 객체 이름 또는 gs:// URI
* @return bool 성공 여부
*/
public function delete(string $objectName): bool
@@ -214,6 +216,8 @@ public function delete(string $objectName): bool
return false;
}
$objectName = $this->stripGsPrefix($objectName);
$accessToken = $this->getAccessToken();
if (!$accessToken) {
return false;
@@ -297,6 +301,26 @@ private function base64UrlEncode(string $data): string
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
/**
* gs://bucket-name/objectName → objectName 변환
*
* upload()가 gs:// URI를 반환하므로, getSignedUrl/delete에서 자동 처리
*/
private function stripGsPrefix(string $objectName): string
{
$prefix = 'gs://' . $this->bucketName . '/';
if (str_starts_with($objectName, $prefix)) {
return substr($objectName, strlen($prefix));
}
// gs://다른-버킷/ 형태도 처리
if (str_starts_with($objectName, 'gs://')) {
$objectName = preg_replace('#^gs://[^/]+/#', '', $objectName);
}
return $objectName;
}
/**
* 버킷 이름 반환
*/