summaryrefslogtreecommitdiff
path: root/vendor/github.com/minio/minio-go/v7/pkg/s3utils/utils.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/minio/minio-go/v7/pkg/s3utils/utils.go')
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/s3utils/utils.go102
1 files changed, 93 insertions, 9 deletions
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/s3utils/utils.go b/vendor/github.com/minio/minio-go/v7/pkg/s3utils/utils.go
index eb631249b..7427c13de 100644
--- a/vendor/github.com/minio/minio-go/v7/pkg/s3utils/utils.go
+++ b/vendor/github.com/minio/minio-go/v7/pkg/s3utils/utils.go
@@ -95,6 +95,12 @@ var amazonS3HostFIPS = regexp.MustCompile(`^s3-fips.(.*?).amazonaws.com$`)
// amazonS3HostFIPSDualStack - regular expression used to determine if an arg is s3 FIPS host dualstack.
var amazonS3HostFIPSDualStack = regexp.MustCompile(`^s3-fips.dualstack.(.*?).amazonaws.com$`)
+// amazonS3HostExpress - regular expression used to determine if an arg is S3 Express zonal endpoint.
+var amazonS3HostExpress = regexp.MustCompile(`^s3express-[a-z0-9]{3,7}-az[1-6]\.([a-z0-9-]+)\.amazonaws\.com$`)
+
+// amazonS3HostExpressControl - regular expression used to determine if an arg is S3 express regional endpoint.
+var amazonS3HostExpressControl = regexp.MustCompile(`^s3express-control\.([a-z0-9-]+)\.amazonaws\.com$`)
+
// amazonS3HostDot - regular expression used to determine if an arg is s3 host in . style.
var amazonS3HostDot = regexp.MustCompile(`^s3.(.*?).amazonaws.com$`)
@@ -118,6 +124,7 @@ func GetRegionFromURL(endpointURL url.URL) string {
if endpointURL == sentinelURL {
return ""
}
+
if endpointURL.Hostname() == "s3-external-1.amazonaws.com" {
return ""
}
@@ -159,27 +166,53 @@ func GetRegionFromURL(endpointURL url.URL) string {
return parts[1]
}
- parts = amazonS3HostDot.FindStringSubmatch(endpointURL.Hostname())
+ parts = amazonS3HostPrivateLink.FindStringSubmatch(endpointURL.Hostname())
if len(parts) > 1 {
return parts[1]
}
- parts = amazonS3HostPrivateLink.FindStringSubmatch(endpointURL.Hostname())
+ parts = amazonS3HostExpress.FindStringSubmatch(endpointURL.Hostname())
if len(parts) > 1 {
return parts[1]
}
+ parts = amazonS3HostExpressControl.FindStringSubmatch(endpointURL.Hostname())
+ if len(parts) > 1 {
+ return parts[1]
+ }
+
+ parts = amazonS3HostDot.FindStringSubmatch(endpointURL.Hostname())
+ if len(parts) > 1 {
+ if strings.HasPrefix(parts[1], "xpress-") {
+ return ""
+ }
+ if strings.HasPrefix(parts[1], "dualstack.") || strings.HasPrefix(parts[1], "control.") || strings.HasPrefix(parts[1], "website-") {
+ return ""
+ }
+ return parts[1]
+ }
+
return ""
}
// IsAliyunOSSEndpoint - Match if it is exactly Aliyun OSS endpoint.
func IsAliyunOSSEndpoint(endpointURL url.URL) bool {
- return strings.HasSuffix(endpointURL.Host, "aliyuncs.com")
+ return strings.HasSuffix(endpointURL.Hostname(), "aliyuncs.com")
+}
+
+// IsAmazonExpressRegionalEndpoint Match if the endpoint is S3 Express regional endpoint.
+func IsAmazonExpressRegionalEndpoint(endpointURL url.URL) bool {
+ return amazonS3HostExpressControl.MatchString(endpointURL.Hostname())
+}
+
+// IsAmazonExpressZonalEndpoint Match if the endpoint is S3 Express zonal endpoint.
+func IsAmazonExpressZonalEndpoint(endpointURL url.URL) bool {
+ return amazonS3HostExpress.MatchString(endpointURL.Hostname())
}
// IsAmazonEndpoint - Match if it is exactly Amazon S3 endpoint.
func IsAmazonEndpoint(endpointURL url.URL) bool {
- if endpointURL.Host == "s3-external-1.amazonaws.com" || endpointURL.Host == "s3.amazonaws.com" {
+ if endpointURL.Hostname() == "s3-external-1.amazonaws.com" || endpointURL.Hostname() == "s3.amazonaws.com" {
return true
}
return GetRegionFromURL(endpointURL) != ""
@@ -200,7 +233,7 @@ func IsAmazonFIPSGovCloudEndpoint(endpointURL url.URL) bool {
if endpointURL == sentinelURL {
return false
}
- return IsAmazonFIPSEndpoint(endpointURL) && strings.Contains(endpointURL.Host, "us-gov-")
+ return IsAmazonFIPSEndpoint(endpointURL) && strings.Contains(endpointURL.Hostname(), "us-gov-")
}
// IsAmazonFIPSEndpoint - Match if it is exactly Amazon S3 FIPS endpoint.
@@ -209,7 +242,7 @@ func IsAmazonFIPSEndpoint(endpointURL url.URL) bool {
if endpointURL == sentinelURL {
return false
}
- return strings.HasPrefix(endpointURL.Host, "s3-fips") && strings.HasSuffix(endpointURL.Host, ".amazonaws.com")
+ return strings.HasPrefix(endpointURL.Hostname(), "s3-fips") && strings.HasSuffix(endpointURL.Hostname(), ".amazonaws.com")
}
// IsAmazonPrivateLinkEndpoint - Match if it is exactly Amazon S3 PrivateLink interface endpoint
@@ -305,9 +338,10 @@ func EncodePath(pathName string) string {
// 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+$`)
+ 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]$`)
+ validBucketNameS3Express = regexp.MustCompile(`^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]--[a-z0-9]{3,7}-az[1-6]--x-s3$`)
+ ipAddress = regexp.MustCompile(`^(\d+\.){3}\d+$`)
)
// Common checker for both stricter and basic validation.
@@ -344,6 +378,56 @@ func CheckValidBucketName(bucketName string) (err error) {
return checkBucketNameCommon(bucketName, false)
}
+// IsS3ExpressBucket is S3 express bucket?
+func IsS3ExpressBucket(bucketName string) bool {
+ return CheckValidBucketNameS3Express(bucketName) == nil
+}
+
+// CheckValidBucketNameS3Express - checks if we have a valid input bucket name for S3 Express.
+func CheckValidBucketNameS3Express(bucketName string) (err error) {
+ if strings.TrimSpace(bucketName) == "" {
+ return errors.New("Bucket name cannot be empty for S3 Express")
+ }
+
+ if len(bucketName) < 3 {
+ return errors.New("Bucket name cannot be shorter than 3 characters for S3 Express")
+ }
+
+ if len(bucketName) > 63 {
+ return errors.New("Bucket name cannot be longer than 63 characters for S3 Express")
+ }
+
+ // Check if the bucket matches the regex
+ if !validBucketNameS3Express.MatchString(bucketName) {
+ return errors.New("Bucket name contains invalid characters")
+ }
+
+ // Extract bucket name (before --<az-id>--x-s3)
+ parts := strings.Split(bucketName, "--")
+ if len(parts) != 3 || parts[2] != "x-s3" {
+ return errors.New("Bucket name pattern is wrong 'x-s3'")
+ }
+ bucketName = parts[0]
+
+ // Additional validation for bucket name
+ // 1. No consecutive periods or hyphens
+ if strings.Contains(bucketName, "..") || strings.Contains(bucketName, "--") {
+ return errors.New("Bucket name contains invalid characters")
+ }
+
+ // 2. No period-hyphen or hyphen-period
+ if strings.Contains(bucketName, ".-") || strings.Contains(bucketName, "-.") {
+ return errors.New("Bucket name has unexpected format or contains invalid characters")
+ }
+
+ // 3. No IP address format (e.g., 192.168.0.1)
+ if ipAddress.MatchString(bucketName) {
+ return errors.New("Bucket name cannot be an ip address")
+ }
+
+ return nil
+}
+
// CheckValidBucketNameStrict - checks if we have a valid input bucket name.
// This is a stricter version.
// - http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html