Skip to content

Commit

Permalink
api: ListBuckets() should have a default region for AWS S3.
Browse files Browse the repository at this point in the history
Fixes #717
  • Loading branch information
harshavardhana authored and minio-trusted committed Jun 21, 2017
1 parent 4dde80b commit db684ac
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 8 deletions.
25 changes: 17 additions & 8 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,15 +558,24 @@ func (c Client) newRequest(method string, metadata requestMetadata) (req *http.R
method = "POST"
}

var location string
// Gather location only if bucketName is present.
if metadata.bucketName != "" && metadata.bucketLocation == "" {
location, err = c.getBucketLocation(metadata.bucketName)
if err != nil {
return nil, err
location := metadata.bucketLocation
if location == "" {
switch {
case metadata.bucketName != "":
// Gather location only if bucketName is present.
location, err = c.getBucketLocation(metadata.bucketName)
if err != nil {
if ToErrorResponse(err).Code != "AccessDenied" {
return nil, err
}
}
// Upon AccessDenied error on fetching bucket location, default
// to possible locations based on endpoint URL. This can usually
// happen when GetBucketLocation() is disabled using IAM policies.
}
if location == "" {
location = getDefaultLocation(c.endpointURL, c.region)
}
} else {
location = metadata.bucketLocation
}

// Construct a new target URL.
Expand Down
21 changes: 21 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,24 @@ func redactSignature(origAuth string) string {
// Strip out 256-bit signature from: Signature=<256-bit signature>
return regSign.ReplaceAllString(newAuth, "Signature=**REDACTED**")
}

// Get default location returns the location based on the input
// URL `u`, if none of the standard URL matches then if regionOverride
// is given location gets defaulted to that instead.
//
// If no other cases match then the location is set to `us-east-1`
// as a last resort.
func getDefaultLocation(u url.URL, regionOverride string) (location string) {
// Default to location to 'us-east-1'.
switch {
case s3utils.IsAmazonChinaEndpoint(u):
location = "cn-north-1"
case s3utils.IsAmazonGovCloudEndpoint(u):
location = "us-gov-west-1"
case regionOverride != "":
location = regionOverride
default:
location = "us-east-1"
}
return
}
42 changes: 42 additions & 0 deletions utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ func TestIsValidEndpointURL(t *testing.T) {
{"/", nil, true},
{"https://s3.am1;4205;0cazonaws.com", nil, true},
{"https://s3.cn-north-1.amazonaws.com.cn", nil, true},
{"https://s3.us-gov-west-1.amazonaws.com", nil, true},
{"https://s3-fips-us-gov-west-1.amazonaws.com", nil, true},
{"https://s3.amazonaws.com/", nil, true},
{"https://storage.googleapis.com/", nil, true},
{"192.168.1.1", ErrInvalidArgument("Endpoint url cannot have fully qualified paths."), false},
Expand Down Expand Up @@ -165,6 +167,46 @@ func TestIsValidEndpointURL(t *testing.T) {
}
}

func TestDefaultBucketLocation(t *testing.T) {
testCases := []struct {
endpointURL url.URL
regionOverride string
expectedLocation string
}{
// Region override is ignored. - Test 1.
{
endpointURL: url.URL{Host: "s3-fips-us-gov-west-1.amazonaws.com"},
regionOverride: "us-west-1",
expectedLocation: "us-gov-west-1",
},
// Region override is honored - Test 2.
{
endpointURL: url.URL{Host: "s3.amazonaws.com"},
regionOverride: "us-west-1",
expectedLocation: "us-west-1",
},
// China region should be honored, region override not provided. - Test 3.
{
endpointURL: url.URL{Host: "s3.cn-north-1.amazonaws.com.cn"},
regionOverride: "",
expectedLocation: "cn-north-1",
},
// No region provided, no standard region strings provided as well. -- Test 4.
{
endpointURL: url.URL{Host: "s3.amazonaws.com"},
regionOverride: "",
expectedLocation: "us-east-1",
},
}

for i, testCase := range testCases {
retLocation := getDefaultLocation(testCase.endpointURL, testCase.regionOverride)
if testCase.expectedLocation != retLocation {
t.Errorf("Test %d: Expected location %s, got %s", i+1, testCase.expectedLocation, retLocation)
}
}
}

// Tests validate the expiry time validator.
func TestIsValidExpiry(t *testing.T) {
testCases := []struct {
Expand Down

0 comments on commit db684ac

Please sign in to comment.