확장 (Extensions)
R2는 기본 S3 API 위에 몇 가지 확장 기능을 추가로 제공해요. 이 페이지에서는 그런 추가 기능들을 정리해 드릴게요. 이 페이지에서 설명하는 기능 중 일부는 커스텀 헤더를 설정해야 사용할 수 있어요. 설정 방법 예시는 커스텀 헤더 구성 문서를 참고해 주세요.
출처: 문서
본문
Unicode를 사용한 확장 메타데이터
Workers R2 API는 customMetadata 필드에 대해 별도의 인코딩이나 디코딩 없이 키와 값에 Unicode를 기본적으로 지원해요. 이 필드들은 R2의 S3 호환 API 엔드포인트에서 사용되는 x-amz-meta- 접두어 헤더로 매핑돼요.
HTTP 헤더 이름과 값은 Unicode 문자 집합의 작은 부분집합인 ASCII 문자만 담을 수 있어요. R2는 사용자를 편하게 만들기 위해 RFC 2047 ↗︎을 따르며, 저장하기 전에 모든 x-amz-meta-* 헤더 값을 자동으로 디코딩해요. 조회할 때는 Unicode가 포함된 메타데이터 값을 응답을 렌더링하기 전에 RFC 2047로 인코딩해요. 메타데이터 값의 길이 제한은 디코딩된 Unicode 값에 적용돼요.
메타데이터 차이
같은 데이터에 접근할 때 Workers와 S3 API 엔드포인트를 모두 사용한다면 주의가 필요해요. R2 메타데이터 키에 Unicode가 포함된 경우, S3 API로 접근하면 그 키는 제거되고 x-amz-missing-meta 헤더에는 생략된 키의 개수가 설정돼요.
이 헤더들은 R2 바인딩의 httpMetadata 필드로 매핑돼요:
| HTTP 헤더 | 속성 이름 |
|---|---|
Content-Encoding |
httpMetadata.contentEncoding |
Content-Type |
httpMetadata.contentType |
Content-Language |
httpMetadata.contentLanguage |
Content-Disposition |
httpMetadata.contentDisposition |
Cache-Control |
httpMetadata.cacheControl |
Expires |
httpMetadata.expires |
객체 키 이름에 Unicode를 사용한다면 Unicode 상호운용성 문서를 참고해 주세요.
업로드 시 버킷 자동 생성
버킷을 요청 시점(on demand)에 만드는 경우, 대상 버킷이 이미 존재한다고 가정하고 업로드를 시작하려 할 수 있어요. 이 상황에서 NoSuchBucket 오류를 받았다면 아마 CreateBucket 작업을 실행했을 거예요. 하지만 이 방식은 문제를 일으킬 수 있어요. 본문(body)이 이미 일부 소비된 상태라면 업로드를 중단(abort)해야 하거든요. 이 문제에 대한 일반적인 해결책으로 다른 객체 스토리지 제공자들이 쓰는 방법은, 본문을 보내야 하는지 아니면 업로드를 다시 시도하기 전에 버킷을 먼저 만들어야 하는지 판단하기 위해 HTTP 100 ↗︎ 응답을 사용하는 거예요. 하지만 Cloudflare는 HTTP 100 응답을 지원하지 않아요. 설령 HTTP 100 응답을 지원한다 해도 왕복(round trip) 때문에 추가 지연이 발생할 수밖에 없어요.
아직 존재하지 않을 수 있는 버킷에 스트리밍 본문으로 업로드를 보내는 것을 지원하기 위해, PutObject나 CreateMultipartUpload 같은 업로드 작업에서는 NoSuchBucket 오류가 반환되지 않도록 보장하는 헤더를 지정할 수 있어요. 업로드 시점에 버킷이 존재하지 않는다면 다음 CreateBucket 요청으로 버킷이 암시적으로 생성돼요:
PUT / HTTP/1.1
Host: bucket.account.r2.cloudflarestorage.com
<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<LocationConstraint>auto</LocationConstraint>
</CreateBucketConfiguration>
이 기능은 버킷 이름이나 선호 접근 위치를 미리 알 수 없어서 버킷을 요청 시점에 만드는 경우에만 유용해요. 예를 들어 고객마다 버킷을 하나씩 두고, 버킷이 계정 등록 때가 아니라 버킷에 대한 첫 업로드 때 생성되는 경우가 있어요. 이런 경우 1,000개가 넘는 버킷을 가진 계정을 지원하는 ListBuckets 확장도 유용할 수 있어요.
PutObject와 CreateMultipartUpload
cf-create-bucket-if-missing
버킷이 아직 존재하지 않는다면 암시적으로 생성하도록, 값이 true인 cf-create-bucket-if-missing 헤더를 추가해요. 이 헤더를 언제 추가해야 하는지에 대한 자세한 설명은 업로드 시 버킷 자동 생성을 참고해 주세요.
CopyObject
MERGE 메타데이터 지시자
x-amz-metadata-directive는 표준 COPY와 REPLACE 옵션 외에도 MERGE 값을 지원해요. MERGE는 COPY와 REPLACE의 조합으로, 소스 객체의 메타데이터 키를 COPY하면서 요청에서 지정한 키는 새 값으로 REPLACE해요. MERGE로는 소스의 기존 메타데이터 키를 제거할 수 없어요. 그럴 때는 REPLACE를 사용해야 해요.
ListBuckets
ListBuckets는 R2에서 ListObjectsV2와 동일한 검색 파라미터를 모두 지원해요. 일부 고객은 1,000개가 넘는 버킷을 가질 수 있기 때문이에요. 기존 S3 라이브러리 같은 도구는 이런 검색 파라미터를 설정하는 방법을 노출하지 않을 수 있으므로, 이 값들은 헤더로도 보낼 수 있어요. 헤더의 값이 검색 파라미터보다 우선해요.
| 검색 파라미터 | HTTP 헤더 | 의미 |
|---|---|---|
prefix |
cf-prefix |
이 접두어를 가진 버킷만 표시해요. |
start-after |
cf-start-after |
계정에서 사전순으로 뒤에 오는 이름을 가진 버킷을 표시해요. |
continuation-token |
cf-continuation-token |
이전에 받은 continuation 토큰부터 목록 표시를 재개해요. |
max-keys |
cf-max-keys |
이 최대 개수만큼 버킷을 반환해요. 기본값과 최댓값은 1000이에요. |
XML 응답에는 상황에 맞게 NextContinuationToken과 IsTruncated 요소가 포함돼요. 기존 S3 API에서 접근할 수 없을 수 있으므로 이 값들은 응답 헤더에서도 사용할 수 있어요:
| XML 응답 요소 | HTTP 응답 헤더 | 의미 |
|---|---|---|
IsTruncated |
cf-is-truncated |
반환된 버킷 목록이 계정의 모든 버킷이 아닌 경우 true로 설정돼요. |
NextContinuationToken |
cf-next-continuation-token |
이후 ListBuckets에서 목록 표시를 재개하도록 넘길 continuation 토큰으로 설정돼요. |
StartAfter |
요청에서 전달된 start-after 값이에요. | |
KeyCount |
반환된 버킷 개수예요. | |
ContinuationToken |
요청에서 제공된 continuation 토큰이에요. | |
MaxKeys |
요청에서 지정된 최대 키 개수예요. | |
대상 객체에 대한 CopyObject의 조건부 작업
참고
이 기능은 현재 베타 단계예요. 피드백이 있다면 Cloudflare Developer Discord ↗︎의 #r2-storage 채널에서 알려주거나 커뮤니티 포럼 ↗︎에 스레드를 열어 주세요.
CopyObject는 S3 API 준수의 일부로 x-amz-copy-source-if-... 헤더를 통해 소스 객체와 관련된 조건을 이미 지원해요. 여기에 더해 R2는 CopyObject 작업이 대상 객체에 조건부로 적용되게 하는 R2 전용 헤더 세트를 지원해요:
cf-copy-destination-if-matchcf-copy-destination-if-none-matchcf-copy-destination-if-modified-sincecf-copy-destination-if-unmodified-since
이 헤더들은 PutObject에서 지원하는 유사한 이름의 조건부 헤더와 비슷하게 동작해요. 대상 객체의 이전 상태가 지정된 조건과 일치하지 않으면 CopyObject 작업은 412 PreconditionFailed 오류 코드와 함께 거부돼요.
x-amz-copy-source-if에 대한 비원자성
x-amz-copy-source-if-... 헤더는 복사 작업의 소스 객체가 선택될 때 검사된다는 것이 보장되고, cf-copy-destination-if-... 헤더는 객체가 버킷 상태에 커밋될 때 검사된다는 것이 보장돼요. 하지만 소스 객체가 복사용으로 선택되는 시점과 대상 객체가 버킷 상태에 커밋되는 시점이 반드시 같지는 않아요. 즉, cf-copy-destination-if-... 헤더는 x-amz-copy-source-if... 헤더와 관련해서 원자적(atomic)이지 않다는 뜻이에요.
더 알아보기 (Learn more)
- 커스텀 헤더 구성 — 커스텀 헤더 설정 예시
- Unicode 상호운용성 — 객체 키 이름에 Unicode 사용하기