func prefixScheme(rawURL string, defaultScheme string) string {
	if strings.HasPrefix(rawURL, "//") {
		if defaultScheme != "" {
			rawURL = defaultScheme + ":" + rawURL
		}
	} else if strings.Index(rawURL, "://") < 0 {
		rawURL = "//" + rawURL
		if defaultScheme != "" {
			rawURL = defaultScheme + ":" + rawURL
		}
	}
	return rawURL
}
/*
Prefix the given rawURL string with a scheme.
If a defaultScheme is provided, and no scheme exists for rawURL, it will be used.
For example:
("test:8080", "https") -> "https://test:8080"
("https://8080", "gopher") -> "https://test:8080"
("test:8080", "") -> "//test:8080"
Params:
rawURL: The raw URL as a string which may or may not have a scheme.
defaultScheme: Optional. The scheme to inject if no scheme is present in rawURL.
Returns:
Returns the given rawURL with a scheme.
package proxy
import (
	"errors"
	"fmt"
	"net"
	"net/url"
	"strconv"
	"strings"
)
const maxUint16 = (1 << 16) - 1
func ParseURL(rawUrl string, defaultScheme string) (*url.URL, error) {
	rawUrl = prefixScheme(strings.TrimSpace(rawUrl), defaultScheme)
	return url.Parse(rawUrl)
}
func ParseTargetURL(targetUrl, defaultScheme string) *url.URL {
	parsedUrl, err := ParseURL(targetUrl, defaultScheme)
	if err != nil {
		return &url.URL{Host: targetUrlWildcard}
	}
	if parsedUrl.Host == "" {
		parsedUrl.Host = targetUrlWildcard
	}
	parsedUrl.User = nil
	parsedUrl.Fragment = ""
	parsedUrl.RawQuery = ""
	parsedUrl.ForceQuery = false
	parsedUrl.Opaque = ""
	parsedUrl.Path = ""
	parsedUrl.RawPath = ""
	return parsedUrl
}
func SplitHostPort(u *url.URL) (host string, port uint16, err error) {
	if u == nil {
		return "", 0, newSplitHostPortError("nil", errors.New("nil URL"))
	}
	host = strings.TrimSpace(u.Host)
	portStr := ""
	i := strings.LastIndex(host, ":")
	if i >= 0 {
		if len(host) > i && strings.Index(host[i:], "]") < 0 {
			portStr = host[i+1:]
			host = host[:i]
		}
	}
	if portStr != "" {
		port64, err := strconv.ParseUint(portStr, 10, 16)
		if err != nil {
			return "", 0, newSplitHostPortError(u.Host, err)
		} else if port64 > maxUint16 {
			return "", 0, newSplitHostPortError(u.Host, errors.New(fmt.Sprintf("%d > %d", port64, maxUint16)))
		}
		port = uint16(port64)
	}
	return host, port, nil
}
func IsLoopbackHost(host string) bool {
	host = strings.TrimSpace(host)
	if host == "localhost" {
		return true
	}
	if len(host) >= 2 && host[0] == '[' && host[len(host)-1] == ']' {
		host = host[1 : len(host)-1]
	}
	if ip := net.ParseIP(host); ip != nil && ip.IsLoopback() {
		return true
	}
	return false
}