본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

커스텀 헤더 구성하기

원문 보기 위키 갱신

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);

더 알아보기 (Learn more)