Skip to content

Commit

Permalink
Added "http_url" tag to validate if the variable is a HTTP(s) URL (#1047
Browse files Browse the repository at this point in the history
)
  • Loading branch information
phith0n committed Mar 19, 2023
1 parent f2078f7 commit 89b91ce
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -114,6 +114,7 @@ Baked-in Validations
| unix_addr | Unix domain socket end point Address |
| uri | URI String |
| url | URL String |
| http_url | HTTP URL String |
| url_encoded | URL Encoded |
| urn_rfc2141 | Urn RFC 2141 String |

Expand Down
18 changes: 18 additions & 0 deletions baked_in.go
Expand Up @@ -123,6 +123,7 @@ var (
"e164": isE164,
"email": isEmail,
"url": isURL,
"http_url": isHttpURL,
"uri": isURI,
"urn_rfc2141": isUrnRFC2141, // RFC 2141
"file": isFile,
Expand Down Expand Up @@ -1403,6 +1404,23 @@ func isURL(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}

// isHttpURL is the validation function for validating if the current field's value is a valid HTTP(s) URL.
func isHttpURL(fl FieldLevel) bool {
if !isURL(fl) {
return false
}

field := fl.Field()
switch field.Kind() {
case reflect.String:

s := strings.ToLower(field.String())
return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
}

panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}

// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
func isUrnRFC2141(fl FieldLevel) bool {
field := fl.Field()
Expand Down
71 changes: 71 additions & 0 deletions validator_test.go
Expand Up @@ -7878,6 +7878,77 @@ func TestUrl(t *testing.T) {
PanicMatches(t, func() { _ = validate.Var(i, "url") }, "Bad field type int")
}

func TestHttpUrl(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"http://foo.bar#com", true},
{"http://foobar.com", true},
{"HTTP://foobar.com", true},
{"https://foobar.com", true},
{"foobar.com", false},
{"http://foobar.coffee/", true},
{"http://foobar.中文网/", true},
{"http://foobar.org/", true},
{"http://foobar.org:8080/", true},
{"ftp://foobar.ru/", false},
{"file:///etc/passwd", false},
{"file://C:/windows/win.ini", false},
{"http://user:pass@www.foobar.com/", true},
{"http://127.0.0.1/", true},
{"http://duckduckgo.com/?q=%2F", true},
{"http://localhost:3000/", true},
{"http://foobar.com/?foo=bar#baz=qux", true},
{"http://foobar.com?foo=bar", true},
{"http://www.xn--froschgrn-x9a.net/", true},
{"", false},
{"a://b", false},
{"xyz://foobar.com", false},
{"invalid.", false},
{".com", false},
{"rtmp://foobar.com", false},
{"http://www.foo_bar.com/", true},
{"http://localhost:3000/", true},
{"http://foobar.com/#baz", true},
{"http://foobar.com#baz=qux", true},
{"http://foobar.com/t$-_.+!*\\'(),", true},
{"http://www.foobar.com/~foobar", true},
{"http://www.-foobar.com/", true},
{"http://www.foo---bar.com/", true},
{"mailto:someone@example.com", false},
{"irc://irc.server.org/channel", false},
{"irc://#channel@network", false},
{"/abs/test/dir", false},
{"./rel/test/dir", false},
}

validate := New()

for i, test := range tests {

errs := validate.Var(test.param, "http_url")

if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
} else {
val := getError(errs, "", "")
if val.Tag() != "http_url" {
t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
}
}
}
}

i := 1
PanicMatches(t, func() { _ = validate.Var(i, "http_url") }, "Bad field type int")
}

func TestUri(t *testing.T) {
tests := []struct {
param string
Expand Down

0 comments on commit 89b91ce

Please sign in to comment.