diff options
Diffstat (limited to 'vendor/github.com/minio/minio-go/pkg/s3utils')
-rw-r--r-- | vendor/github.com/minio/minio-go/pkg/s3utils/utils.go | 93 | ||||
-rw-r--r-- | vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go | 85 |
2 files changed, 177 insertions, 1 deletions
diff --git a/vendor/github.com/minio/minio-go/pkg/s3utils/utils.go b/vendor/github.com/minio/minio-go/pkg/s3utils/utils.go index a3b6ed845..9d6ac4d81 100644 --- a/vendor/github.com/minio/minio-go/pkg/s3utils/utils.go +++ b/vendor/github.com/minio/minio-go/pkg/s3utils/utils.go @@ -19,6 +19,7 @@ package s3utils import ( "bytes" "encoding/hex" + "errors" "net" "net/url" "regexp" @@ -84,10 +85,29 @@ func IsAmazonEndpoint(endpointURL url.URL) bool { if IsAmazonChinaEndpoint(endpointURL) { return true } - + if IsAmazonGovCloudEndpoint(endpointURL) { + return true + } return endpointURL.Host == "s3.amazonaws.com" } +// IsAmazonGovCloudEndpoint - Match if it is exactly Amazon S3 GovCloud endpoint. +func IsAmazonGovCloudEndpoint(endpointURL url.URL) bool { + if endpointURL == sentinelURL { + return false + } + return (endpointURL.Host == "s3-us-gov-west-1.amazonaws.com" || + IsAmazonFIPSGovCloudEndpoint(endpointURL)) +} + +// IsAmazonFIPSGovCloudEndpoint - Match if it is exactly Amazon S3 FIPS GovCloud endpoint. +func IsAmazonFIPSGovCloudEndpoint(endpointURL url.URL) bool { + if endpointURL == sentinelURL { + return false + } + return endpointURL.Host == "s3-fips-us-gov-west-1.amazonaws.com" +} + // IsAmazonChinaEndpoint - Match if it is exactly Amazon S3 China endpoint. // Customers who wish to use the new Beijing Region are required // to sign up for a separate set of account credentials unique to @@ -181,3 +201,74 @@ func EncodePath(pathName string) string { } return encodedPathname } + +// We support '.' with bucket names but we fallback to using path +// style requests instead for such buckets. +var ( + validBucketName = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9\.\-]{1,61}[A-Za-z0-9]$`) + validBucketNameStrict = regexp.MustCompile(`^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$`) + ipAddress = regexp.MustCompile(`^(\d+\.){3}\d+$`) +) + +// Common checker for both stricter and basic validation. +func checkBucketNameCommon(bucketName string, strict bool) (err error) { + if strings.TrimSpace(bucketName) == "" { + return errors.New("Bucket name cannot be empty") + } + if len(bucketName) < 3 { + return errors.New("Bucket name cannot be smaller than 3 characters") + } + if len(bucketName) > 63 { + return errors.New("Bucket name cannot be greater than 63 characters") + } + if ipAddress.MatchString(bucketName) { + return errors.New("Bucket name cannot be an ip address") + } + if strings.Contains(bucketName, "..") { + return errors.New("Bucket name contains invalid characters") + } + if strict { + if !validBucketNameStrict.MatchString(bucketName) { + err = errors.New("Bucket name contains invalid characters") + } + return err + } + if !validBucketName.MatchString(bucketName) { + err = errors.New("Bucket name contains invalid characters") + } + return err +} + +// CheckValidBucketName - checks if we have a valid input bucket name. +// This is a non stricter version. +// - http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html +func CheckValidBucketName(bucketName string) (err error) { + return checkBucketNameCommon(bucketName, false) +} + +// CheckValidBucketNameStrict - checks if we have a valid input bucket name. +// This is a stricter version. +func CheckValidBucketNameStrict(bucketName string) (err error) { + return checkBucketNameCommon(bucketName, true) +} + +// CheckValidObjectNamePrefix - checks if we have a valid input object name prefix. +// - http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html +func CheckValidObjectNamePrefix(objectName string) error { + if len(objectName) > 1024 { + return errors.New("Object name cannot be greater than 1024 characters") + } + if !utf8.ValidString(objectName) { + return errors.New("Object name with non UTF-8 strings are not supported") + } + return nil +} + +// CheckValidObjectName - checks if we have a valid input object name. +// - http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html +func CheckValidObjectName(objectName string) error { + if strings.TrimSpace(objectName) == "" { + return errors.New("Object name cannot be empty") + } + return CheckValidObjectNamePrefix(objectName) +} diff --git a/vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go b/vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go index f790861cd..6be701d18 100644 --- a/vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go +++ b/vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go @@ -17,6 +17,7 @@ package s3utils import ( + "errors" "net/url" "testing" ) @@ -282,3 +283,87 @@ func TestEncodePath(t *testing.T) { } } } + +// Tests validate the bucket name validator. +func TestIsValidBucketName(t *testing.T) { + testCases := []struct { + // Input. + bucketName string + // Expected result. + err error + // Flag to indicate whether test should Pass. + shouldPass bool + }{ + {".mybucket", errors.New("Bucket name contains invalid characters"), false}, + {"$mybucket", errors.New("Bucket name contains invalid characters"), false}, + {"mybucket-", errors.New("Bucket name contains invalid characters"), false}, + {"my", errors.New("Bucket name cannot be smaller than 3 characters"), false}, + {"", errors.New("Bucket name cannot be empty"), false}, + {"my..bucket", errors.New("Bucket name contains invalid characters"), false}, + {"192.168.1.168", errors.New("Bucket name cannot be an ip address"), false}, + {"my.bucket.com", nil, true}, + {"my-bucket", nil, true}, + {"123my-bucket", nil, true}, + {"Mybucket", nil, true}, + } + + for i, testCase := range testCases { + err := CheckValidBucketName(testCase.bucketName) + if err != nil && testCase.shouldPass { + t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error()) + } + if err == nil && !testCase.shouldPass { + t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error()) + } + // Failed as expected, but does it fail for the expected reason. + if err != nil && !testCase.shouldPass { + if err.Error() != testCase.err.Error() { + t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error()) + } + } + + } + +} + +// Tests validate the bucket name validator stricter. +func TestIsValidBucketNameStrict(t *testing.T) { + testCases := []struct { + // Input. + bucketName string + // Expected result. + err error + // Flag to indicate whether test should Pass. + shouldPass bool + }{ + {".mybucket", errors.New("Bucket name contains invalid characters"), false}, + {"$mybucket", errors.New("Bucket name contains invalid characters"), false}, + {"mybucket-", errors.New("Bucket name contains invalid characters"), false}, + {"my", errors.New("Bucket name cannot be smaller than 3 characters"), false}, + {"", errors.New("Bucket name cannot be empty"), false}, + {"my..bucket", errors.New("Bucket name contains invalid characters"), false}, + {"192.168.1.168", errors.New("Bucket name cannot be an ip address"), false}, + {"Mybucket", errors.New("Bucket name contains invalid characters"), false}, + {"my.bucket.com", nil, true}, + {"my-bucket", nil, true}, + {"123my-bucket", nil, true}, + } + + for i, testCase := range testCases { + err := CheckValidBucketNameStrict(testCase.bucketName) + if err != nil && testCase.shouldPass { + t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error()) + } + if err == nil && !testCase.shouldPass { + t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error()) + } + // Failed as expected, but does it fail for the expected reason. + if err != nil && !testCase.shouldPass { + if err.Error() != testCase.err.Error() { + t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error()) + } + } + + } + +} |