INTEGRITY Dokumentace

Konfigurace vlastních hlaviček

Některé z R2 rozšíření vyžadují při použití v rozhraní API kompatibilním s S3 nastavení konkrétní hlavičky. U některých funkcí může být potřeba nastavit hlavičku požadavku pro celou kategorii požadavků. Jindy může být potřeba nakonfigurovat odlišnou hlavičku pro každý jednotlivý požadavek. Tato stránka obsahuje několik příkladů, jak to provést pomocí boto3 a s aws-sdk-js-v3.

Nastavení vlastní hlavičky pro všechny požadavky

Při používání některých funkcí, jako je cf-create-bucket-if-missing hlavičku, možná budete chtít nastavit konstantní hlavičku pro všechny PutObject požadavků, které odesíláte.

Nastavení hlavičky pro všechny požadavky pomocí boto3

Boto3 má systém událostí, který umožňuje upravovat požadavky. Zde do tohoto systému zaregistrujeme funkci, která přidá naši hlavičku ke každému PutObject odesílaného požadavku.

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)

Nastavení hlavičky pro všechny požadavky pomocí aws-sdk-js-v3

aws-sdk-js-v3 umožňuje přizpůsobit chování požadavků pomocí zásobník middlewaru. Tento příklad přidává do klienta middleware, který přidává hlavičku ke každému PutObject odesílaného požadavku.

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

Nastavení odlišné hlavičky pro každý požadavek

Některá rozšíření, která R2 poskytuje v rámci S3 kompatibilního API, mohou vyžadovat nastavení jiné hlavičky pro každý požadavek. Můžete například chtít přepsat objekt pouze tehdy, pokud jeho etag odpovídá určité očekávané hodnotě. Tato hodnota se pravděpodobně bude lišit pro každý přepisovaný objekt, což vyžaduje If-Match hlavička se lišila s každým požadavkem, který odešlete. Tato část ukazuje příklady, jak toho dosáhnout.

Nastavení hlavičky pro jednotlivý požadavek v boto3

Aby bylo možné předat vlastní hlavičky jako další argument do volání client.put_object() musíme zaregistrovat 2 funkce do boto3systém událostí. To je nutné, protože boto3 provádí krok ověření parametrů, který odmítá nadbytečné argumenty metody. Protože k tomuto ověření parametrů dochází dříve, než lze nastavit hlavičky požadavku, je nejprve nutné přesunout vlastní argument do kontextu požadavku, než k ověření parametrů dojde. V dalším kroku pak lze hlavičky nastavit na základě informací, které jsme do kontextu požadavku vložili.

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)

Nastavení hlavičky pro jednotlivý požadavek v aws-sdk-js-v3

I zde nastavíme požadovanou hlavičku vytvořením middlewaru, tentokrát jej ale přidáme přímo k požadavku, a ne k celému klientovi.

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