跳转到内容
搜索文档

配置自定义请求头

最后更新 查看 MarkdownAgent 设置

R2 的某些扩展在 S3 兼容 API 中使用时需要设置特定的请求头。对于某些功能,您可能希望为一整类请求设置请求头。其他情况下,您可能希望为每个单独请求配置不同的请求头。本页包含如何使用 boto3aws-sdk-js-v3 实现此目的的示例。

为所有请求设置自定义请求头

使用某些功能(例如 cf-create-bucket-if-missing 请求头)时,您可能希望为所有 PutObject 请求设置固定的请求头。

使用 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 为所有请求设置请求头

aws-sdk-js-v3 允许通过其中间件栈自定义请求行为。此示例向客户端添加中间件,为每个 PutObject 请求添加请求头。

import {
  PutObjectCommand,
  S3Client,
} from "@aws-sdk/client-s3";

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, 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 中提供的某些扩展可能需要为每个请求设置不同的请求头。例如,您可能只想在对象的 etag 与某个预期值匹配时才覆盖该对象。该值对于每个被覆盖的对象可能不同,因此需要 If-Match 请求头随每次请求而变化。本节展示如何实现这一点。

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 中为每个请求设置请求头

此处我们再次通过创建中间件来配置要设置的请求头,但这次将中间件添加到请求本身,而不是整个客户端。

import {
  PutObjectCommand,
  S3Client,
} from "@aws-sdk/client-s3";

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

这篇文档对您有帮助吗?