@@ -13,7 +13,7 @@ use aws_sdk_s3::{
1313use std:: future:: Future ;
1414use tokio:: runtime:: Runtime ;
1515
16- /// A [`Service`] implementation based on the Google Cloud Storage service .
16+ /// A [`Service`] implementation based on the AWS Simple Storage Service .
1717pub ( in crate :: server) struct AwsService {
1818 client : s3:: Client ,
1919 rt : Runtime ,
@@ -63,9 +63,11 @@ pub enum AwsCredentials {
6363
6464impl AwsService {
6565 pub ( in crate :: server) fn new (
66- region : String ,
66+ region : Option < String > ,
6767 bucket : String ,
6868 creds : AwsCredentials ,
69+ endpoint_url : Option < String > ,
70+ force_path_style : bool ,
6971 ) -> Result < Self > {
7072 let rt = Runtime :: new ( ) ?;
7173
@@ -92,13 +94,37 @@ impl AwsService {
9294 // Just use the default.
9395 }
9496 }
95- config_provider
96- . region ( RegionProviderChain :: first_try ( Region :: new ( region) ) )
97- . load ( )
98- . await
97+ // This will:
98+ // 1. If a region is set, use it
99+ // 2. if No region is set, follow the AWS default provider chain
100+ // (https://docs.aws.amazon.com/sdk-for-rust/latest/dg/region.html)
101+ // 3. If no region is discovered, hardcode to "us-east-1"
102+ //
103+ // If there's a region specified we will always prefer that
104+ // next, the default provider chain will look at things like AWS_REGION environment
105+ // variables, the profile file, etc.
106+ //
107+ // we provide the hardcoded fallback because a region MUST be set
108+ // but, a region being set does _not_ make sense if endpoint_url is set, because
109+ // the endpoint URL would include a region.
110+ // realistically, endpoint_url is more useful for S3-compatible services
111+ // and would not use a separate region in addition to endpoint_url.
112+ config_provider = config_provider. region (
113+ RegionProviderChain :: first_try ( region. map ( Region :: new) )
114+ . or_default_provider ( )
115+ . or_else ( Region :: new ( "us-east-1" ) ) ,
116+ ) ;
117+ match endpoint_url {
118+ Some ( url) => config_provider = config_provider. endpoint_url ( url) ,
119+ None => { }
120+ }
121+ config_provider. load ( ) . await
99122 } ) ;
100123
101- let client = s3:: client:: Client :: new ( & config) ;
124+ let s3_config = aws_sdk_s3:: config:: Builder :: from ( & config)
125+ . force_path_style ( force_path_style)
126+ . build ( ) ;
127+ let client = aws_sdk_s3:: Client :: from_conf ( s3_config) ;
102128 Ok ( Self { client, rt, bucket } )
103129 }
104130
@@ -405,12 +431,14 @@ mod tests {
405431
406432 Some (
407433 AwsService :: new (
408- region,
434+ Some ( region) ,
409435 bucket,
410436 AwsCredentials :: AccessKey {
411437 access_key_id,
412438 secret_access_key,
413439 } ,
440+ None ,
441+ false ,
414442 )
415443 . unwrap ( ) ,
416444 )
0 commit comments