Is there any function in a standard package in GO that allows to validate a URL?
I have not found anything on my initial search, and I would prefer not to resort to regex checking.
Yep, url.ParseRequestURI returns an error if the URL is not valid, not an absolute url, etc etc. url.Parse returns valid on almost anything...
import "net/url"
...
u, err := url.ParseRequestURI("http://google.com/")
if err != nil {
panic(err)
}
The above example will not fail, but these will:
u, err := url.ParseRequestURI("http//google.com")
u, err := url.ParseRequestURI("google.com")
u, err := url.ParseRequestURI("/foo/bar")
The accepted answer allows empty http:// and relative urls like /foo/bar. If you want a stricter check, this will reject those:
import "net/url"
func IsUrl(str string) bool {
u, err := url.Parse(str)
return err == nil && u.Scheme != "" && u.Host != ""
}
Example: https://play.golang.org/p/JngFarWPF2-
Which came from this answer: https://stackoverflow.com/a/25747925/744298
This helped me understand how the standard library url.Parse method works, hope it helps some of you as well. Notice that all these values never throw an error.
package main
import (
"fmt"
"net/url"
)
func main() {
urls := []string{
"https",
"https://",
"",
"http://www",
"http://www.dumpsters.com",
"https://www.dumpsters.com:443",
"/testing-path",
"testing-path",
"alskjff#?asf//dfas",
}
for _, u := range urls {
val, err := url.Parse(u)
scheme := val.Scheme
host := val.Host
hostname := val.Hostname()
path := val.Path
fmt.Println("val : "+u+" : ", val)
fmt.Println("error : "+u+" : ", err)
fmt.Println("scheme : "+u+" : ", scheme)
fmt.Println("host : "+u+" : ", host)
fmt.Println("hostname : "+u+" : ", hostname)
fmt.Println("path : "+u+" : ", path)
fmt.Println()
}
}
The results
val : https : https
error : https : <nil>
scheme : https :
host : https :
hostname : https :
path : https : https
val : https:// : https:
error : https:// : <nil>
scheme : https:// : https
host : https:// :
hostname : https:// :
path : https:// :
val : :
error : : <nil>
scheme : :
host : :
hostname : :
path : :
val : http://www : http://www
error : http://www : <nil>
scheme : http://www : http
host : http://www : www
hostname : http://www : www
path : http://www :
val : http://www.dumpsters.com : http://www.dumpsters.com
error : http://www.dumpsters.com : <nil>
scheme : http://www.dumpsters.com : http
host : http://www.dumpsters.com : www.dumpsters.com
hostname : http://www.dumpsters.com : www.dumpsters.com
path : http://www.dumpsters.com :
val : https://www.dumpsters.com:443 : https://www.dumpsters.com:443
error : https://www.dumpsters.com:443 : <nil>
scheme : https://www.dumpsters.com:443 : https
host : https://www.dumpsters.com:443 : www.dumpsters.com:443
hostname : https://www.dumpsters.com:443 : www.dumpsters.com
path : https://www.dumpsters.com:443 :
val : /testing-path : /testing-path
error : /testing-path : <nil>
scheme : /testing-path :
host : /testing-path :
hostname : /testing-path :
path : /testing-path : /testing-path
val : testing-path : testing-path
error : testing-path : <nil>
scheme : testing-path :
host : testing-path :
hostname : testing-path :
path : testing-path : testing-path
val : alskjff#?asf//dfas : alskjff#?asf//dfas
error : alskjff#?asf//dfas : <nil>
scheme : alskjff#?asf//dfas :
host : alskjff#?asf//dfas :
hostname : alskjff#?asf//dfas :
path : alskjff#?asf//dfas : alskjff
func IsUrl(str string) bool {
url, err := url.ParseRequestURI(str)
if err != nil {
log.Info(err.Error())
return false
}
address := net.ParseIP(url.Host)
log.Infow("url-info", "host", address)
if address == nil {
log.Infow("url-info", "host", url.Host)
return strings.Contains(url.Host, ".")
}
return true
}
func Test_IsAllowUrl(t *testing.T) {
assert.True(t, IsUrl("http://google.com"))
assert.True(t, IsUrl("http://w.com/cn"))
assert.True(t, IsUrl("http://192.158.0.1:90"))
assert.False(t, IsUrl("http://w"))
assert.False(t, IsUrl("fsw"))
assert.False(t, IsUrl("http://192.158.1/1"))
}
the last "http:/192.158.1/1" not pass. may be should match all allow domains,but will be to complex https://www.iana.org/domains/root/db