github.com/searKing/golang/go@v1.2.117/net/hostport.go (about)

     1  package net
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  )
     7  
     8  // HostportOrDefault takes the user input target string and default port, returns formatted host and port info.
     9  // If target doesn't specify a port, set the port to be the defaultPort.
    10  // If target is in IPv6 format and host-name is enclosed in square brackets, brackets
    11  // are stripped when setting the host.
    12  // examples:
    13  // target: "www.google.com" defaultPort: "443" returns host: "www.google.com", port: "443"
    14  // target: "ipv4-host:80" defaultPort: "443" returns host: "ipv4-host", port: "80"
    15  // target: "[ipv6-host]" defaultPort: "443" returns host: "ipv6-host", port: "443"
    16  // target: ":80" defaultPort: "443" returns host: "localhost", port: "80"
    17  func HostportOrDefault(hostport string, defHostport string) string {
    18  	host, port, _ := SplitHostPort(hostport)
    19  	defHost, defPort, _ := SplitHostPort(defHostport)
    20  	if host == "" {
    21  		host = defHost
    22  	}
    23  	if port == "" {
    24  		port = defPort
    25  	}
    26  	return net.JoinHostPort(host, port)
    27  }
    28  
    29  // SplitHostPort splits a network address of the form "host:port",
    30  // "host%zone:port", "[host]:port" or "[host%zone]:port" into host or
    31  // host%zone and port.
    32  // Different to net.SplitHostPort, host or port can be not set
    33  //
    34  // A literal IPv6 address in hostport must be enclosed in square
    35  // brackets, as in "[::1]:80", "[::1%lo0]:80".
    36  //
    37  // See func Dial for a description of the hostport parameter, and host
    38  // and port results.
    39  func SplitHostPort(hostport string) (host, port string, err error) {
    40  	host, portStr, err := net.SplitHostPort(hostport)
    41  	if err != nil {
    42  		// If adding a port makes it valid, the previous error
    43  		// was not due to an invalid address and we can append a port.
    44  		host, _, err := net.SplitHostPort(hostport + ":1234")
    45  		return host, "", err
    46  	}
    47  	return host, portStr, err
    48  }
    49  
    50  // RandomPort returns a random port by a temporary listen on :0
    51  func RandomPort(host string) (int, error) {
    52  	if host == "" {
    53  		host = "localhost"
    54  	}
    55  	ln, err := net.Listen("tcp", net.JoinHostPort(host, "0"))
    56  	if err != nil {
    57  		return 0, fmt.Errorf("could not generate random port: %w", err)
    58  	}
    59  	port := ln.Addr().(*net.TCPAddr).Port
    60  	err = ln.Close()
    61  	if err != nil {
    62  		return 0, fmt.Errorf("could not generate random port: %w", err)
    63  	}
    64  	return port, nil
    65  
    66  }