go-micro.dev/v5@v5.12.0/util/net/net.go (about) 1 package net 2 3 import ( 4 "errors" 5 "fmt" 6 "net" 7 "os" 8 "strconv" 9 "strings" 10 ) 11 12 // HostPort format addr and port suitable for dial. 13 func HostPort(addr string, port interface{}) string { 14 host := addr 15 if strings.Count(addr, ":") > 0 { 16 host = fmt.Sprintf("[%s]", addr) 17 } 18 // when port is blank or 0, host is a queue name 19 if v, ok := port.(string); ok && v == "" { 20 return host 21 } else if v, ok := port.(int); ok && v == 0 && net.ParseIP(host) == nil { 22 return host 23 } 24 25 return fmt.Sprintf("%s:%v", host, port) 26 } 27 28 // Listen takes addr:portmin-portmax and binds to the first available port 29 // Example: Listen("localhost:5000-6000", fn). 30 func Listen(addr string, fn func(string) (net.Listener, error)) (net.Listener, error) { 31 if strings.Count(addr, ":") == 1 && strings.Count(addr, "-") == 0 { 32 return fn(addr) 33 } 34 35 // host:port || host:min-max 36 host, ports, err := net.SplitHostPort(addr) 37 if err != nil { 38 return nil, err 39 } 40 41 // try to extract port range 42 prange := strings.Split(ports, "-") 43 44 // single port 45 if len(prange) < 2 { 46 return fn(addr) 47 } 48 49 // we have a port range 50 51 // extract min port 52 min, err := strconv.Atoi(prange[0]) 53 if err != nil { 54 return nil, errors.New("unable to extract port range") 55 } 56 57 // extract max port 58 max, err := strconv.Atoi(prange[1]) 59 if err != nil { 60 return nil, errors.New("unable to extract port range") 61 } 62 63 // range the ports 64 for port := min; port <= max; port++ { 65 // try bind to host:port 66 ln, err := fn(HostPort(host, port)) 67 if err == nil { 68 return ln, nil 69 } 70 71 // hit max port 72 if port == max { 73 return nil, err 74 } 75 } 76 77 // why are we here? 78 return nil, fmt.Errorf("unable to bind to %s", addr) 79 } 80 81 // Proxy returns the proxy and the address if it exits. 82 func Proxy(service string, address []string) (string, []string, bool) { 83 var hasProxy bool 84 85 // get proxy. we parse out address if present 86 if prx := os.Getenv("MICRO_PROXY"); len(prx) > 0 { 87 // default name 88 if prx == "service" { 89 prx = "go.micro.proxy" 90 address = nil 91 } 92 93 // check if its an address 94 if v := strings.Split(prx, ":"); len(v) > 1 { 95 address = []string{prx} 96 } 97 98 service = prx 99 hasProxy = true 100 101 return service, address, hasProxy 102 } 103 104 if prx := os.Getenv("MICRO_NETWORK"); len(prx) > 0 { 105 // default name 106 if prx == "service" { 107 prx = "go.micro.network" 108 } 109 service = prx 110 hasProxy = true 111 } 112 113 if prx := os.Getenv("MICRO_NETWORK_ADDRESS"); len(prx) > 0 { 114 address = []string{prx} 115 hasProxy = true 116 } 117 118 return service, address, hasProxy 119 }