mirror of
https://github.com/minio/minio.git
synced 2025-11-07 21:02:58 -05:00
committed by
Nitish Tiwari
parent
52b159b1db
commit
bebaff269c
@@ -149,6 +149,11 @@ func makeAdminPeers(endpoints EndpointList) (adminPeerList adminPeers) {
|
||||
// Use first IPv4 instead of loopback address.
|
||||
localAddr = net.JoinHostPort(sortIPs(localIP4.ToSlice())[0], globalMinioPort)
|
||||
}
|
||||
if strings.HasPrefix(localAddr, "[::1]:") {
|
||||
// Use first IPv4 instead of loopback address.
|
||||
localAddr = net.JoinHostPort(localIP6.ToSlice()[0], globalMinioPort)
|
||||
}
|
||||
|
||||
adminPeerList = append(adminPeerList, adminPeer{
|
||||
addr: localAddr,
|
||||
cmdRunner: localAdminClient{},
|
||||
|
||||
@@ -226,6 +226,17 @@ func TestGetSetIndexes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getHexSequences(start int, number int, paddinglen int) (seq []string) {
|
||||
for i := start; i <= number; i++ {
|
||||
if paddinglen == 0 {
|
||||
seq = append(seq, fmt.Sprintf("%x", i))
|
||||
} else {
|
||||
seq = append(seq, fmt.Sprintf(fmt.Sprintf("%%0%dx", paddinglen), i))
|
||||
}
|
||||
}
|
||||
return seq
|
||||
}
|
||||
|
||||
func getSequences(start int, number int, paddinglen int) (seq []string) {
|
||||
for i := start; i <= number; i++ {
|
||||
if paddinglen == 0 {
|
||||
@@ -472,6 +483,52 @@ func TestParseEndpointSet(t *testing.T) {
|
||||
},
|
||||
true,
|
||||
},
|
||||
// IPv6 ellipses with hexadecimal expansion
|
||||
{
|
||||
"http://[2001:3984:3989::{1...a}]/disk{1...10}",
|
||||
endpointSet{
|
||||
[]ellipses.ArgPattern{
|
||||
[]ellipses.Pattern{
|
||||
{
|
||||
Prefix: "",
|
||||
Suffix: "",
|
||||
Seq: getSequences(1, 10, 0),
|
||||
},
|
||||
{
|
||||
Prefix: "http://[2001:3984:3989::",
|
||||
Suffix: "]/disk",
|
||||
Seq: getHexSequences(1, 10, 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
nil,
|
||||
[][]uint64{{10, 10, 10, 10, 10, 10, 10, 10, 10, 10}},
|
||||
},
|
||||
true,
|
||||
},
|
||||
// IPv6 ellipses with hexadecimal expansion with 3 position numerics.
|
||||
{
|
||||
"http://[2001:3984:3989::{001...00a}]/disk{1...10}",
|
||||
endpointSet{
|
||||
[]ellipses.ArgPattern{
|
||||
[]ellipses.Pattern{
|
||||
{
|
||||
Prefix: "",
|
||||
Suffix: "",
|
||||
Seq: getSequences(1, 10, 0),
|
||||
},
|
||||
{
|
||||
Prefix: "http://[2001:3984:3989::",
|
||||
Suffix: "]/disk",
|
||||
Seq: getHexSequences(1, 10, 3),
|
||||
},
|
||||
},
|
||||
},
|
||||
nil,
|
||||
[][]uint64{{10, 10, 10, 10, 10, 10, 10, 10, 10, 10}},
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
|
||||
@@ -112,6 +112,9 @@ func NewEndpoint(arg string) (ep Endpoint, e error) {
|
||||
return ep, fmt.Errorf("invalid URL endpoint format: port number must be between 1 to 65535")
|
||||
}
|
||||
}
|
||||
if i := strings.Index(host, "%"); i > -1 {
|
||||
host = host[:i]
|
||||
}
|
||||
|
||||
if host == "" {
|
||||
return ep, fmt.Errorf("invalid URL endpoint format: empty host name")
|
||||
@@ -152,7 +155,7 @@ func NewEndpoint(arg string) (ep Endpoint, e error) {
|
||||
// Only check if the arg is an ip address and ask for scheme since its absent.
|
||||
// localhost, example.com, any FQDN cannot be disambiguated from a regular file path such as
|
||||
// /mnt/export1. So we go ahead and start the minio server in FS modes in these cases.
|
||||
if isHostIPv4(arg) {
|
||||
if isHostIP(arg) {
|
||||
return ep, fmt.Errorf("invalid URL endpoint format: missing scheme http or https")
|
||||
}
|
||||
u = &url.URL{Path: path.Clean(arg)}
|
||||
@@ -224,7 +227,6 @@ func NewEndpointList(args ...string) (endpoints EndpointList, err error) {
|
||||
uniqueArgs.Add(arg)
|
||||
endpoints = append(endpoints, endpoint)
|
||||
}
|
||||
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
@@ -341,7 +343,7 @@ func CreateEndpoints(serverAddr string, args ...[]string) (string, EndpointList,
|
||||
if err != nil {
|
||||
host = endpoint.Host
|
||||
}
|
||||
hostIPSet, _ := getHostIP4(host)
|
||||
hostIPSet, _ := getHostIP(host)
|
||||
if IPSet, ok := pathIPMap[endpoint.Path]; ok {
|
||||
if !IPSet.Intersection(hostIPSet).IsEmpty() {
|
||||
return serverAddr, endpoints, setupType,
|
||||
@@ -411,12 +413,12 @@ func CreateEndpoints(serverAddr string, args ...[]string) (string, EndpointList,
|
||||
host = localServerAddr
|
||||
}
|
||||
|
||||
ipList, err := getHostIP4(host)
|
||||
ipList, err := getHostIP(host)
|
||||
logger.FatalIf(err, "unexpected error when resolving host '%s'", host)
|
||||
|
||||
// Filter ipList by IPs those start with '127.'.
|
||||
// Filter ipList by IPs those start with '127.' or '::1'
|
||||
loopBackIPs := ipList.FuncMatch(func(ip string, matchString string) bool {
|
||||
return strings.HasPrefix(ip, "127.")
|
||||
return strings.HasPrefix(ip, "127.") || strings.HasPrefix(ip, "::1")
|
||||
}, "")
|
||||
|
||||
// If loop back IP is found and ipList contains only loop back IPs, then error out.
|
||||
@@ -485,10 +487,10 @@ func GetLocalPeer(endpoints EndpointList) (localPeer string) {
|
||||
// Local peer can be empty in FS or Erasure coded mode.
|
||||
// If so, return globalMinioHost + globalMinioPort value.
|
||||
if globalMinioHost != "" {
|
||||
return globalMinioHost + ":" + globalMinioPort
|
||||
return net.JoinHostPort(globalMinioHost, globalMinioPort)
|
||||
}
|
||||
|
||||
return "127.0.0.1:" + globalMinioPort
|
||||
return net.JoinHostPort("127.0.0.1", globalMinioPort)
|
||||
}
|
||||
return peerSet.ToSlice()[0]
|
||||
}
|
||||
@@ -525,10 +527,10 @@ func updateDomainIPs(endPoints set.StringSet) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
IPs, _ := getHostIP4(host)
|
||||
IPs, _ := getHostIP(host)
|
||||
ipList = ipList.Union(IPs)
|
||||
}
|
||||
globalDomainIPs = ipList.FuncMatch(func(ip string, matchString string) bool {
|
||||
return !strings.HasPrefix(ip, "127.")
|
||||
return !strings.HasPrefix(ip, "127.") || strings.HasPrefix(ip, "::1")
|
||||
}, "")
|
||||
}
|
||||
|
||||
@@ -304,27 +304,27 @@ func TestCreateEndpoints(t *testing.T) {
|
||||
}, DistXLSetupType, nil},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
for i, testCase := range testCases {
|
||||
serverAddr, endpoints, setupType, err := CreateEndpoints(testCase.serverAddr, testCase.args...)
|
||||
|
||||
if err == nil {
|
||||
if testCase.expectedErr != nil {
|
||||
t.Fatalf("error: expected = %v, got = <nil>", testCase.expectedErr)
|
||||
t.Fatalf("Test (%d) error: expected = %v, got = <nil>", i+1, testCase.expectedErr)
|
||||
} else {
|
||||
if serverAddr != testCase.expectedServerAddr {
|
||||
t.Fatalf("serverAddr: expected = %v, got = %v", testCase.expectedServerAddr, serverAddr)
|
||||
t.Fatalf("Test (%d) serverAddr: expected = %v, got = %v", i+1, testCase.expectedServerAddr, serverAddr)
|
||||
}
|
||||
if !reflect.DeepEqual(endpoints, testCase.expectedEndpoints) {
|
||||
t.Fatalf("endpoints: expected = %v, got = %v", testCase.expectedEndpoints, endpoints)
|
||||
t.Fatalf("Test (%d) endpoints: expected = %v, got = %v", i+1, testCase.expectedEndpoints, endpoints)
|
||||
}
|
||||
if setupType != testCase.expectedSetupType {
|
||||
t.Fatalf("setupType: expected = %v, got = %v", testCase.expectedSetupType, setupType)
|
||||
t.Fatalf("Test (%d) setupType: expected = %v, got = %v", i+1, testCase.expectedSetupType, setupType)
|
||||
}
|
||||
}
|
||||
} else if testCase.expectedErr == nil {
|
||||
t.Fatalf("error: expected = <nil>, got = %v", err)
|
||||
t.Fatalf("Test (%d) error: expected = <nil>, got = %v", i+1, err)
|
||||
} else if err.Error() != testCase.expectedErr.Error() {
|
||||
t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err)
|
||||
t.Fatalf("Test (%d) error: expected = %v, got = %v", i+1, testCase.expectedErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package cmd
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
@@ -135,11 +134,7 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
|
||||
handleCommonCmdArgs(ctx)
|
||||
|
||||
// Get port to listen on from gateway address
|
||||
var pErr error
|
||||
_, globalMinioPort, pErr = net.SplitHostPort(gatewayAddr)
|
||||
if pErr != nil {
|
||||
logger.FatalIf(pErr, "Unable to start gateway")
|
||||
}
|
||||
globalMinioHost, globalMinioPort = mustSplitHostPort(gatewayAddr)
|
||||
|
||||
// On macOS, if a process already listens on LOCALIPADDR:PORT, net.Listen() falls back
|
||||
// to IPv6 address ie minio will start listening on IPv6 address whereas another
|
||||
@@ -301,7 +296,7 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
|
||||
}
|
||||
|
||||
// Print gateway startup message.
|
||||
printGatewayStartupMessage(getAPIEndpoints(gatewayAddr), gatewayName)
|
||||
printGatewayStartupMessage(getAPIEndpoints(), gatewayName)
|
||||
}
|
||||
|
||||
handleSignals()
|
||||
|
||||
@@ -399,8 +399,8 @@ func newHTTPListener(serverAddrs []string,
|
||||
|
||||
for _, serverAddr := range serverAddrs {
|
||||
var l net.Listener
|
||||
if l, err = listen("tcp4", serverAddr); err != nil {
|
||||
if l, err = fallbackListen("tcp4", serverAddr); err != nil {
|
||||
if l, err = listen("tcp", serverAddr); err != nil {
|
||||
if l, err = fallbackListen("tcp", serverAddr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
77
cmd/net.go
77
cmd/net.go
@@ -37,14 +37,21 @@ import (
|
||||
// IPv4 addresses of local host.
|
||||
var localIP4 = mustGetLocalIP4()
|
||||
|
||||
// IPv6 address of local host.
|
||||
var localIP6 = mustGetLocalIP6()
|
||||
|
||||
// mustSplitHostPort is a wrapper to net.SplitHostPort() where error is assumed to be a fatal.
|
||||
func mustSplitHostPort(hostPort string) (host, port string) {
|
||||
host, port, err := net.SplitHostPort(hostPort)
|
||||
// Strip off IPv6 zone information.
|
||||
if i := strings.Index(host, "%"); i > -1 {
|
||||
host = host[:i]
|
||||
}
|
||||
logger.FatalIf(err, "Unable to split host port %s", hostPort)
|
||||
return host, port
|
||||
}
|
||||
|
||||
// mustGetLocalIP4 returns IPv4 addresses of local host. It panics on error.
|
||||
// mustGetLocalIP4 returns IPv4 addresses of localhost. It panics on error.
|
||||
func mustGetLocalIP4() (ipList set.StringSet) {
|
||||
ipList = set.NewStringSet()
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
@@ -67,8 +74,31 @@ func mustGetLocalIP4() (ipList set.StringSet) {
|
||||
return ipList
|
||||
}
|
||||
|
||||
// getHostIP4 returns IPv4 address of given host.
|
||||
func getHostIP4(host string) (ipList set.StringSet, err error) {
|
||||
// mustGetLocalIP6 returns IPv6 addresses of localhost. It panics on error.
|
||||
func mustGetLocalIP6() (ipList set.StringSet) {
|
||||
ipList = set.NewStringSet()
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
logger.FatalIf(err, "Unable to get IP addresses of this host")
|
||||
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
}
|
||||
|
||||
if ip.To16() != nil {
|
||||
ipList.Add(ip.String())
|
||||
}
|
||||
}
|
||||
|
||||
return ipList
|
||||
}
|
||||
|
||||
// getHostIP returns IP address of given host.
|
||||
func getHostIP(host string) (ipList set.StringSet, err error) {
|
||||
var ips []net.IP
|
||||
|
||||
if ips, err = net.LookupIP(host); err != nil {
|
||||
@@ -110,9 +140,7 @@ func getHostIP4(host string) (ipList set.StringSet, err error) {
|
||||
|
||||
ipList = set.NewStringSet()
|
||||
for _, ip := range ips {
|
||||
if ip.To4() != nil {
|
||||
ipList.Add(ip.String())
|
||||
}
|
||||
ipList.Add(ip.String())
|
||||
}
|
||||
|
||||
return ipList, err
|
||||
@@ -169,29 +197,32 @@ func sortIPs(ipList []string) []string {
|
||||
return append(nonIPs, ips...)
|
||||
}
|
||||
|
||||
func getAPIEndpoints(serverAddr string) (apiEndpoints []string) {
|
||||
host, port := mustSplitHostPort(serverAddr)
|
||||
|
||||
func getAPIEndpoints() (apiEndpoints []string) {
|
||||
var ipList []string
|
||||
if host == "" {
|
||||
if globalMinioHost == "" {
|
||||
ipList = sortIPs(localIP4.ToSlice())
|
||||
ipList = append(ipList, localIP6.ToSlice()...)
|
||||
} else {
|
||||
ipList = []string{host}
|
||||
ipList = []string{globalMinioHost}
|
||||
}
|
||||
|
||||
for _, ip := range ipList {
|
||||
apiEndpoints = append(apiEndpoints, fmt.Sprintf("%s://%s:%s", getURLScheme(globalIsSSL), ip, port))
|
||||
apiEndpoints = append(apiEndpoints, fmt.Sprintf("%s://%s", getURLScheme(globalIsSSL), net.JoinHostPort(ip, globalMinioPort)))
|
||||
}
|
||||
|
||||
return apiEndpoints
|
||||
}
|
||||
|
||||
// isHostIPv4 - helper for validating if the provided arg is an ip address.
|
||||
func isHostIPv4(ipAddress string) bool {
|
||||
// isHostIP - helper for validating if the provided arg is an ip address.
|
||||
func isHostIP(ipAddress string) bool {
|
||||
host, _, err := net.SplitHostPort(ipAddress)
|
||||
if err != nil {
|
||||
host = ipAddress
|
||||
}
|
||||
// Strip off IPv6 zone information.
|
||||
if i := strings.Index(host, "%"); i > -1 {
|
||||
host = host[:i]
|
||||
}
|
||||
return net.ParseIP(host) != nil
|
||||
}
|
||||
|
||||
@@ -291,19 +322,20 @@ func extractHostPort(hostAddr string) (string, string, error) {
|
||||
// correspond to one of the local IP of the
|
||||
// current machine
|
||||
func isLocalHost(host string) (bool, error) {
|
||||
hostIPs, err := getHostIP4(host)
|
||||
hostIPs, err := getHostIP(host)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// If intersection of two IP sets is not empty, then the host is local host.
|
||||
isLocal := !localIP4.Intersection(hostIPs).IsEmpty()
|
||||
return isLocal, nil
|
||||
// If intersection of two IP sets is not empty, then the host is localhost.
|
||||
isLocalv4 := !localIP4.Intersection(hostIPs).IsEmpty()
|
||||
isLocalv6 := !localIP6.Intersection(hostIPs).IsEmpty()
|
||||
return isLocalv4 || isLocalv6, nil
|
||||
}
|
||||
|
||||
// sameLocalAddrs - returns true if two addresses, even with different
|
||||
// formats, point to the same machine, e.g:
|
||||
// ':9000' and 'http://localhost:9000/' will return true
|
||||
// ':9000' and 'http://localhost:9000/' will return true
|
||||
func sameLocalAddrs(addr1, addr2 string) (bool, error) {
|
||||
|
||||
// Extract host & port from given parameters
|
||||
@@ -355,6 +387,11 @@ func CheckLocalServerAddr(serverAddr string) error {
|
||||
return uiErrInvalidAddressFlag(err)
|
||||
}
|
||||
|
||||
// Strip off IPv6 zone information.
|
||||
if i := strings.Index(host, "%"); i > -1 {
|
||||
host = host[:i]
|
||||
}
|
||||
|
||||
// Check whether port is a valid port number.
|
||||
p, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
@@ -366,7 +403,7 @@ func CheckLocalServerAddr(serverAddr string) error {
|
||||
// 0.0.0.0 is a wildcard address and refers to local network
|
||||
// addresses. I.e, 0.0.0.0:9000 like ":9000" refers to port
|
||||
// 9000 on localhost.
|
||||
if host != "" && host != net.IPv4zero.String() {
|
||||
if host != "" && host != net.IPv4zero.String() && host != net.IPv6zero.String() {
|
||||
isLocalHost, err := isLocalHost(host)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -138,7 +138,7 @@ func TestGetHostIP(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
ipList, err := getHostIP4(testCase.host)
|
||||
ipList, err := getHostIP(testCase.host)
|
||||
if testCase.expectedErr == nil {
|
||||
if err != nil {
|
||||
t.Fatalf("error: expected = <nil>, got = %v", err)
|
||||
@@ -157,17 +157,22 @@ func TestGetHostIP(t *testing.T) {
|
||||
|
||||
// Tests finalize api endpoints.
|
||||
func TestGetAPIEndpoints(t *testing.T) {
|
||||
host, port := globalMinioHost, globalMinioAddr
|
||||
defer func() {
|
||||
globalMinioHost, globalMinioAddr = host, port
|
||||
}()
|
||||
testCases := []struct {
|
||||
serverAddr string
|
||||
host, port string
|
||||
expectedResult string
|
||||
}{
|
||||
{":80", "http://127.0.0.1:80"},
|
||||
{"127.0.0.1:80", "http://127.0.0.1:80"},
|
||||
{"localhost:80", "http://localhost:80"},
|
||||
{"", "80", "http://127.0.0.1:80"},
|
||||
{"127.0.0.1", "80", "http://127.0.0.1:80"},
|
||||
{"localhost", "80", "http://localhost:80"},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
apiEndpoints := getAPIEndpoints(testCase.serverAddr)
|
||||
globalMinioHost, globalMinioPort = testCase.host, testCase.port
|
||||
apiEndpoints := getAPIEndpoints()
|
||||
apiEndpointSet := set.CreateStringSet(apiEndpoints...)
|
||||
if !apiEndpointSet.Contains(testCase.expectedResult) {
|
||||
t.Fatalf("test %d: expected: Found, got: Not Found", i+1)
|
||||
@@ -330,7 +335,7 @@ func TestSameLocalAddrs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestIsHostIPv4(t *testing.T) {
|
||||
func TestIsHostIP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
args string
|
||||
expectedResult bool
|
||||
@@ -341,10 +346,11 @@ func TestIsHostIPv4(t *testing.T) {
|
||||
{"http://192.168.1.0", false},
|
||||
{"http://192.168.1.0:9000", false},
|
||||
{"192.168.1.0", true},
|
||||
{"[2001:3984:3989::20%eth0]:9000", true},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
ret := isHostIPv4(testCase.args)
|
||||
ret := isHostIP(testCase.args)
|
||||
if testCase.expectedResult != ret {
|
||||
t.Fatalf("expected: %v , got: %v", testCase.expectedResult, ret)
|
||||
}
|
||||
|
||||
@@ -389,8 +389,7 @@ func serverMain(ctx *cli.Context) {
|
||||
globalObjLayerMutex.Unlock()
|
||||
|
||||
// Prints the formatted startup message once object layer is initialized.
|
||||
apiEndpoints := getAPIEndpoints(globalMinioAddr)
|
||||
printStartupMessage(apiEndpoints)
|
||||
printStartupMessage(getAPIEndpoints())
|
||||
|
||||
// Set uptime time after object layer has initialized.
|
||||
globalBootTime = UTCNow()
|
||||
|
||||
@@ -20,12 +20,12 @@ import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
humanize "github.com/dustin/go-humanize"
|
||||
"github.com/minio/minio/cmd/logger"
|
||||
xnet "github.com/minio/minio/pkg/net"
|
||||
)
|
||||
|
||||
// Documentation links, these are part of message printing code.
|
||||
@@ -83,23 +83,12 @@ func stripStandardPorts(apiEndpoints []string) (newAPIEndpoints []string) {
|
||||
newAPIEndpoints = make([]string, len(apiEndpoints))
|
||||
// Check all API endpoints for standard ports and strip them.
|
||||
for i, apiEndpoint := range apiEndpoints {
|
||||
url, err := url.Parse(apiEndpoint)
|
||||
url, err := xnet.ParseURL(apiEndpoint)
|
||||
if err != nil {
|
||||
newAPIEndpoints[i] = apiEndpoint
|
||||
continue
|
||||
}
|
||||
host, port := mustSplitHostPort(url.Host)
|
||||
// For standard HTTP(s) ports such as "80" and "443"
|
||||
// apiEndpoints should only be host without port.
|
||||
switch {
|
||||
case url.Scheme == "http" && port == "80":
|
||||
fallthrough
|
||||
case url.Scheme == "https" && port == "443":
|
||||
url.Host = host
|
||||
newAPIEndpoints[i] = url.String()
|
||||
default:
|
||||
newAPIEndpoints[i] = apiEndpoint
|
||||
}
|
||||
newAPIEndpoints[i] = url.String()
|
||||
}
|
||||
return newAPIEndpoints
|
||||
}
|
||||
|
||||
@@ -2319,7 +2319,7 @@ func getEndpointsLocalAddr(endpoints EndpointList) string {
|
||||
}
|
||||
}
|
||||
|
||||
return globalMinioHost + ":" + globalMinioPort
|
||||
return net.JoinHostPort(globalMinioHost, globalMinioPort)
|
||||
}
|
||||
|
||||
// fetches a random number between range min-max.
|
||||
|
||||
Reference in New Issue
Block a user