6666import java .nio .file .StandardOpenOption ;
6767import java .security .InvalidKeyException ;
6868import java .security .NoSuchAlgorithmException ;
69+ import java .util .Arrays ;
6970import java .util .Date ;
7071import java .util .Iterator ;
7172import java .util .LinkedList ;
7576import java .util .concurrent .CompletableFuture ;
7677import java .util .concurrent .CompletionException ;
7778import java .util .concurrent .ExecutionException ;
79+ import java .util .regex .Matcher ;
7880import okhttp3 .HttpUrl ;
7981import okhttp3 .OkHttpClient ;
8082import okhttp3 .Request ;
131133public class MinioAsyncClient extends S3Base {
132134 private MinioAsyncClient (
133135 HttpUrl baseUrl ,
134- String region ,
135- boolean isAwsHost ,
136- boolean isFipsHost ,
137- boolean isAccelerateHost ,
138- boolean isDualStackHost ,
136+ String awsS3Prefix ,
137+ String awsDomainSuffix ,
138+ boolean awsDualstack ,
139139 boolean useVirtualStyle ,
140+ String region ,
140141 Provider provider ,
141142 OkHttpClient httpClient ) {
142143 super (
143144 baseUrl ,
144- region ,
145- isAwsHost ,
146- isFipsHost ,
147- isAccelerateHost ,
148- isDualStackHost ,
145+ awsS3Prefix ,
146+ awsDomainSuffix ,
147+ awsDualstack ,
149148 useVirtualStyle ,
149+ region ,
150150 provider ,
151151 httpClient );
152152 }
@@ -3213,87 +3213,66 @@ public static Builder builder() {
32133213 /** Argument builder of {@link MinioClient}. */
32143214 public static final class Builder {
32153215 private HttpUrl baseUrl ;
3216- private String region ;
3217- private boolean isAwsHost ;
3218- private boolean isFipsHost ;
3219- private boolean isAccelerateHost ;
3220- private boolean isDualStackHost ;
3216+ private String awsS3Prefix ;
3217+ private String awsDomainSuffix ;
3218+ private boolean awsDualstack ;
32213219 private boolean useVirtualStyle ;
3220+
3221+ private String region ;
32223222 private Provider provider ;
32233223 private OkHttpClient httpClient ;
32243224
3225- private boolean isAwsChinaHost ;
3226- private String regionInUrl ;
3225+ private void setAwsInfo (String host , boolean https ) {
3226+ this .awsS3Prefix = null ;
3227+ this .awsDomainSuffix = null ;
3228+ this .awsDualstack = false ;
32273229
3228- private boolean isAwsFipsEndpoint (String endpoint ) {
3229- return endpoint .startsWith ("s3-fips." );
3230- }
3230+ if (!HttpUtils .HOSTNAME_REGEX .matcher (host ).find ()) return ;
32313231
3232- private boolean isAwsAccelerateEndpoint (String endpoint ) {
3233- return endpoint .startsWith ("s3-accelerate." );
3234- }
3232+ if (HttpUtils .AWS_ELB_ENDPOINT_REGEX .matcher (host ).find ()) {
3233+ String [] tokens = host .split ("\\ .elb\\ .amazonaws\\ .com" , 1 )[0 ].split ("\\ ." );
3234+ this .region = tokens [tokens .length - 1 ];
3235+ return ;
3236+ }
32353237
3236- private boolean isAwsEndpoint (String endpoint ) {
3237- return (endpoint .startsWith ("s3." )
3238- || isAwsFipsEndpoint (endpoint )
3239- || isAwsAccelerateEndpoint (endpoint ))
3240- && (endpoint .endsWith (".amazonaws.com" ) || endpoint .endsWith (".amazonaws.com.cn" ));
3241- }
3238+ if (!HttpUtils .AWS_ENDPOINT_REGEX .matcher (host ).find ()) return ;
32423239
3243- private boolean isAwsDualStackEndpoint (String endpoint ) {
3244- return endpoint .contains (".dualstack." );
3245- }
3240+ if (!HttpUtils .AWS_S3_ENDPOINT_REGEX .matcher (host ).find ()) {
3241+ throw new IllegalArgumentException ("invalid Amazon AWS host " + host );
3242+ }
3243+
3244+ Matcher matcher = HttpUtils .AWS_S3_PREFIX_REGEX .matcher (host );
3245+ matcher .lookingAt ();
3246+ int end = matcher .end ();
3247+
3248+ this .awsS3Prefix = host .substring (0 , end );
3249+ if (this .awsS3Prefix .contains ("s3-accesspoint" ) && !https ) {
3250+ throw new IllegalArgumentException ("use HTTPS scheme for host " + host );
3251+ }
32463252
3247- /**
3248- * Extracts region from AWS endpoint if available. Region is placed at second token normal
3249- * endpoints and third token for dualstack endpoints.
3250- *
3251- * <p>Region is marked in square brackets in below examples.
3252- * <pre>
3253- * https://s3.[us-east-2].amazonaws.com
3254- * https://s3.dualstack.[ca-central-1].amazonaws.com
3255- * https://s3.[cn-north-1].amazonaws.com.cn
3256- * https://s3.dualstack.[cn-northwest-1].amazonaws.com.cn
3257- */
3258- private String extractRegion (String endpoint ) {
3259- String [] tokens = endpoint .split ("\\ ." );
3260- String token = tokens [1 ];
3261-
3262- // If token is "dualstack", then region might be in next token.
3263- if (token .equals ("dualstack" )) {
3264- token = tokens [2 ];
3253+ String [] tokens = host .substring (end ).split ("\\ ." );
3254+ awsDualstack = "dualstack" .equals (tokens [0 ]);
3255+ if (awsDualstack ) tokens = Arrays .copyOfRange (tokens , 1 , tokens .length );
3256+ String regionInHost = null ;
3257+ if (!tokens [0 ].equals ("vpce" ) && !tokens [0 ].equals ("amazonaws" )) {
3258+ regionInHost = tokens [0 ];
3259+ tokens = Arrays .copyOfRange (tokens , 1 , tokens .length );
32653260 }
3261+ this .awsDomainSuffix = String .join ("." , tokens );
32663262
3267- // If token is equal to "amazonaws", region is not passed in the endpoint.
3268- if (token .equals ("amazonaws" )) {
3269- return null ;
3263+ if (host .equals ("s3-external-1.amazonaws.com" )) regionInHost = "us-east-1" ;
3264+ if (host .equals ("s3-us-gov-west-1.amazonaws.com" )
3265+ || host .equals ("s3-fips-us-gov-west-1.amazonaws.com" )) {
3266+ regionInHost = "us-gov-west-1" ;
32703267 }
32713268
3272- // Return token as region.
3273- return token ;
3269+ if (regionInHost != null ) this .region = regionInHost ;
32743270 }
32753271
32763272 private void setBaseUrl (HttpUrl url ) {
3277- String host = url .host ();
3278-
3279- this .isAwsHost = isAwsEndpoint (host );
3280- this .isAwsChinaHost = false ;
3281- if (this .isAwsHost ) {
3282- this .isAwsChinaHost = host .endsWith (".cn" );
3283- url =
3284- url .newBuilder ()
3285- .host (this .isAwsChinaHost ? "amazonaws.com.cn" : "amazonaws.com" )
3286- .build ();
3287- this .isFipsHost = isAwsFipsEndpoint (host );
3288- this .isAccelerateHost = isAwsAccelerateEndpoint (host );
3289- this .isDualStackHost = isAwsDualStackEndpoint (host );
3290- this .regionInUrl = extractRegion (host );
3291- this .useVirtualStyle = true ;
3292- } else {
3293- this .useVirtualStyle = host .endsWith ("aliyuncs.com" );
3294- }
3295-
32963273 this .baseUrl = url ;
3274+ this .setAwsInfo (url .host (), url .isHttps ());
3275+ this .useVirtualStyle = this .awsDomainSuffix != null || url .host ().endsWith ("aliyuncs.com" );
32973276 }
32983277
32993278 public Builder endpoint (String endpoint ) {
@@ -3325,8 +3304,9 @@ public Builder endpoint(HttpUrl url) {
33253304 }
33263305
33273306 public Builder region (String region ) {
3328- HttpUtils .validateNullOrNotEmptyString (region , "region" );
3329- this .regionInUrl = region ;
3307+ if (region != null && !HttpUtils .REGION_REGEX .matcher (region ).find ()) {
3308+ throw new IllegalArgumentException ("invalid region " + region );
3309+ }
33303310 this .region = region ;
33313311 return this ;
33323312 }
@@ -3349,7 +3329,11 @@ public Builder httpClient(OkHttpClient httpClient) {
33493329
33503330 public MinioAsyncClient build () {
33513331 HttpUtils .validateNotNull (this .baseUrl , "endpoint" );
3352- if (this .isAwsChinaHost && this .regionInUrl == null && this .region == null ) {
3332+
3333+ if (this .awsDomainSuffix != null
3334+ && this .awsDomainSuffix .endsWith (".cn" )
3335+ && !this .awsS3Prefix .endsWith ("s3-accelerate." )
3336+ && this .region == null ) {
33533337 throw new IllegalArgumentException (
33543338 "Region missing in Amazon S3 China endpoint " + this .baseUrl );
33553339 }
@@ -3358,17 +3342,15 @@ public MinioAsyncClient build() {
33583342 this .httpClient =
33593343 HttpUtils .newDefaultHttpClient (
33603344 DEFAULT_CONNECTION_TIMEOUT , DEFAULT_CONNECTION_TIMEOUT , DEFAULT_CONNECTION_TIMEOUT );
3361- if (this .region == null ) this .region = regionInUrl ;
33623345 }
33633346
33643347 return new MinioAsyncClient (
33653348 baseUrl ,
3366- region ,
3367- isAwsHost ,
3368- isFipsHost ,
3369- isAccelerateHost ,
3370- isDualStackHost ,
3349+ awsS3Prefix ,
3350+ awsDomainSuffix ,
3351+ awsDualstack ,
33713352 useVirtualStyle ,
3353+ region ,
33723354 provider ,
33733355 httpClient );
33743356 }
0 commit comments