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

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package url
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"net"
    11  )
    12  
    13  // ParseHostPort takes the user input target string, returns formatted host and port info.
    14  // If target doesn't specify a port, set the port to be the defaultPort.
    15  // If target is in IPv6 format and host-name is enclosed in sqarue brackets, brackets
    16  // are strippd when setting the host.
    17  // examples:
    18  // target: "www.google.com" returns host: "www.google.com", port: "443"
    19  // target: "ipv4-host:80" returns host: "ipv4-host", port: "80"
    20  // target: "[ipv6-host]" returns host: "ipv6-host", port: "443"
    21  // target: ":80" returns host: "localhost", port: "80"
    22  // target: ":" returns host: "localhost", port: "443"
    23  func ParseHostPort(scheme string, hostport string, getDefaultPort func(schema string) (string, error)) (host, port string, err error) {
    24  	if hostport == "" {
    25  		return "", "", errors.New("missing hostport")
    26  	}
    27  	if getDefaultPort == nil {
    28  		return "", "", errors.New("missing getDefaultPort")
    29  	}
    30  
    31  	// justIP, no port follow
    32  	if ip := net.ParseIP(hostport); ip != nil {
    33  		// hostport is an IPv4 or IPv6(without brackets) address
    34  		port, err := getDefaultPort(scheme)
    35  		if err != nil {
    36  			return "", "", err
    37  		}
    38  		return hostport, port, nil
    39  	}
    40  
    41  	if host, port, err = net.SplitHostPort(hostport); err == nil {
    42  		// hostport has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port
    43  		if host == "" {
    44  			// Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed.
    45  			host = "localhost"
    46  		}
    47  		if port == "" {
    48  			// If the port field is empty(hostport ends with colon), e.g. "[::1]:", defaultPort is used.
    49  			port, err = getDefaultPort(scheme)
    50  			if err != nil {
    51  				return "", "", err
    52  			}
    53  		}
    54  		return host, port, nil
    55  	}
    56  	// missing port
    57  	defaultPort, err := getDefaultPort(scheme)
    58  	if err != nil {
    59  		return "", "", err
    60  	}
    61  	if host, port, err = net.SplitHostPort(hostport + ":" + defaultPort); err == nil {
    62  		// hostport doesn't have port
    63  		return host, port, nil
    64  	}
    65  	return "", "", fmt.Errorf("invalid hostport address %v", hostport)
    66  }