커스텀 헤더 구성하기
R2의 S3 호환 API에서 커스텀 헤더를 설정하는 예시예요. 모든 요청에 공통 헤더를 붙이거나 요청마다 다른 헤더(예: If-Match)를 설정하는 방법을 boto3와 aws-sdk-js-v3로 보여줘요.
출처: 문서
본문
모든 요청에 커스텀 헤더 설정 (Setting a custom header on all requests)
cf-create-bucket-if-missing 헤더 같은 특정 기능을 사용할 때, 보내는 모든 PutObject 요청에 상수(constant) 헤더를 설정하고 싶을 수 있어요.
boto3로 모든 요청에 헤더 설정 (Set a header for all requests with boto3)
Boto3에는 요청을 수정할 수 있는 이벤트 시스템이 있어요. 여기서는 보내는 모든 PutObject 요청에 헤더를 추가하는 함수를 이벤트 시스템에 등록해요.
import boto3
client = boto3.resource('s3',
# Provide your Cloudflare account ID
endpoint_url = 'https://<ACCOUNT_ID>.r2.cloudflarestorage.com',
# Retrieve your S3 API credentials for your R2 bucket via API tokens (see: https://developers.cloudflare.com/r2/api/tokens)
aws_access_key_id = '<ACCESS_KEY_ID>',
aws_secret_access_key = '<SECRET_ACCESS_KEY>'
)
event_system = client.meta.events
# Define function responsible for adding the header
def add_custom_header(params, **kwargs):
params["headers"]['cf-create-bucket-if-missing'] = 'true'
event_system.register('before-call.s3.PutObject', add_custom_header)
response = client.put_object(Bucket="my-bucket", Key="my_file", Body="file_contents")
print(response)
aws-sdk-js-v3로 모든 요청에 헤더 설정 (Set a header for all requests with aws-sdk-js-v3)
aws-sdk-js-v3는 미들웨어 스택 ↗︎을 통해 요청 동작을 커스터마이즈할 수 있어요. 이 예시는 보내는 모든 PutObject 요청에 헤더를 추가하는 미들웨어를 클라이언트에 추가해요.
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { HttpRequest } from "@smithy/core/protocols";
const client = new S3Client({
region: "auto", // Required by SDK but not used by R2
endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
// Retrieve your S3 API credentials for your R2 bucket via API tokens (see: https://developers.cloudflare.com/r2/api/tokens)
credentials: {
accessKeyId: ACCESS_KEY_ID,
secretAccessKey: SECRET_ACCESS_KEY,
},
});
client.middlewareStack.add(
(next) => async (args) => {
const request = args.request;
if (HttpRequest.isInstance(request)) {
request.headers["cf-create-bucket-if-missing"] = "true";
}
return next(args);
},
{ step: "build", name: "customHeaders" },
);
const command = new PutObjectCommand({
Bucket: "my-bucket",
Key: "my_key",
Body: "my_data",
});
const response = await client.send(command);
console.log(response);
요청마다 다른 헤더 설정 (Set a different header on each request)
R2가 S3 호환 API에서 제공하는 특정 확장 기능들은 요청마다 다른 헤더를 설정해야 할 수 있어요. 예를 들어 객체가 특정 etag 값과 일치할 때만 덮어쓰고 싶을 수 있어요. 이 값은 덮어쓰려는 객체마다 달라질 가능성이 높아서, 요청할 때마다 If-Match 헤더가 달라야 해요. 이 섹션에서는 그 방법을 보여줘요.
boto3에서 요청별 헤더 설정 (Set a header per request in boto3)
client.put_object() 호출에 커스텀 헤더를 추가 인수로 전달하려면 boto3의 이벤트 시스템에 함수 2개를 등록해야 해요. boto3는 추가 메서드 인수를 거부하는 파라미터 검증 단계를 수행하기 때문에 필요해요. 이 검증이 요청에 헤더를 설정하기 전에 일어나므로, 우선 검증이 일어나기 전에 커스텀 인수를 요청 컨텍스트로 옮겨야 해요. 다음 단계에서 요청 컨텍스트에 넣은 정보를 바탕으로 실제로 헤더를 설정할 수 있어요.
import boto3
client = boto3.resource('s3',
# Provide your Cloudflare account ID
endpoint_url = 'https://<ACCOUNT_ID>.r2.cloudflarestorage.com',
# Retrieve your S3 API credentials for your R2 bucket via API tokens (see: https://developers.cloudflare.com/r2/api/tokens)
aws_access_key_id = '<ACCESS_KEY_ID>',
aws_secret_access_key = '<SECRET_ACCESS_KEY>'
)
event_system = client.meta.events
# Moves the custom headers from the parameters to the request context
def process_custom_arguments(params, context, **kwargs):
if (custom_headers := params.pop("custom_headers", None)):
context["custom_headers"] = custom_headers
# Here we extract the headers from the request context and actually set them
def add_custom_headers(params, context, **kwargs):
if (custom_headers := context.get("custom_headers")):
params["headers"].update(custom_headers)
event_system.register('before-parameter-build.s3.PutObject', process_custom_arguments)
event_system.register('before-call.s3.PutObject', add_custom_headers)
custom_headers = {'If-Match' : '"29d911f495d1ba7cb3a4d7d15e63236a"'}
# Note that boto3 will throw an exception if the precondition failed. Catch this exception if necessary
response = client.put_object(Bucket="my-bucket", Key="my_key", Body="file_contents", custom_headers=custom_headers)
print(response)
aws-sdk-js-v3에서 요청별 헤더 설정 (Set a header per request in aws-sdk-js-v3)
여기서도 미들웨어를 만들어 설정할 헤더를 구성하지만, 이번에는 클라이언트 전체가 아니라 요청 자체에 미들웨어를 추가해요.
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { HttpRequest } from "@smithy/core/protocols";
const client = new S3Client({
region: "auto", // Required by SDK but not used by R2
// Provide your Cloudflare account ID
endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
// Retrieve your S3 API credentials for your R2 bucket via API tokens (see: https://developers.cloudflare.com/r2/api/tokens)
credentials: {
accessKeyId: ACCESS_KEY_ID,
secretAccessKey: SECRET_ACCESS_KEY,
},
});
const command = new PutObjectCommand({
Bucket: "my-bucket",
Key: "my_key",
Body: "my_data",
});
const headers = { "If-Match": '"29d911f495d1ba7cb3a4d7d15e63236a"' };
command.middlewareStack.add(
(next) => (args) => {
const request = args.request;
if (HttpRequest.isInstance(request)) {
Object.assign(request.headers, headers);
}
return next(args);
},
{ step: "build", name: "customHeaders" },
);
const response = await client.send(command);
console.log(response);