aws-sdk-rust
You must generate an Access Key before getting started. All examples will utilize access_key_id
and access_key_secret
variables which represent the Access Key ID and Secret Access Key values you generated.
This example uses the aws-sdk-s3 ↗ crate from the AWS SDK for Rust ↗. You must pass in the R2 configuration credentials when instantiating your S3
client:
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"; let account_id = "<accountid>"; let access_key_id = "<access_key_id>"; let access_key_secret = "<access_key_secret>";
// 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") .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(())}
To upload an object to 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(())}
To download an object from 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(())}
You can also generate presigned links that can be used to temporarily share public read or write access to a bucket.
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())}
You can use these presigned URLs with any HTTP client. For example, to upload a file using the PUT URL:
curl -X PUT "https://<your-presigned-put-url>" -H "Content-Type: application/octet-stream" --data-binary "@local-file.txt"
To download a file using the GET URL:
curl -X GET "https://<your-presigned-get-url>" -o downloaded-file.txt
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Products
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark