コンテンツにスキップ

カスタムヘッダーの設定

R2の拡張機能のいくつかは、S3互換APIで使用する際に特定のヘッダーを設定する必要があります。特定の機能に対して、リクエストの全カテゴリにリクエストヘッダーを設定したい場合があります。その他の場合では、各リクエストごとに異なるヘッダーを設定したいこともあります。このページでは、boto3およびaws-sdk-js-v3を使用してそれを行う方法のいくつかの例を示します。

すべてのリクエストにカスタムヘッダーを設定する

cf-create-bucket-if-missingヘッダーのような特定の機能を使用する場合、すべてのPutObjectリクエストに対して定数ヘッダーを設定したいことがあります。

boto3を使用してすべてのリクエストにヘッダーを設定する

Boto3には、リクエストを変更するためのイベントシステムがあります。ここでは、すべてのPutObjectリクエストにヘッダーを追加する関数をイベントシステムに登録します。

import boto3
client = boto3.resource('s3',
endpoint_url = 'https://<accountid>.r2.cloudflarestorage.com',
aws_access_key_id = '<access_key_id>',
aws_secret_access_key = '<access_key_secret>'
)
event_system = client.meta.events
# ヘッダーを追加する関数を定義
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を使用してすべてのリクエストにヘッダーを設定する

aws-sdk-js-v3は、そのミドルウェアスタックを使用してリクエストの動作をカスタマイズすることを可能にします。この例では、クライアントにミドルウェアを追加し、すべてのPutObjectリクエストにヘッダーを追加します。

import {
PutObjectCommand,
S3Client,
} from "@aws-sdk/client-s3";
const client = new S3Client({
region: "auto",
endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
credentials: {
accessKeyId: ACCESS_KEY_ID,
secretAccessKey: SECRET_ACCESS_KEY,
},
});
client.middlewareStack.add(
(next, context) => async (args) => {
const r = args.request as RequestInit
r.headers["cf-create-bucket-if-missing"] = "true";
return await 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);

各リクエストに異なるヘッダーを設定する

R2がS3互換APIで提供する特定の拡張機能は、各リクエストに異なるヘッダーを設定する必要がある場合があります。たとえば、特定の期待値と一致する場合にのみオブジェクトを上書きしたいことがあります。この値は、上書きされる各オブジェクトで異なる可能性が高く、これにより、各リクエストでIf-Matchヘッダーが異なる必要があります。このセクションでは、それを達成する方法の例を示します。

boto3でリクエストごとにヘッダーを設定する

client.put_object()への呼び出しにカスタムヘッダーを追加の引数として渡すために、boto3のイベントシステムに2つの関数を登録する必要があります。これは、boto3が追加のメソッド引数を拒否するパラメータ検証ステップを実行するためです。このパラメータ検証は、リクエストのヘッダーを設定する前に発生するため、最初にカスタム引数をリクエストコンテキストに移動する必要があります。その後のステップで、リクエストコンテキストに入れた情報に基づいてヘッダーを実際に設定できます。

import boto3
client = boto3.resource('s3',
endpoint_url = 'https://<accountid>.r2.cloudflarestorage.com',
aws_access_key_id = '<access_key_id>',
aws_secret_access_key = '<access_key_secret>'
)
event_system = client.meta.events
# パラメータからリクエストコンテキストにカスタムヘッダーを移動
def process_custom_arguments(params, context, **kwargs):
if (custom_headers := params.pop("custom_headers", None)):
context["custom_headers"] = custom_headers
# リクエストコンテキストからヘッダーを抽出し、実際に設定する
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"'}
# boto3は前提条件が失敗した場合に例外をスローします。必要に応じてこの例外をキャッチしてください
response = client.put_object(Bucket="my_bucket", Key="my_key", Body="file_contents", custom_headers=custom_headers)
print(response)

aws-sdk-js-v3でリクエストごとにヘッダーを設定する

ここでも、ミドルウェアを作成して設定したいヘッダーを構成しますが、今回はクライアント全体ではなく、リクエスト自体にミドルウェアを追加します。

import {
PutObjectCommand,
S3Client,
} from "@aws-sdk/client-s3";
const client = new S3Client({
region: "auto",
endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
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 r = args.request as RequestInit
Object.entries(headers).forEach(
([k, v]: [key: string, value: string]): void => {
r.headers[k] = v
},
)
return next(args)
},
{ step: 'build', name: 'customHeaders' },
)
const response = await client.send(command);
console.log(response);