Install rust-s3 via Cargo
masterAdd rust-s3 to your Cargo.toml dependencies to use the library in your Rust project.
[dependencies]
rust-s3 = "0.37.2"repository·master·Indexed 19 days ago
https://github.com/durch/rust-s3A flexible Rust library for interacting with Amazon S3 and S3-compatible object storage APIs such as Minio, R2, Google Cloud Storage, and Backblaze B2. It supports async/await (via tokio or async-std) and synchronous execution models. The library includes the aws-creds crate for managing IAM credentials from environment variables, credential files, and STS, as well as the aws-region crate for defining AWS S3 region identifiers and custom endpoints.
Add rust-s3 to your Cargo.toml dependencies to use the library in your Rust project.
[dependencies]
rust-s3 = "0.37.2"The aws-region crate provides a Region type to represent AWS S3 region identifiers. You can create a Region instance by parsing a string, using a predefined enum variant for standard AWS regions, or by defining a Custom region with a specific name and endpoint.
Important: When using Region::Custom, you must provide a valid endpoint. Providing an invalid endpoint for a custom region will result in errors during operation.
use std::str::FromStr;
use awsregion::Region;
// Parse from a string
let region: Region = "us-east-1".parse().unwrap();
// Choose region directly
let region = Region::EuWest2;
// Custom region requires valid region name and endpoint
let region_name = "nl-ams".to_string();
let endpoint = "https://s3.nl-ams.scw.cloud".to_string();
let region = Region::Custom { region: region_name, endpoint };The aws-creds crate provides utilities to load AWS access credentials (access key, secret key, and optional session token) from multiple sources.
Credentials can be loaded in the following order of preference:
Credentials::new().AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN.To load from the standard AWS credentials file, use Credentials::default() (which uses the [default] profile) or Credentials::new() with a profile name provided as the fourth argument.
use awscreds::Credentials;
// Load from [default] profile in AWS credentials file
let credentials = Credentials::default();
// Load from [my-profile] profile in AWS credentials file
let credentials = Credentials::new(None, None, None, Some("my-profile".into()));When uploading large files via put_object_stream, the library automatically manages multipart uploads to optimize performance and memory usage.
CHUNK_SIZE (8MB), it performs a standard PutObject.initiate_multipart_upload to get an upload_id.max_concurrent_chunks based on available system memory (clamped between 2 and 100) to prevent OOM errors. It uses FuturesUnordered to upload multiple chunks concurrently.abort_upload to clean up the partial upload on S3.complete_multipart_upload to finalize the file.The library supports multiple runtimes and execution models via Cargo features. You can choose between tokio (default), async-std, or a purely synchronous (sync) implementation.
Key features include:
default: Uses tokio runtime and native-tls.blocking: Generates *_blocking variants of all Bucket methods for synchronous use.fail-on-err: Returns Result::Err for HTTP errors instead of treating them as successful responses.with-async-std: Uses async-std runtime and surf client.sync: Uses no async runtime and attohttpc for HTTP requests.tags: Required to use Bucket::get_object_tagging.All runtimes support either native-tls or rustls-tls.
# tokio, default
cargo run --example tokio
# async-std
cargo run --example async-std --no-default-features --features async-std-native-tls
# sync
cargo run --example sync --no-default-features --features sync-native-tls
# minio
cargo run --example minio
# r2
cargo run --example r2
# google cloud
cargo run --example google-cloudThe Region enum is used to specify the S3 region or provider endpoint. It supports standard AWS regions, DigitalOcean, Wasabi, Cloudflare R2, OVH, and Yandex. You can use predefined variants, parse from a string, or use a Custom variant for any S3-compatible provider.
Note on Custom Regions: When using Region::Custom, you must provide both a valid region name and a valid endpoint. If you parse an unknown string using FromStr, it will automatically default to a Custom region where the region name and endpoint are identical.
use std::str::FromStr;
use awsregion::Region;
// Parse from a string
let region: Region = "us-east-1".parse().unwrap();
// Choose region directly
let region = Region::EuWest2;
// Custom region requires valid region name and endpoint
let region_name = "nl-ams".to_string();
let endpoint = "https://s3.nl-ams.scw.cloud".to_string();
let region = Region::Custom { region: region_name, endpoint };Use the CannedBucketAcl enum to apply standard, predefined Amazon S3 access control lists (ACLs) to a bucket. This is a convenient way to set common permission levels without defining granular user/group permissions.
Available variants:
Private: Only the owner has full control.PublicRead: Anyone can read objects in the bucket.PublicReadWrite: Anyone can read and write objects in the bucket.AuthenticatedRead: Only authenticated AWS users can read objects.Custom(String): Allows specifying a custom ACL string.use rust_s3::CannedBucketAcl;
// Example: Setting a bucket to public read
let acl = CannedBucketAcl::PublicRead;For more precise control, use the BucketAcl enum to grant specific permissions to individual users, groups, or email addresses. These can be used within a BucketConfiguration to populate grant fields like grant_read or grant_full_control.
use rust_s3::BucketAcl;
let user_acl = BucketAcl::Id { id: "user-id-123".to_string() };
let group_acl = BucketAcl::Uri { uri: "http://example.com/group".to_string() };
let email_acl = BucketAcl::Email { email: "user@example.com".to_string() };The library provides structured types for parsing S3 listing responses:
ListBucketResult: Represents the result of ListObjects or ListObjectsV2. It contains metadata about the bucket and a list of Objects. It handles pagination via is_truncated and next_continuation_token (or next_marker for older API versions).Object: Represents an individual item in a bucket, containing the key, size, last_modified date, e_tag, and storage_class.ListMultipartUploadsResult: Represents a list of ongoing multipart uploads in a bucket.Use PostPolicy to create secure, conditional upload URLs for S3. You define an expiration time and a set of conditions (like file size limits or specific keys) that the upload must satisfy. Once signed, it produces a PresignedPost object containing the upload URL and the necessary form fields.
PostPolicy::new(expiration)..condition(field, value) to restrict the upload (e.g., limiting the file path or size)..sign(bucket) to generate the PresignedPost.url and the combined fields and dynamic_fields from the PresignedPost to perform a multipart/form-data POST request to S3.// Example: Create a policy that allows uploading a file to a specific prefix
// with a maximum size of 3MB, expiring in 1 hour.
let policy = PostPolicy::new(3600)
.condition(
PostPolicyField::Key,
PostPolicyValue::StartsWith(Cow::from("uploads/user1/"))
)?
.condition(
PostPolicyField::ContentLengthRange,
PostPolicyValue::Range(0, 3_000_000)
)?;
let presigned_post = policy.sign(bucket).await?;
// Use presigned_post.url and the fields for your HTTP clientSome S3-compatible services (like LocalStack) do not support AWS-style location constraints in bucket creation requests and may return InvalidLocationConstraint errors. You can skip sending these constraints by setting the RUST_S3_SKIP_LOCATION_CONSTRAINT environment variable to true or 1.
export RUST_S3_SKIP_LOCATION_CONSTRAINT=true
# or
export RUST_S3_SKIP_LOCATION_CONSTRAINT=1You can bypass environment variables and credential files by passing the keys directly to the Credentials::new constructor.
use s3::credentials::Credentials;
let access_key = String::from("AKIAIOSFODNN7EXAMPLE");
let secret_key = String::from("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
// Arguments: access_key, secret_key, session_token, profile_name
let credentials = Credentials::new(Some(access_key), Some(secret_key), None, None);