11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciconst assert = require('assert'); 41cb0ef41Sopenharmony_ciconst url = require('url'); 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ciif (!common.hasIntl) 71cb0ef41Sopenharmony_ci common.skip('missing Intl'); 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci// Formatting tests to verify that it'll format slightly wonky content to a 101cb0ef41Sopenharmony_ci// valid URL. 111cb0ef41Sopenharmony_ciconst formatTests = { 121cb0ef41Sopenharmony_ci 'http://example.com?': { 131cb0ef41Sopenharmony_ci href: 'http://example.com/?', 141cb0ef41Sopenharmony_ci protocol: 'http:', 151cb0ef41Sopenharmony_ci slashes: true, 161cb0ef41Sopenharmony_ci host: 'example.com', 171cb0ef41Sopenharmony_ci hostname: 'example.com', 181cb0ef41Sopenharmony_ci search: '?', 191cb0ef41Sopenharmony_ci query: {}, 201cb0ef41Sopenharmony_ci pathname: '/' 211cb0ef41Sopenharmony_ci }, 221cb0ef41Sopenharmony_ci 'http://example.com?foo=bar#frag': { 231cb0ef41Sopenharmony_ci href: 'http://example.com/?foo=bar#frag', 241cb0ef41Sopenharmony_ci protocol: 'http:', 251cb0ef41Sopenharmony_ci host: 'example.com', 261cb0ef41Sopenharmony_ci hostname: 'example.com', 271cb0ef41Sopenharmony_ci hash: '#frag', 281cb0ef41Sopenharmony_ci search: '?foo=bar', 291cb0ef41Sopenharmony_ci query: 'foo=bar', 301cb0ef41Sopenharmony_ci pathname: '/' 311cb0ef41Sopenharmony_ci }, 321cb0ef41Sopenharmony_ci 'http://example.com?foo=@bar#frag': { 331cb0ef41Sopenharmony_ci href: 'http://example.com/?foo=@bar#frag', 341cb0ef41Sopenharmony_ci protocol: 'http:', 351cb0ef41Sopenharmony_ci host: 'example.com', 361cb0ef41Sopenharmony_ci hostname: 'example.com', 371cb0ef41Sopenharmony_ci hash: '#frag', 381cb0ef41Sopenharmony_ci search: '?foo=@bar', 391cb0ef41Sopenharmony_ci query: 'foo=@bar', 401cb0ef41Sopenharmony_ci pathname: '/' 411cb0ef41Sopenharmony_ci }, 421cb0ef41Sopenharmony_ci 'http://example.com?foo=/bar/#frag': { 431cb0ef41Sopenharmony_ci href: 'http://example.com/?foo=/bar/#frag', 441cb0ef41Sopenharmony_ci protocol: 'http:', 451cb0ef41Sopenharmony_ci host: 'example.com', 461cb0ef41Sopenharmony_ci hostname: 'example.com', 471cb0ef41Sopenharmony_ci hash: '#frag', 481cb0ef41Sopenharmony_ci search: '?foo=/bar/', 491cb0ef41Sopenharmony_ci query: 'foo=/bar/', 501cb0ef41Sopenharmony_ci pathname: '/' 511cb0ef41Sopenharmony_ci }, 521cb0ef41Sopenharmony_ci 'http://example.com?foo=?bar/#frag': { 531cb0ef41Sopenharmony_ci href: 'http://example.com/?foo=?bar/#frag', 541cb0ef41Sopenharmony_ci protocol: 'http:', 551cb0ef41Sopenharmony_ci host: 'example.com', 561cb0ef41Sopenharmony_ci hostname: 'example.com', 571cb0ef41Sopenharmony_ci hash: '#frag', 581cb0ef41Sopenharmony_ci search: '?foo=?bar/', 591cb0ef41Sopenharmony_ci query: 'foo=?bar/', 601cb0ef41Sopenharmony_ci pathname: '/' 611cb0ef41Sopenharmony_ci }, 621cb0ef41Sopenharmony_ci 'http://example.com#frag=?bar/#frag': { 631cb0ef41Sopenharmony_ci href: 'http://example.com/#frag=?bar/#frag', 641cb0ef41Sopenharmony_ci protocol: 'http:', 651cb0ef41Sopenharmony_ci host: 'example.com', 661cb0ef41Sopenharmony_ci hostname: 'example.com', 671cb0ef41Sopenharmony_ci hash: '#frag=?bar/#frag', 681cb0ef41Sopenharmony_ci pathname: '/' 691cb0ef41Sopenharmony_ci }, 701cb0ef41Sopenharmony_ci 'http://google.com" onload="alert(42)/': { 711cb0ef41Sopenharmony_ci href: 'http://google.com/%22%20onload=%22alert(42)/', 721cb0ef41Sopenharmony_ci protocol: 'http:', 731cb0ef41Sopenharmony_ci host: 'google.com', 741cb0ef41Sopenharmony_ci pathname: '/%22%20onload=%22alert(42)/' 751cb0ef41Sopenharmony_ci }, 761cb0ef41Sopenharmony_ci 'http://a.com/a/b/c?s#h': { 771cb0ef41Sopenharmony_ci href: 'http://a.com/a/b/c?s#h', 781cb0ef41Sopenharmony_ci protocol: 'http', 791cb0ef41Sopenharmony_ci host: 'a.com', 801cb0ef41Sopenharmony_ci pathname: 'a/b/c', 811cb0ef41Sopenharmony_ci hash: 'h', 821cb0ef41Sopenharmony_ci search: 's' 831cb0ef41Sopenharmony_ci }, 841cb0ef41Sopenharmony_ci 'xmpp:isaacschlueter@jabber.org': { 851cb0ef41Sopenharmony_ci href: 'xmpp:isaacschlueter@jabber.org', 861cb0ef41Sopenharmony_ci protocol: 'xmpp:', 871cb0ef41Sopenharmony_ci host: 'jabber.org', 881cb0ef41Sopenharmony_ci auth: 'isaacschlueter', 891cb0ef41Sopenharmony_ci hostname: 'jabber.org' 901cb0ef41Sopenharmony_ci }, 911cb0ef41Sopenharmony_ci 'http://atpass:foo%40bar@127.0.0.1/': { 921cb0ef41Sopenharmony_ci href: 'http://atpass:foo%40bar@127.0.0.1/', 931cb0ef41Sopenharmony_ci auth: 'atpass:foo@bar', 941cb0ef41Sopenharmony_ci hostname: '127.0.0.1', 951cb0ef41Sopenharmony_ci protocol: 'http:', 961cb0ef41Sopenharmony_ci pathname: '/' 971cb0ef41Sopenharmony_ci }, 981cb0ef41Sopenharmony_ci 'http://atslash%2F%40:%2F%40@foo/': { 991cb0ef41Sopenharmony_ci href: 'http://atslash%2F%40:%2F%40@foo/', 1001cb0ef41Sopenharmony_ci auth: 'atslash/@:/@', 1011cb0ef41Sopenharmony_ci hostname: 'foo', 1021cb0ef41Sopenharmony_ci protocol: 'http:', 1031cb0ef41Sopenharmony_ci pathname: '/' 1041cb0ef41Sopenharmony_ci }, 1051cb0ef41Sopenharmony_ci 'svn+ssh://foo/bar': { 1061cb0ef41Sopenharmony_ci href: 'svn+ssh://foo/bar', 1071cb0ef41Sopenharmony_ci hostname: 'foo', 1081cb0ef41Sopenharmony_ci protocol: 'svn+ssh:', 1091cb0ef41Sopenharmony_ci pathname: '/bar', 1101cb0ef41Sopenharmony_ci slashes: true 1111cb0ef41Sopenharmony_ci }, 1121cb0ef41Sopenharmony_ci 'dash-test://foo/bar': { 1131cb0ef41Sopenharmony_ci href: 'dash-test://foo/bar', 1141cb0ef41Sopenharmony_ci hostname: 'foo', 1151cb0ef41Sopenharmony_ci protocol: 'dash-test:', 1161cb0ef41Sopenharmony_ci pathname: '/bar', 1171cb0ef41Sopenharmony_ci slashes: true 1181cb0ef41Sopenharmony_ci }, 1191cb0ef41Sopenharmony_ci 'dash-test:foo/bar': { 1201cb0ef41Sopenharmony_ci href: 'dash-test:foo/bar', 1211cb0ef41Sopenharmony_ci hostname: 'foo', 1221cb0ef41Sopenharmony_ci protocol: 'dash-test:', 1231cb0ef41Sopenharmony_ci pathname: '/bar' 1241cb0ef41Sopenharmony_ci }, 1251cb0ef41Sopenharmony_ci 'dot.test://foo/bar': { 1261cb0ef41Sopenharmony_ci href: 'dot.test://foo/bar', 1271cb0ef41Sopenharmony_ci hostname: 'foo', 1281cb0ef41Sopenharmony_ci protocol: 'dot.test:', 1291cb0ef41Sopenharmony_ci pathname: '/bar', 1301cb0ef41Sopenharmony_ci slashes: true 1311cb0ef41Sopenharmony_ci }, 1321cb0ef41Sopenharmony_ci 'dot.test:foo/bar': { 1331cb0ef41Sopenharmony_ci href: 'dot.test:foo/bar', 1341cb0ef41Sopenharmony_ci hostname: 'foo', 1351cb0ef41Sopenharmony_ci protocol: 'dot.test:', 1361cb0ef41Sopenharmony_ci pathname: '/bar' 1371cb0ef41Sopenharmony_ci }, 1381cb0ef41Sopenharmony_ci // IPv6 support 1391cb0ef41Sopenharmony_ci 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature': { 1401cb0ef41Sopenharmony_ci href: 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature', 1411cb0ef41Sopenharmony_ci protocol: 'coap:', 1421cb0ef41Sopenharmony_ci auth: 'u:p', 1431cb0ef41Sopenharmony_ci hostname: '::1', 1441cb0ef41Sopenharmony_ci port: '61616', 1451cb0ef41Sopenharmony_ci pathname: '/.well-known/r', 1461cb0ef41Sopenharmony_ci search: 'n=Temperature' 1471cb0ef41Sopenharmony_ci }, 1481cb0ef41Sopenharmony_ci 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton': { 1491cb0ef41Sopenharmony_ci href: 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton', 1501cb0ef41Sopenharmony_ci protocol: 'coap', 1511cb0ef41Sopenharmony_ci host: '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616', 1521cb0ef41Sopenharmony_ci pathname: '/s/stopButton' 1531cb0ef41Sopenharmony_ci }, 1541cb0ef41Sopenharmony_ci 'http://[::]/': { 1551cb0ef41Sopenharmony_ci href: 'http://[::]/', 1561cb0ef41Sopenharmony_ci protocol: 'http:', 1571cb0ef41Sopenharmony_ci hostname: '[::]', 1581cb0ef41Sopenharmony_ci pathname: '/' 1591cb0ef41Sopenharmony_ci }, 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci // Encode context-specific delimiters in path and query, but do not touch 1621cb0ef41Sopenharmony_ci // other non-delimiter chars like `%`. 1631cb0ef41Sopenharmony_ci // <https://github.com/nodejs/node-v0.x-archive/issues/4082> 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci // `#`,`?` in path 1661cb0ef41Sopenharmony_ci '/path/to/%%23%3F+=&.txt?foo=theA1#bar': { 1671cb0ef41Sopenharmony_ci href: '/path/to/%%23%3F+=&.txt?foo=theA1#bar', 1681cb0ef41Sopenharmony_ci pathname: '/path/to/%#?+=&.txt', 1691cb0ef41Sopenharmony_ci query: { 1701cb0ef41Sopenharmony_ci foo: 'theA1' 1711cb0ef41Sopenharmony_ci }, 1721cb0ef41Sopenharmony_ci hash: '#bar' 1731cb0ef41Sopenharmony_ci }, 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci // `#`,`?` in path + `#` in query 1761cb0ef41Sopenharmony_ci '/path/to/%%23%3F+=&.txt?foo=the%231#bar': { 1771cb0ef41Sopenharmony_ci href: '/path/to/%%23%3F+=&.txt?foo=the%231#bar', 1781cb0ef41Sopenharmony_ci pathname: '/path/to/%#?+=&.txt', 1791cb0ef41Sopenharmony_ci query: { 1801cb0ef41Sopenharmony_ci foo: 'the#1' 1811cb0ef41Sopenharmony_ci }, 1821cb0ef41Sopenharmony_ci hash: '#bar' 1831cb0ef41Sopenharmony_ci }, 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci // `#` in path end + `#` in query 1861cb0ef41Sopenharmony_ci '/path/to/%%23?foo=the%231#bar': { 1871cb0ef41Sopenharmony_ci href: '/path/to/%%23?foo=the%231#bar', 1881cb0ef41Sopenharmony_ci pathname: '/path/to/%#', 1891cb0ef41Sopenharmony_ci query: { 1901cb0ef41Sopenharmony_ci foo: 'the#1' 1911cb0ef41Sopenharmony_ci }, 1921cb0ef41Sopenharmony_ci hash: '#bar' 1931cb0ef41Sopenharmony_ci }, 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci // `?` and `#` in path and search 1961cb0ef41Sopenharmony_ci 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag': { 1971cb0ef41Sopenharmony_ci href: 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag', 1981cb0ef41Sopenharmony_ci protocol: 'http:', 1991cb0ef41Sopenharmony_ci hostname: 'ex.com', 2001cb0ef41Sopenharmony_ci hash: '#frag', 2011cb0ef41Sopenharmony_ci search: '?abc=the#1?&foo=bar', 2021cb0ef41Sopenharmony_ci pathname: '/foo?100%m#r', 2031cb0ef41Sopenharmony_ci }, 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci // `?` and `#` in search only 2061cb0ef41Sopenharmony_ci 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag': { 2071cb0ef41Sopenharmony_ci href: 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag', 2081cb0ef41Sopenharmony_ci protocol: 'http:', 2091cb0ef41Sopenharmony_ci hostname: 'ex.com', 2101cb0ef41Sopenharmony_ci hash: '#frag', 2111cb0ef41Sopenharmony_ci search: '?abc=the#1?&foo=bar', 2121cb0ef41Sopenharmony_ci pathname: '/fooA100%mBr', 2131cb0ef41Sopenharmony_ci }, 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci // Multiple `#` in search 2161cb0ef41Sopenharmony_ci 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag': { 2171cb0ef41Sopenharmony_ci href: 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag', 2181cb0ef41Sopenharmony_ci protocol: 'http:', 2191cb0ef41Sopenharmony_ci slashes: true, 2201cb0ef41Sopenharmony_ci host: 'example.com', 2211cb0ef41Sopenharmony_ci hostname: 'example.com', 2221cb0ef41Sopenharmony_ci hash: '#frag', 2231cb0ef41Sopenharmony_ci search: '?foo=bar#1#2#3&abc=#4##5', 2241cb0ef41Sopenharmony_ci query: {}, 2251cb0ef41Sopenharmony_ci pathname: '/' 2261cb0ef41Sopenharmony_ci }, 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci // More than 255 characters in hostname which exceeds the limit 2291cb0ef41Sopenharmony_ci [`http://${'a'.repeat(255)}.com/node`]: { 2301cb0ef41Sopenharmony_ci href: 'http:///node', 2311cb0ef41Sopenharmony_ci protocol: 'http:', 2321cb0ef41Sopenharmony_ci slashes: true, 2331cb0ef41Sopenharmony_ci host: '', 2341cb0ef41Sopenharmony_ci hostname: '', 2351cb0ef41Sopenharmony_ci pathname: '/node', 2361cb0ef41Sopenharmony_ci path: '/node' 2371cb0ef41Sopenharmony_ci }, 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci // Greater than or equal to 63 characters after `.` in hostname 2401cb0ef41Sopenharmony_ci [`http://www.${'z'.repeat(63)}example.com/node`]: { 2411cb0ef41Sopenharmony_ci href: `http://www.${'z'.repeat(63)}example.com/node`, 2421cb0ef41Sopenharmony_ci protocol: 'http:', 2431cb0ef41Sopenharmony_ci slashes: true, 2441cb0ef41Sopenharmony_ci host: `www.${'z'.repeat(63)}example.com`, 2451cb0ef41Sopenharmony_ci hostname: `www.${'z'.repeat(63)}example.com`, 2461cb0ef41Sopenharmony_ci pathname: '/node', 2471cb0ef41Sopenharmony_ci path: '/node' 2481cb0ef41Sopenharmony_ci }, 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci // https://github.com/nodejs/node/issues/3361 2511cb0ef41Sopenharmony_ci 'file:///home/user': { 2521cb0ef41Sopenharmony_ci href: 'file:///home/user', 2531cb0ef41Sopenharmony_ci protocol: 'file', 2541cb0ef41Sopenharmony_ci pathname: '/home/user', 2551cb0ef41Sopenharmony_ci path: '/home/user' 2561cb0ef41Sopenharmony_ci }, 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci // surrogate in auth 2591cb0ef41Sopenharmony_ci 'http://%F0%9F%98%80@www.example.com/': { 2601cb0ef41Sopenharmony_ci href: 'http://%F0%9F%98%80@www.example.com/', 2611cb0ef41Sopenharmony_ci protocol: 'http:', 2621cb0ef41Sopenharmony_ci auth: '\uD83D\uDE00', 2631cb0ef41Sopenharmony_ci hostname: 'www.example.com', 2641cb0ef41Sopenharmony_ci pathname: '/' 2651cb0ef41Sopenharmony_ci } 2661cb0ef41Sopenharmony_ci}; 2671cb0ef41Sopenharmony_cifor (const u in formatTests) { 2681cb0ef41Sopenharmony_ci const expect = formatTests[u].href; 2691cb0ef41Sopenharmony_ci delete formatTests[u].href; 2701cb0ef41Sopenharmony_ci const actual = url.format(u); 2711cb0ef41Sopenharmony_ci const actualObj = url.format(formatTests[u]); 2721cb0ef41Sopenharmony_ci assert.strictEqual(actual, expect, 2731cb0ef41Sopenharmony_ci `wonky format(${u}) == ${expect}\nactual:${actual}`); 2741cb0ef41Sopenharmony_ci assert.strictEqual(actualObj, expect, 2751cb0ef41Sopenharmony_ci `wonky format(${JSON.stringify(formatTests[u])}) == ${ 2761cb0ef41Sopenharmony_ci expect}\nactual: ${actualObj}`); 2771cb0ef41Sopenharmony_ci} 278