@@ -1465,29 +1465,49 @@ func isURI(fl FieldLevel) bool {
1465
1465
func isURL (fl FieldLevel ) bool {
1466
1466
field := fl .Field ()
1467
1467
1468
+ var s string
1469
+ var uri * url.URL
1470
+ var ok bool
1471
+
1468
1472
switch field .Kind () {
1469
1473
case reflect .String :
1474
+ s = strings .ToLower (field .String ())
1475
+ case reflect .Struct :
1476
+ var u url.URL
1477
+ if u , ok = field .Interface ().(url.URL ); ! ok {
1478
+ panic (fmt .Sprintf ("Bad field type %s" , field .Type ()))
1479
+ }
1480
+ uri = & u
1481
+ default :
1482
+ var stringer fmt.Stringer
1483
+ if stringer , ok = field .Interface ().(fmt.Stringer ); ! ok {
1484
+ panic (fmt .Sprintf ("Bad field type %s" , field .Type ()))
1485
+ }
1486
+ s = stringer .String ()
1487
+ }
1470
1488
1471
- s := strings .ToLower (field .String ())
1489
+ if len (s ) == 0 && uri == nil {
1490
+ return false
1491
+ }
1472
1492
1473
- if len (s ) == 0 {
1493
+ if uri == nil {
1494
+ var err error
1495
+ if uri , err = url .Parse (s ); err != nil {
1474
1496
return false
1475
1497
}
1498
+ }
1476
1499
1477
- url , err := url .Parse (s )
1478
- if err != nil || url .Scheme == "" {
1479
- return false
1480
- }
1481
- isFileScheme := url .Scheme == "file"
1500
+ if uri .Scheme == "" {
1501
+ return false
1502
+ }
1482
1503
1483
- if (isFileScheme && (len (url .Path ) == 0 || url .Path == "/" )) || (! isFileScheme && len (url .Host ) == 0 && len (url .Fragment ) == 0 && len (url .Opaque ) == 0 ) {
1484
- return false
1485
- }
1504
+ isFileScheme := uri .Scheme == "file"
1486
1505
1487
- return true
1506
+ if (isFileScheme && (len (uri .Path ) == 0 || uri .Path == "/" )) || (! isFileScheme && len (uri .Host ) == 0 && len (uri .Fragment ) == 0 && len (uri .Opaque ) == 0 ) {
1507
+ return false
1488
1508
}
1489
1509
1490
- panic ( fmt . Sprintf ( "Bad field type %s" , field . Type ()))
1510
+ return true
1491
1511
}
1492
1512
1493
1513
// isHttpURL is the validation function for validating if the current field's value is a valid HTTP(s) URL.
@@ -1497,20 +1517,32 @@ func isHttpURL(fl FieldLevel) bool {
1497
1517
}
1498
1518
1499
1519
field := fl .Field ()
1520
+ var s string
1521
+ var ok bool
1500
1522
switch field .Kind () {
1501
1523
case reflect .String :
1524
+ s = strings .ToLower (field .String ())
1525
+ case reflect .Struct :
1526
+ var u url.URL
1502
1527
1503
- s := strings .ToLower (field .String ())
1504
-
1505
- url , err := url .Parse (s )
1506
- if err != nil || url .Host == "" {
1507
- return false
1528
+ if u , ok = field .Interface ().(url.URL ); ! ok {
1529
+ panic (fmt .Sprintf ("Bad field type %s" , field .Type ()))
1530
+ }
1531
+ s = u .String ()
1532
+ default :
1533
+ if stringer , ok := fl .Field ().Interface ().(fmt.Stringer ); ok {
1534
+ s = stringer .String ()
1535
+ } else {
1536
+ panic (fmt .Sprintf ("Bad field type %s" , field .Type ()))
1508
1537
}
1538
+ }
1509
1539
1510
- return url .Scheme == "http" || url .Scheme == "https"
1540
+ url , err := url .Parse (s )
1541
+ if err != nil || url .Host == "" {
1542
+ return false
1511
1543
}
1512
1544
1513
- panic ( fmt . Sprintf ( "Bad field type %s" , field . Type ()))
1545
+ return url . Scheme == "http" || url . Scheme == "https"
1514
1546
}
1515
1547
1516
1548
// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
0 commit comments