package url import ( "net" "net/url" "regexp" ) var reScheme = regexp.MustCompile(`(?i)^([a-z][a-z0-9.+-:]*)://`) // Validate checks whether the given address is a valid URL func Validate(address string) error { _, err := Parse(address) return err } // Parse parses an URL into its components. Returns a net/url.URL or // an error if the URL couldn't be parsed. func Parse(address string) (*url.URL, error) { address = reScheme.ReplaceAllString(address, "//") u, err := url.Parse(address) return u, err } // HasScheme returns whether the address has an URL scheme prefix func HasScheme(address string) bool { if ok := reScheme.MatchString(address); ok { return true } return false } // Lookup returns the first resolved IP address of the host in the address. // If the address doesn't have an URL scheme prefix, an empty string and no // error is returned. If the address is an URL and the lookup fails, an // error is returned. func Lookup(address string) (string, error) { if !HasScheme(address) { return "", nil } u, err := Parse(address) if err != nil { return "", err } if len(u.Host) == 0 { return "", nil } host, _, err := net.SplitHostPort(u.Host) if err != nil { host = u.Host } addrs, err := net.LookupHost(host) if err != nil { return "", err } return addrs[0], nil }