Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions src/services/storage/providers/s3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use aws_config::retry::RetryConfig;
use aws_sdk_s3 as s3;
use aws_sdk_s3::config::BehaviorVersion;
use aws_sdk_s3::config::Region;
use aws_sdk_s3::config::RequestChecksumCalculation;
use aws_sdk_s3::config::retry::ReconnectMode;
use aws_sdk_s3::error::DisplayErrorContext;
use aws_sdk_s3::primitives::ByteStream;
use aws_sdk_s3::types::{CompletedMultipartUpload, CompletedPart};
use futures::StreamExt;
Expand Down Expand Up @@ -135,6 +137,10 @@ impl StorageProvider for S3Provider {
.credentials_provider(credentials)
.region(region)
.force_path_style(true)
// S3-compatible endpoints (MinIO, Garage, RustFS, Synology, ...) reject the
// default CRC32 integrity checksums the SDK attaches to multipart uploads.
// Only send checksums when the operation actually requires them.
.request_checksum_calculation(RequestChecksumCalculation::WhenRequired)
.endpoint_url(endpoint)
.behavior_version(BehaviorVersion::latest())
.build();
Expand Down Expand Up @@ -164,11 +170,12 @@ impl StorageProvider for S3Provider {
{
Ok(r) => r,
Err(e) => {
error!("Failed to create multipart upload: {}", e);
let detail = DisplayErrorContext(&e).to_string();
error!("Failed to create multipart upload: {}", detail);
return UploadResult {
storage_id: storage.id.clone(),
success: false,
error: Some(e.to_string()),
error: Some(detail),
remote_file_path: None,
total_size: None,
};
Expand Down Expand Up @@ -251,7 +258,8 @@ impl StorageProvider for S3Provider {
}
}
Err(e) => {
error!("Failed to upload part {}: {}", part_number, e);
let detail = DisplayErrorContext(&e).to_string();
error!("Failed to upload part {}: {}", part_number, detail);
let _ = client
.abort_multipart_upload()
.bucket(bucket)
Expand All @@ -262,7 +270,7 @@ impl StorageProvider for S3Provider {
return UploadResult {
storage_id: storage.id.clone(),
success: false,
error: Some(e.to_string()),
error: Some(detail),
remote_file_path: None,
total_size: None,
};
Expand Down Expand Up @@ -317,7 +325,8 @@ impl StorageProvider for S3Provider {
}
}
Err(e) => {
error!("Failed to complete multipart upload: {}", e);
let detail = DisplayErrorContext(&e).to_string();
error!("Failed to complete multipart upload: {}", detail);
let _ = client
.abort_multipart_upload()
.bucket(bucket)
Expand All @@ -328,7 +337,7 @@ impl StorageProvider for S3Provider {
UploadResult {
storage_id: storage.id.clone(),
success: false,
error: Some(e.to_string()),
error: Some(detail),
remote_file_path: None,
total_size: None,
}
Expand Down
Loading