github.com/minio/madmin-go/v3@v3.0.51/utils.go (about) 1 // 2 // Copyright (c) 2015-2022 MinIO, Inc. 3 // 4 // This file is part of MinIO Object Storage stack 5 // 6 // This program is free software: you can redistribute it and/or modify 7 // it under the terms of the GNU Affero General Public License as 8 // published by the Free Software Foundation, either version 3 of the 9 // License, or (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU Affero General Public License for more details. 15 // 16 // You should have received a copy of the GNU Affero General Public License 17 // along with this program. If not, see <http://www.gnu.org/licenses/>. 18 // 19 20 package madmin 21 22 import ( 23 "io" 24 "net" 25 "net/http" 26 "net/url" 27 "strings" 28 29 "github.com/minio/minio-go/v7/pkg/s3utils" 30 ) 31 32 // AdminAPIVersion - admin api version used in the request. 33 const ( 34 AdminAPIVersion = "v3" 35 AdminAPIVersionV2 = "v2" 36 adminAPIPrefix = "/" + AdminAPIVersion 37 kmsAPIVersion = "v1" 38 kmsAPIPrefix = "/" + kmsAPIVersion 39 ) 40 41 // getEndpointURL - construct a new endpoint. 42 func getEndpointURL(endpoint string, secure bool) (*url.URL, error) { 43 if strings.Contains(endpoint, ":") { 44 host, _, err := net.SplitHostPort(endpoint) 45 if err != nil { 46 return nil, err 47 } 48 if !s3utils.IsValidIP(host) && !s3utils.IsValidDomain(host) { 49 msg := "Endpoint: " + endpoint + " does not follow ip address or domain name standards." 50 return nil, ErrInvalidArgument(msg) 51 } 52 } else { 53 if !s3utils.IsValidIP(endpoint) && !s3utils.IsValidDomain(endpoint) { 54 msg := "Endpoint: " + endpoint + " does not follow ip address or domain name standards." 55 return nil, ErrInvalidArgument(msg) 56 } 57 } 58 59 // If secure is false, use 'http' scheme. 60 scheme := "https" 61 if !secure { 62 scheme = "http" 63 } 64 65 // Strip the obvious :443 and :80 from the endpoint 66 // to avoid the signature mismatch error. 67 if secure && strings.HasSuffix(endpoint, ":443") { 68 endpoint = strings.TrimSuffix(endpoint, ":443") 69 } 70 if !secure && strings.HasSuffix(endpoint, ":80") { 71 endpoint = strings.TrimSuffix(endpoint, ":80") 72 } 73 74 // Construct a secured endpoint URL. 75 endpointURLStr := scheme + "://" + endpoint 76 endpointURL, err := url.Parse(endpointURLStr) 77 if err != nil { 78 return nil, err 79 } 80 81 // Validate incoming endpoint URL. 82 if err := isValidEndpointURL(endpointURL.String()); err != nil { 83 return nil, err 84 } 85 return endpointURL, nil 86 } 87 88 // Verify if input endpoint URL is valid. 89 func isValidEndpointURL(endpointURL string) error { 90 if endpointURL == "" { 91 return ErrInvalidArgument("Endpoint url cannot be empty.") 92 } 93 url, err := url.Parse(endpointURL) 94 if err != nil { 95 return ErrInvalidArgument("Endpoint url cannot be parsed.") 96 } 97 if url.Path != "/" && url.Path != "" { 98 return ErrInvalidArgument("Endpoint url cannot have fully qualified paths.") 99 } 100 return nil 101 } 102 103 // closeResponse close non nil response with any response Body. 104 // convenient wrapper to drain any remaining data on response body. 105 // 106 // Subsequently this allows golang http RoundTripper 107 // to re-use the same connection for future requests. 108 func closeResponse(resp *http.Response) { 109 // Callers should close resp.Body when done reading from it. 110 // If resp.Body is not closed, the Client's underlying RoundTripper 111 // (typically Transport) may not be able to re-use a persistent TCP 112 // connection to the server for a subsequent "keep-alive" request. 113 if resp != nil && resp.Body != nil { 114 // Drain any remaining Body and then close the connection. 115 // Without this closing connection would disallow re-using 116 // the same connection for future uses. 117 // - http://stackoverflow.com/a/17961593/4465767 118 io.Copy(io.Discard, resp.Body) 119 resp.Body.Close() 120 } 121 }