@@ -383,6 +383,16 @@ var urltests = []URLTest{
383383 },
384384 "" ,
385385 },
386+ // valid IPv6 host with port and path
387+ {
388+ "https://[2001:db8::1]:8443/test/path" ,
389+ & URL {
390+ Scheme : "https" ,
391+ Host : "[2001:db8::1]:8443" ,
392+ Path : "/test/path" ,
393+ },
394+ "" ,
395+ },
386396 // host subcomponent; IPv6 address with zone identifier in RFC 6874
387397 {
388398 "http://[fe80::1%25en0]/" , // alphanum zone identifier
@@ -707,6 +717,24 @@ var parseRequestURLTests = []struct {
707717 // RFC 6874.
708718 {"http://[fe80::1%en0]/" , false },
709719 {"http://[fe80::1%en0]:8080/" , false },
720+
721+ // Tests exercising RFC 3986 compliance
722+ {"https://[1:2:3:4:5:6:7:8]" , true }, // full IPv6 address
723+ {"https://[2001:db8::a:b:c:d]" , true }, // compressed IPv6 address
724+ {"https://[fe80::1%25eth0]" , true }, // link-local address with zone ID (interface name)
725+ {"https://[fe80::abc:def%254]" , true }, // link-local address with zone ID (interface index)
726+ {"https://[2001:db8::1]/path" , true }, // compressed IPv6 address with path
727+ {"https://[fe80::1%25eth0]/path?query=1" , true }, // link-local with zone, path, and query
728+
729+ {"https://[::ffff:192.0.2.1]" , false },
730+ {"https://[:1] " , false },
731+ {"https://[1:2:3:4:5:6:7:8:9]" , false },
732+ {"https://[1::1::1]" , false },
733+ {"https://[1:2:3:]" , false },
734+ {"https://[ffff::127.0.0.4000]" , false },
735+ {"https://[0:0::test.com]:80" , false },
736+ {"https://[2001:db8::test.com]" , false },
737+ {"https://[test.com]" , false },
710738}
711739
712740func TestParseRequestURI (t * testing.T ) {
@@ -1643,6 +1671,17 @@ func TestParseErrors(t *testing.T) {
16431671 {"cache_object:foo" , true },
16441672 {"cache_object:foo/bar" , true },
16451673 {"cache_object/:foo/bar" , false },
1674+
1675+ {"http://[192.168.0.1]/" , true }, // IPv4 in brackets
1676+ {"http://[192.168.0.1]:8080/" , true }, // IPv4 in brackets with port
1677+ {"http://[::ffff:192.168.0.1]/" , true }, // IPv4-mapped IPv6 in brackets
1678+ {"http://[::ffff:192.168.0.1]:8080/" , true }, // IPv4-mapped IPv6 in brackets with port
1679+ {"http://[::ffff:c0a8:1]/" , true }, // IPv4-mapped IPv6 in brackets (hex)
1680+ {"http://[not-an-ip]/" , true }, // invalid IP string in brackets
1681+ {"http://[fe80::1%foo]/" , true }, // invalid zone format in brackets
1682+ {"http://[fe80::1" , true }, // missing closing bracket
1683+ {"http://fe80::1]/" , true }, // missing opening bracket
1684+ {"http://[test.com]/" , true }, // domain name in brackets
16461685 }
16471686 for _ , tt := range tests {
16481687 u , err := Parse (tt .in )
0 commit comments