diff options
-rw-r--r-- | cli/js/web/url.ts | 13 | ||||
-rw-r--r-- | cli/tests/unit/url_test.ts | 22 |
2 files changed, 32 insertions, 3 deletions
diff --git a/cli/js/web/url.ts b/cli/js/web/url.ts index bbe405f85..76aa21919 100644 --- a/cli/js/web/url.ts +++ b/cli/js/web/url.ts @@ -39,7 +39,7 @@ const MAX_PORT = 2 ** 16 - 1; // (LHS). e.g. // takePattern("https://deno.land:80", /^([a-z]+):[/]{2}/) // = ["http", "deno.land:80"] -// takePattern("deno.land:80", /^([^:]+):) +// takePattern("deno.land:80", /^(\[[0-9a-fA-F.:]{2,}\]|[^:]+)/) // = ["deno.land", "80"] function takePattern(string: string, pattern: RegExp): [string, string] { let capture = ""; @@ -80,7 +80,10 @@ function parse(url: string, isBase = true): URLParts | undefined { parts.username = encodeUserinfo(parts.username); [parts.password] = takePattern(restAuthentication, /^:(.*)/); parts.password = encodeUserinfo(parts.password); - [parts.hostname, restAuthority] = takePattern(restAuthority, /^([^:]+)/); + [parts.hostname, restAuthority] = takePattern( + restAuthority, + /^(\[[0-9a-fA-F.:]{2,}\]|[^:]+)/ + ); [parts.port] = takePattern(restAuthority, /^:(.*)/); if (!isValidPort(parts.port)) { return undefined; @@ -92,7 +95,11 @@ function parse(url: string, isBase = true): URLParts | undefined { parts.port = ""; } try { - parts.hostname = encodeHostname(parts.hostname).toLowerCase(); + const IPv6re = /^\[[0-9a-fA-F.:]{2,}\]$/; + if (!IPv6re.test(parts.hostname)) { + parts.hostname = encodeHostname(parts.hostname); // Non-IPv6 URLs + } + parts.hostname = parts.hostname.toLowerCase(); } catch { return undefined; } diff --git a/cli/tests/unit/url_test.ts b/cli/tests/unit/url_test.ts index 68fcbd95e..b4c31ea6d 100644 --- a/cli/tests/unit/url_test.ts +++ b/cli/tests/unit/url_test.ts @@ -29,6 +29,28 @@ unitTest(function urlParsing(): void { JSON.stringify({ key: url }), `{"key":"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"}` ); + + // IPv6 type hostname. + const urlv6 = new URL( + "https://foo:bar@[::1]:8000/qux/quux?foo=bar&baz=12#qat" + ); + assertEquals(urlv6.origin, "https://[::1]:8000"); + assertEquals(urlv6.password, "bar"); + assertEquals(urlv6.pathname, "/qux/quux"); + assertEquals(urlv6.port, "8000"); + assertEquals(urlv6.protocol, "https:"); + assertEquals(urlv6.search, "?foo=bar&baz=12"); + assertEquals(urlv6.searchParams.getAll("foo"), ["bar"]); + assertEquals(urlv6.searchParams.getAll("baz"), ["12"]); + assertEquals(urlv6.username, "foo"); + assertEquals( + String(urlv6), + "https://foo:bar@[::1]:8000/qux/quux?foo=bar&baz=12#qat" + ); + assertEquals( + JSON.stringify({ key: urlv6 }), + `{"key":"https://foo:bar@[::1]:8000/qux/quux?foo=bar&baz=12#qat"}` + ); }); unitTest(function urlModifications(): void { |