From 1fb6aab3d4ee9a63c87dc17f6cec206be9e8f68e Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Mon, 11 Apr 2022 15:06:33 +0100 Subject: [PATCH] More fixes in ipv6 parsing in get bucket location Also fix the endpoint validation. The code was assuming that any address has ':' in it means it has a port but this is not true. --- bucket-cache.go | 3 +++ utils.go | 30 +++++++++++++++--------------- utils_test.go | 2 +- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/bucket-cache.go b/bucket-cache.go index 19dabd25b7..b7d99c6931 100644 --- a/bucket-cache.go +++ b/bucket-cache.go @@ -181,6 +181,9 @@ func (c *Client) getBucketLocationRequest(ctx context.Context, bucketName string if h, p, err := net.SplitHostPort(targetURL.Host); err == nil { if targetURL.Scheme == "http" && p == "80" || targetURL.Scheme == "https" && p == "443" { targetURL.Host = h + if ip := net.ParseIP(h); ip != nil && ip.To16() != nil { + targetURL.Host = "[" + h + "]" + } } } diff --git a/utils.go b/utils.go index 172a04c74d..efe974d0b2 100644 --- a/utils.go +++ b/utils.go @@ -105,21 +105,6 @@ func sumMD5Base64(data []byte) string { // getEndpointURL - construct a new endpoint. func getEndpointURL(endpoint string, secure bool) (*url.URL, error) { - if strings.Contains(endpoint, ":") { - host, _, err := net.SplitHostPort(endpoint) - if err != nil { - return nil, err - } - if !s3utils.IsValidIP(host) && !s3utils.IsValidDomain(host) { - msg := "Endpoint: " + endpoint + " does not follow ip address or domain name standards." - return nil, errInvalidArgument(msg) - } - } else { - if !s3utils.IsValidIP(endpoint) && !s3utils.IsValidDomain(endpoint) { - msg := "Endpoint: " + endpoint + " does not follow ip address or domain name standards." - return nil, errInvalidArgument(msg) - } - } // If secure is false, use 'http' scheme. scheme := "https" if !secure { @@ -176,6 +161,21 @@ func isValidEndpointURL(endpointURL url.URL) error { if endpointURL.Path != "/" && endpointURL.Path != "" { return errInvalidArgument("Endpoint url cannot have fully qualified paths.") } + + host, _, err := net.SplitHostPort(endpointURL.Host) + if err != nil { + if strings.Contains(err.Error(), "missing port in address") { + err = nil + host = endpointURL.Host + } else { + return err + } + } + if !s3utils.IsValidIP(host) && !s3utils.IsValidDomain(host) { + msg := "Endpoint: " + endpointURL.Host + " does not follow ip address or domain name standards." + return errInvalidArgument(msg) + } + if strings.Contains(endpointURL.Host, ".s3.amazonaws.com") { if !s3utils.IsAmazonEndpoint(endpointURL) { return errInvalidArgument("Amazon S3 endpoint should be 's3.amazonaws.com'.") diff --git a/utils_test.go b/utils_test.go index 9e4da53d31..1d4409205e 100644 --- a/utils_test.go +++ b/utils_test.go @@ -153,7 +153,6 @@ func TestIsValidEndpointURL(t *testing.T) { shouldPass bool }{ {"", errInvalidArgument("Endpoint url cannot be empty."), false}, - {"/", nil, true}, {"https://s3.amazonaws.com", nil, true}, {"https://s3.cn-north-1.amazonaws.com.cn", nil, true}, {"https://s3-us-gov-west-1.amazonaws.com", nil, true}, @@ -167,6 +166,7 @@ func TestIsValidEndpointURL(t *testing.T) { {"https://amazon.googleapis.com/", errInvalidArgument("Google Cloud Storage endpoint should be 'storage.googleapis.com'."), false}, {"https://storage.googleapis.com/bucket/", errInvalidArgument("Endpoint url cannot have fully qualified paths."), false}, {"https://s3.amazonaws.com/bucket/object", errInvalidArgument("Endpoint url cannot have fully qualified paths."), false}, + {"https://.s3server.example.com/", errInvalidArgument("Endpoint: .s3server.example.com does not follow ip address or domain name standards."), false}, } for i, testCase := range testCases {