|
| 1 | +/* eslint-disable max-len */ |
| 2 | +'use strict'; |
| 3 | +require('../common'); |
| 4 | +const assert = require('assert'); |
| 5 | +const url = require('url'); |
| 6 | + |
| 7 | +// some extra formatting tests, just to verify |
| 8 | +// that it'll format slightly wonky content to a valid url. |
| 9 | +const formatTests = { |
| 10 | + 'http://example.com?': { |
| 11 | + href: 'http://example.com/?', |
| 12 | + protocol: 'http:', |
| 13 | + slashes: true, |
| 14 | + host: 'example.com', |
| 15 | + hostname: 'example.com', |
| 16 | + search: '?', |
| 17 | + query: {}, |
| 18 | + pathname: '/' |
| 19 | + }, |
| 20 | + 'http://example.com?foo=bar#frag': { |
| 21 | + href: 'http://example.com/?foo=bar#frag', |
| 22 | + protocol: 'http:', |
| 23 | + host: 'example.com', |
| 24 | + hostname: 'example.com', |
| 25 | + hash: '#frag', |
| 26 | + search: '?foo=bar', |
| 27 | + query: 'foo=bar', |
| 28 | + pathname: '/' |
| 29 | + }, |
| 30 | + 'http://example.com?foo=@bar#frag': { |
| 31 | + href: 'http://example.com/?foo=@bar#frag', |
| 32 | + protocol: 'http:', |
| 33 | + host: 'example.com', |
| 34 | + hostname: 'example.com', |
| 35 | + hash: '#frag', |
| 36 | + search: '?foo=@bar', |
| 37 | + query: 'foo=@bar', |
| 38 | + pathname: '/' |
| 39 | + }, |
| 40 | + 'http://example.com?foo=/bar/#frag': { |
| 41 | + href: 'http://example.com/?foo=/bar/#frag', |
| 42 | + protocol: 'http:', |
| 43 | + host: 'example.com', |
| 44 | + hostname: 'example.com', |
| 45 | + hash: '#frag', |
| 46 | + search: '?foo=/bar/', |
| 47 | + query: 'foo=/bar/', |
| 48 | + pathname: '/' |
| 49 | + }, |
| 50 | + 'http://example.com?foo=?bar/#frag': { |
| 51 | + href: 'http://example.com/?foo=?bar/#frag', |
| 52 | + protocol: 'http:', |
| 53 | + host: 'example.com', |
| 54 | + hostname: 'example.com', |
| 55 | + hash: '#frag', |
| 56 | + search: '?foo=?bar/', |
| 57 | + query: 'foo=?bar/', |
| 58 | + pathname: '/' |
| 59 | + }, |
| 60 | + 'http://example.com#frag=?bar/#frag': { |
| 61 | + href: 'http://example.com/#frag=?bar/#frag', |
| 62 | + protocol: 'http:', |
| 63 | + host: 'example.com', |
| 64 | + hostname: 'example.com', |
| 65 | + hash: '#frag=?bar/#frag', |
| 66 | + pathname: '/' |
| 67 | + }, |
| 68 | + 'http://google.com" onload="alert(42)/': { |
| 69 | + href: 'http://google.com/%22%20onload=%22alert(42)/', |
| 70 | + protocol: 'http:', |
| 71 | + host: 'google.com', |
| 72 | + pathname: '/%22%20onload=%22alert(42)/' |
| 73 | + }, |
| 74 | + 'http://a.com/a/b/c?s#h': { |
| 75 | + href: 'http://a.com/a/b/c?s#h', |
| 76 | + protocol: 'http', |
| 77 | + host: 'a.com', |
| 78 | + pathname: 'a/b/c', |
| 79 | + hash: 'h', |
| 80 | + search: 's' |
| 81 | + }, |
| 82 | + |
| 83 | + |
| 84 | + protocol: 'xmpp:', |
| 85 | + host: 'jabber.org', |
| 86 | + auth: 'isaacschlueter', |
| 87 | + hostname: 'jabber.org' |
| 88 | + }, |
| 89 | + 'http://atpass:foo%[email protected]/': { |
| 90 | + href: 'http://atpass:foo%[email protected]/', |
| 91 | + auth: 'atpass:foo@bar', |
| 92 | + hostname: '127.0.0.1', |
| 93 | + protocol: 'http:', |
| 94 | + pathname: '/' |
| 95 | + }, |
| 96 | + 'http://atslash%2F%40:%2F%40@foo/': { |
| 97 | + href: 'http://atslash%2F%40:%2F%40@foo/', |
| 98 | + auth: 'atslash/@:/@', |
| 99 | + hostname: 'foo', |
| 100 | + protocol: 'http:', |
| 101 | + pathname: '/' |
| 102 | + }, |
| 103 | + 'svn+ssh://foo/bar': { |
| 104 | + href: 'svn+ssh://foo/bar', |
| 105 | + hostname: 'foo', |
| 106 | + protocol: 'svn+ssh:', |
| 107 | + pathname: '/bar', |
| 108 | + slashes: true |
| 109 | + }, |
| 110 | + 'dash-test://foo/bar': { |
| 111 | + href: 'dash-test://foo/bar', |
| 112 | + hostname: 'foo', |
| 113 | + protocol: 'dash-test:', |
| 114 | + pathname: '/bar', |
| 115 | + slashes: true |
| 116 | + }, |
| 117 | + 'dash-test:foo/bar': { |
| 118 | + href: 'dash-test:foo/bar', |
| 119 | + hostname: 'foo', |
| 120 | + protocol: 'dash-test:', |
| 121 | + pathname: '/bar' |
| 122 | + }, |
| 123 | + 'dot.test://foo/bar': { |
| 124 | + href: 'dot.test://foo/bar', |
| 125 | + hostname: 'foo', |
| 126 | + protocol: 'dot.test:', |
| 127 | + pathname: '/bar', |
| 128 | + slashes: true |
| 129 | + }, |
| 130 | + 'dot.test:foo/bar': { |
| 131 | + href: 'dot.test:foo/bar', |
| 132 | + hostname: 'foo', |
| 133 | + protocol: 'dot.test:', |
| 134 | + pathname: '/bar' |
| 135 | + }, |
| 136 | + // ipv6 support |
| 137 | + 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature': { |
| 138 | + href: 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature', |
| 139 | + protocol: 'coap:', |
| 140 | + auth: 'u:p', |
| 141 | + hostname: '::1', |
| 142 | + port: '61616', |
| 143 | + pathname: '/.well-known/r', |
| 144 | + search: 'n=Temperature' |
| 145 | + }, |
| 146 | + 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton': { |
| 147 | + href: 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton', |
| 148 | + protocol: 'coap', |
| 149 | + host: '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616', |
| 150 | + pathname: '/s/stopButton' |
| 151 | + }, |
| 152 | + |
| 153 | + // encode context-specific delimiters in path and query, but do not touch |
| 154 | + // other non-delimiter chars like `%`. |
| 155 | + // <https://github.com/joyent/node/issues/4082> |
| 156 | + |
| 157 | + // `#`,`?` in path |
| 158 | + '/path/to/%%23%3F+=&.txt?foo=theA1#bar': { |
| 159 | + href: '/path/to/%%23%3F+=&.txt?foo=theA1#bar', |
| 160 | + pathname: '/path/to/%#?+=&.txt', |
| 161 | + query: { |
| 162 | + foo: 'theA1' |
| 163 | + }, |
| 164 | + hash: '#bar' |
| 165 | + }, |
| 166 | + |
| 167 | + // `#`,`?` in path + `#` in query |
| 168 | + '/path/to/%%23%3F+=&.txt?foo=the%231#bar': { |
| 169 | + href: '/path/to/%%23%3F+=&.txt?foo=the%231#bar', |
| 170 | + pathname: '/path/to/%#?+=&.txt', |
| 171 | + query: { |
| 172 | + foo: 'the#1' |
| 173 | + }, |
| 174 | + hash: '#bar' |
| 175 | + }, |
| 176 | + |
| 177 | + // `?` and `#` in path and search |
| 178 | + 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag': { |
| 179 | + href: 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag', |
| 180 | + protocol: 'http:', |
| 181 | + hostname: 'ex.com', |
| 182 | + hash: '#frag', |
| 183 | + search: '?abc=the#1?&foo=bar', |
| 184 | + pathname: '/foo?100%m#r', |
| 185 | + }, |
| 186 | + |
| 187 | + // `?` and `#` in search only |
| 188 | + 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag': { |
| 189 | + href: 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag', |
| 190 | + protocol: 'http:', |
| 191 | + hostname: 'ex.com', |
| 192 | + hash: '#frag', |
| 193 | + search: '?abc=the#1?&foo=bar', |
| 194 | + pathname: '/fooA100%mBr', |
| 195 | + }, |
| 196 | + |
| 197 | + // multiple `#` in search |
| 198 | + 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag': { |
| 199 | + href: 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag', |
| 200 | + protocol: 'http:', |
| 201 | + slashes: true, |
| 202 | + host: 'example.com', |
| 203 | + hostname: 'example.com', |
| 204 | + hash: '#frag', |
| 205 | + search: '?foo=bar#1#2#3&abc=#4##5', |
| 206 | + query: {}, |
| 207 | + pathname: '/' |
| 208 | + }, |
| 209 | + |
| 210 | + // more than 255 characters in hostname which exceeds the limit |
| 211 | + [`http://${'a'.repeat(255)}.com/node`]: { |
| 212 | + href: 'http:///node', |
| 213 | + protocol: 'http:', |
| 214 | + slashes: true, |
| 215 | + host: '', |
| 216 | + hostname: '', |
| 217 | + pathname: '/node', |
| 218 | + path: '/node' |
| 219 | + }, |
| 220 | + |
| 221 | + // greater than or equal to 63 characters after `.` in hostname |
| 222 | + [`http://www.${'z'.repeat(63)}example.com/node`]: { |
| 223 | + href: `http://www.${'z'.repeat(63)}example.com/node`, |
| 224 | + protocol: 'http:', |
| 225 | + slashes: true, |
| 226 | + host: `www.${'z'.repeat(63)}example.com`, |
| 227 | + hostname: `www.${'z'.repeat(63)}example.com`, |
| 228 | + pathname: '/node', |
| 229 | + path: '/node' |
| 230 | + }, |
| 231 | + |
| 232 | + // https://github.com/nodejs/node/issues/3361 |
| 233 | + 'file:///home/user': { |
| 234 | + href: 'file:///home/user', |
| 235 | + protocol: 'file', |
| 236 | + pathname: '/home/user', |
| 237 | + path: '/home/user' |
| 238 | + } |
| 239 | +}; |
| 240 | +for (const u in formatTests) { |
| 241 | + const expect = formatTests[u].href; |
| 242 | + delete formatTests[u].href; |
| 243 | + const actual = url.format(u); |
| 244 | + const actualObj = url.format(formatTests[u]); |
| 245 | + assert.strictEqual(actual, expect, |
| 246 | + 'wonky format(' + u + ') == ' + expect + |
| 247 | + '\nactual:' + actual); |
| 248 | + assert.strictEqual(actualObj, expect, |
| 249 | + 'wonky format(' + JSON.stringify(formatTests[u]) + |
| 250 | + ') == ' + expect + |
| 251 | + '\nactual: ' + actualObj); |
| 252 | +} |
0 commit comments