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

Rust용 AWS SDK (aws-sdk-s3)로 R2 사용하기

원문 보기 위키 갱신

Rust용 AWS SDK(aws-sdk-s3)로 R2를 사용하는 예시예요. S3 클라이언트를 구성하고 버킷·객체를 나열하고 업로드·다운로드하며 사전 서명 URL을 생성하는 방법을 보여줘요.

출처: 문서

본문

이 예시는 AWS SDK for Rust ↗︎의 aws-sdk-s3 ↗︎ 크레이트를 사용해요. S3 클라이언트를 만들 때 R2 구성 자격 증명을 반드시 전달해야 해요.

기본 사용법 (Basic Usage)

use aws_sdk_s3 as s3;
use aws_smithy_types::date_time::Format::DateTime;

#[tokio::main]
async fn main() -> Result<(), s3::Error> {
    let bucket_name = "sdk-example";
    // Provide your Cloudflare account ID
    let account_id = "<ACCOUNT_ID>";
    // Retrieve your S3 API credentials for your R2 bucket via API tokens
    // (see: https://developers.cloudflare.com/r2/api/tokens)
    let access_key_id = "<ACCESS_KEY_ID>";
    let access_key_secret = "<SECRET_ACCESS_KEY>";

    // Configure the client
    let config = aws_config::from_env()
        .endpoint_url(format!("https://{}.r2.cloudflarestorage.com", account_id))
        .credentials_provider(aws_sdk_s3::config::Credentials::new(
            access_key_id,
            access_key_secret,
            None, // session token is not used with R2
            None,
            "R2",
        ))
        .region("auto") // Required by SDK but not used by R2
        .load()
        .await;

    let client = s3::Client::new(&config);

    // List buckets
    let list_buckets_output = client.list_buckets().send().await?;

    println!("Buckets:");
    for bucket in list_buckets_output.buckets() {
        println!("  - {}: {}",
            bucket.name().unwrap_or_default(),
            bucket.creation_date().map_or_else(
                || "Unknown creation date".to_string(),
                |date| date.fmt(DateTime).unwrap()
            )
        );
    }

    // List objects in a specific bucket
    let list_objects_output = client
        .list_objects_v2()
        .bucket(bucket_name)
        .send()
        .await?;

    println!("\nObjects in {}:", bucket_name);
    for object in list_objects_output.contents() {
        println!("  - {}: {} bytes, last modified: {}",
            object.key().unwrap_or_default(),
            object.size().unwrap_or_default(),
            object.last_modified().map_or_else(
                || "Unknown".to_string(),
                |date| date.fmt(DateTime).unwrap()
            )
        );
    }

    Ok(())
}

객체 업로드 (Upload Objects)

R2에 객체를 업로드하려면:

use aws_sdk_s3::primitives::ByteStream;
use std::path::Path;

async fn upload_object(
    client: &s3::Client,
    bucket: &str,
    key: &str,
    file_path: &str,
) -> Result<(), s3::Error> {
    let body = ByteStream::from_path(Path::new(file_path)).await.unwrap();

    client
        .put_object()
        .bucket(bucket)
        .key(key)
        .body(body)
        .send()
        .await?;

    println!("Uploaded {} to {}/{}", file_path, bucket, key);
    Ok(())
}

객체 다운로드 (Download Objects)

R2에서 객체를 다운로드하려면:

use std::fs;
use std::io::Write;

async fn download_object(
    client: &s3::Client,
    bucket: &str,
    key: &str,
    output_path: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    let resp = client
        .get_object()
        .bucket(bucket)
        .key(key)
        .send()
        .await?;

    let data = resp.body.collect().await?;
    let bytes = data.into_bytes();

    let mut file = fs::File::create(output_path)?;
    file.write_all(&bytes)?;

    println!("Downloaded {}/{} to {}", bucket, key, output_path);
    Ok(())
}

사전 서명 URL 생성 (Generate Presigned URLs)

버킷에 대한 공개 읽기 또는 쓰기 접근 권한을 일시적으로 공유하는 데 사용할 수 있는 사전 서명 링크도 생성할 수 있어요.

use aws_sdk_s3::presigning::PresigningConfig;
use std::time::Duration;

async fn generate_get_presigned_url(
    client: &s3::Client,
    bucket: &str,
    key: &str,
    expires_in: Duration,
) -> Result<String, s3::Error> {
    let presigning_config = PresigningConfig::expires_in(expires_in)?;

    // Generate a presigned URL for GET (download)
    let presigned_get_request = client
        .get_object()
        .bucket(bucket)
        .key(key)
        .presigned(presigning_config)
        .await?;

    Ok(presigned_get_request.uri().to_string())
}

async fn generate_upload_presigned_url(
    client: &s3::Client,
    bucket: &str,
    key: &str,
    expires_in: Duration,
) -> Result<String, s3::Error> {
    let presigning_config = PresigningConfig::expires_in(expires_in)?;

    // Generate a presigned URL for PUT (upload)
    let presigned_put_request = client
        .put_object()
        .bucket(bucket)
        .key(key)
        .presigned(presigning_config)
        .await?;

    Ok(presigned_put_request.uri().to_string())
}

이 사전 서명 URL은 어떤 HTTP 클라이언트에서든 사용할 수 있어요. 예를 들어 PUT URL로 파일을 업로드하려면:

curl -X PUT "https://<your-presigned-put-url>" -H "Content-Type: application/octet-stream" --data-binary "@local-file.txt"

GET URL로 파일을 다운로드하려면:

curl -X GET "https://<your-presigned-get-url>" -o downloaded-file.txt

더 알아보기 (Learn more)