Skip to content

Commit 45f3a8e

Browse files
authored
Added https_url tag (#1461)
1 parent 7a23bca commit 45f3a8e

File tree

3 files changed

+100
-1
lines changed

3 files changed

+100
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ validate := validator.New(validator.WithRequiredStructEnabled())
124124
| unix_addr | Unix domain socket end point Address |
125125
| uri | URI String |
126126
| url | URL String |
127-
| http_url | HTTP URL String |
127+
| http_url | HTTP(s) URL String |
128+
| https_url | HTTPS-only URL String |
128129
| url_encoded | URL Encoded |
129130
| urn_rfc2141 | Urn RFC 2141 String |
130131

baked_in.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ var (
134134
"email": isEmail,
135135
"url": isURL,
136136
"http_url": isHttpURL,
137+
"https_url": isHttpsURL,
137138
"uri": isURI,
138139
"urn_rfc2141": isUrnRFC2141, // RFC 2141
139140
"file": isFile,
@@ -1513,6 +1514,29 @@ func isHttpURL(fl FieldLevel) bool {
15131514
panic(fmt.Sprintf("Bad field type %s", field.Type()))
15141515
}
15151516

1517+
// isHttpsURL is the validation function for validating if the current field's value is a valid HTTPS-only URL.
1518+
func isHttpsURL(fl FieldLevel) bool {
1519+
if !isURL(fl) {
1520+
return false
1521+
}
1522+
1523+
field := fl.Field()
1524+
switch field.Kind() {
1525+
case reflect.String:
1526+
1527+
s := strings.ToLower(field.String())
1528+
1529+
url, err := url.Parse(s)
1530+
if err != nil || url.Host == "" {
1531+
return false
1532+
}
1533+
1534+
return url.Scheme == "https"
1535+
}
1536+
1537+
panic(fmt.Sprintf("Bad field type %s", field.Type()))
1538+
}
1539+
15161540
// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
15171541
func isUrnRFC2141(fl FieldLevel) bool {
15181542
field := fl.Field()

validator_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8360,6 +8360,80 @@ func TestHttpUrl(t *testing.T) {
83608360
PanicMatches(t, func() { _ = validate.Var(i, "http_url") }, "Bad field type int")
83618361
}
83628362

8363+
func TestHttpsUrl(t *testing.T) {
8364+
tests := []struct {
8365+
param string
8366+
expected bool
8367+
}{
8368+
{"https://foo.bar#com", true},
8369+
{"https://foobar.com", true},
8370+
{"HTTPS://foobar.com", true},
8371+
{"http://foobar.com", false},
8372+
{"foobar.com", false},
8373+
{"https://foobar.coffee/", true},
8374+
{"https://foobar.中文网/", true},
8375+
{"https://foobar.org/", true},
8376+
{"https://foobar.org:8080/", true},
8377+
{"ftp://foobar.ru/", false},
8378+
{"file:///etc/passwd", false},
8379+
{"file://C:/windows/win.ini", false},
8380+
{"https://user:[email protected]/", true},
8381+
{"https://127.0.0.1/", true},
8382+
{"https://duckduckgo.com/?q=%2F", true},
8383+
{"https://localhost:3000/", true},
8384+
{"https://foobar.com/?foo=bar#baz=qux", true},
8385+
{"https://foobar.com?foo=bar", true},
8386+
{"https://www.xn--froschgrn-x9a.net/", true},
8387+
{"", false},
8388+
{"a://b", false},
8389+
{"xyz://foobar.com", false},
8390+
{"invalid.", false},
8391+
{".com", false},
8392+
{"rtmp://foobar.com", false},
8393+
{"https://www.foo_bar.com/", true},
8394+
{"https://localhost:3000/", true},
8395+
{"https://foobar.com/#baz", true},
8396+
{"https://foobar.com#baz=qux", true},
8397+
{"https://foobar.com/t$-_.+!*\\'(),", true},
8398+
{"https://www.foobar.com/~foobar", true},
8399+
{"https://www.-foobar.com/", true},
8400+
{"https://www.foo---bar.com/", true},
8401+
{"mailto:[email protected]", false},
8402+
{"irc://irc.server.org/channel", false},
8403+
{"irc://#channel@network", false},
8404+
{"/abs/test/dir", false},
8405+
{"./rel/test/dir", false},
8406+
{"https:", false},
8407+
{"https://", false},
8408+
{"https://#invalid", false},
8409+
{"http://1.1.1.1", false},
8410+
}
8411+
8412+
validate := New()
8413+
8414+
for i, test := range tests {
8415+
errs := validate.Var(test.param, "https_url")
8416+
8417+
if test.expected {
8418+
if !IsEqual(errs, nil) {
8419+
t.Fatalf("Index: %d HTTPS URL failed Error: %s", i, errs)
8420+
}
8421+
} else {
8422+
if IsEqual(errs, nil) {
8423+
t.Fatalf("Index: %d HTTPS URL failed Error: %s", i, errs)
8424+
} else {
8425+
val := getError(errs, "", "")
8426+
if val.Tag() != "https_url" {
8427+
t.Fatalf("Index: %d HTTPS URL failed Error: %s", i, errs)
8428+
}
8429+
}
8430+
}
8431+
}
8432+
8433+
i := 1
8434+
PanicMatches(t, func() { _ = validate.Var(i, "https_url") }, "Bad field type int")
8435+
}
8436+
83638437
func TestUri(t *testing.T) {
83648438
tests := []struct {
83658439
param string

0 commit comments

Comments
 (0)