From 98ea9174770693035158b5efba8efef1abe4a934 Mon Sep 17 00:00:00 2001 From: Timur Alperovich Date: Wed, 11 Jan 2017 18:14:57 -0800 Subject: [PATCH] GetBucketLocation should use path-style requests. When making a GetBucketLocation request, Amazon may route the request to the bucket region. When making it with v4 signer, the request may fail because of the region mismatch. Concretely, a request to test.s3.amazonaws.com may resolve to s3-us-west-2-w.amazonaws.com. The request itself is prepared for the us-east-1 region (s3.amazonaws.com endpoint), but then fails when the DNS resolution points to a us-west-2 endpoint. Bucket-in-path works around this for the GetBucketLocation requests. That means that every GetBucketLocation request will be of the form: https://s3.amazonaws.com/{bucket}?location. This ensures that jclouds requests will not be subjected to Amazon's routing/DNS pointers. Fixes: JCLOUDS-1213 --- apis/s3/src/main/java/org/jclouds/s3/S3Client.java | 4 ++-- .../java/org/jclouds/aws/s3/AWSS3ClientExpectTest.java | 5 ++--- .../test/java/org/jclouds/aws/s3/AWSS3ClientTest.java | 10 ++++------ 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java index cb1d9bd47c..7f80f3b71a 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java @@ -533,10 +533,10 @@ public interface S3Client extends Closeable { @Named("GetBucketLocation") @GET @QueryParams(keys = "location") - @Path("/") + @Path("/{bucket}") @Endpoint(Bucket.class) @XMLResponseParser(LocationConstraintHandler.class) - String getBucketLocation(@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( + String getBucketLocation(@Bucket @PathParam("bucket") @ParamValidators( BucketNameValidator.class) String bucketName); diff --git a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientExpectTest.java b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientExpectTest.java index b4e493cbef..db1ed95a15 100644 --- a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientExpectTest.java +++ b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientExpectTest.java @@ -36,10 +36,9 @@ public class AWSS3ClientExpectTest extends BaseAWSS3ClientExpectTest { HttpRequest bucketLocationRequest = HttpRequest.builder() .method("GET") - .endpoint("https://test.s3.amazonaws.com/?location") - .addHeader("Host", "test.s3.amazonaws.com") + .endpoint("https://s3.amazonaws.com/test?location") .addHeader("Date", CONSTANT_DATE) - .addHeader("Authorization", "AWS identity:D1rymKrEdvzvhmZXeg+Z0R+tiug=").build(); + .addHeader("Authorization", "AWS identity:sOZnJSLuwnMVn7CiEKcVmpFI0rU=").build(); HttpResponse bucketLocationResponse = HttpResponse.builder() .statusCode(200) diff --git a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientTest.java b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientTest.java index 4d58afb5ef..6b2f36fcdd 100644 --- a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientTest.java +++ b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ClientTest.java @@ -80,8 +80,7 @@ public class AWSS3ClientTest extends S3ClientTest { Invokable method = method(AWSS3Client.class, "getBucketLocation", String.class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("bucket-eu-west-1")); - assertRequestLineEquals(request, "GET https://bucket-eu-west-1.s3.amazonaws.com/?location HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Host: bucket-eu-west-1.s3.amazonaws.com\n"); + assertRequestLineEquals(request, "GET https://s3.amazonaws.com/bucket-eu-west-1?location HTTP/1.1"); assertPayloadEquals(request, null, null, false); assertResponseParserClassEquals(method, request, ParseSax.class); @@ -116,16 +115,15 @@ public class AWSS3ClientTest extends S3ClientTest { Invokable method = method(AWSS3Client.class, "getBucketLocation", String.class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("bucket")); - assertRequestLineEquals(request, "GET https://bucket.s3.amazonaws.com/?location HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Host: bucket.s3.amazonaws.com\n"); + assertRequestLineEquals(request, "GET https://s3.amazonaws.com/bucket?location HTTP/1.1"); assertPayloadEquals(request, null, null, false); request = (GeneratedHttpRequest) filter.filter(request); - assertRequestLineEquals(request, "GET https://bucket.s3.amazonaws.com/?location HTTP/1.1"); + assertRequestLineEquals(request, "GET https://s3.amazonaws.com/bucket?location HTTP/1.1"); assertNonPayloadHeadersEqual( request, - "Authorization: AWS identity:2fFTeYJTDwiJmaAkKj732RjNbOg=\nDate: 2009-11-08T15:54:08.897Z\nHost: bucket.s3.amazonaws.com\n"); + "Authorization: AWS identity:f1Pt8/8Yr/HZahuc6KPI1B2+Mw4=\nDate: 2009-11-08T15:54:08.897Z\n"); assertPayloadEquals(request, null, null, false); assertResponseParserClassEquals(method, request, ParseSax.class);