1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | 'use strict';
|
25 |
|
26 | var punycode = require('punycode/');
|
27 |
|
28 | function Url() {
|
29 | this.protocol = null;
|
30 | this.slashes = null;
|
31 | this.auth = null;
|
32 | this.host = null;
|
33 | this.port = null;
|
34 | this.hostname = null;
|
35 | this.hash = null;
|
36 | this.search = null;
|
37 | this.query = null;
|
38 | this.pathname = null;
|
39 | this.path = null;
|
40 | this.href = null;
|
41 | }
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | var protocolPattern = /^([a-z0-9.+-]+:)/i,
|
50 | portPattern = /:[0-9]*$/,
|
51 |
|
52 |
|
53 | simplePathPattern = /^(\/\/?(?!\/)[^?\s]*)(\?[^\s]*)?$/,
|
54 |
|
55 | |
56 |
|
57 |
|
58 |
|
59 | delims = [
|
60 | '<', '>', '"', '`', ' ', '\r', '\n', '\t'
|
61 | ],
|
62 |
|
63 |
|
64 | unwise = [
|
65 | '{', '}', '|', '\\', '^', '`'
|
66 | ].concat(delims),
|
67 |
|
68 |
|
69 | autoEscape = ['\''].concat(unwise),
|
70 | |
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 | nonHostChars = [
|
77 | '%', '/', '?', ';', '#'
|
78 | ].concat(autoEscape),
|
79 | hostEndingChars = [
|
80 | '/', '?', '#'
|
81 | ],
|
82 | hostnameMaxLen = 255,
|
83 | hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
|
84 | hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
|
85 |
|
86 | unsafeProtocol = {
|
87 | javascript: true,
|
88 | 'javascript:': true
|
89 | },
|
90 |
|
91 | hostlessProtocol = {
|
92 | javascript: true,
|
93 | 'javascript:': true
|
94 | },
|
95 |
|
96 | slashedProtocol = {
|
97 | http: true,
|
98 | https: true,
|
99 | ftp: true,
|
100 | gopher: true,
|
101 | file: true,
|
102 | 'http:': true,
|
103 | 'https:': true,
|
104 | 'ftp:': true,
|
105 | 'gopher:': true,
|
106 | 'file:': true
|
107 | },
|
108 | querystring = require('qs');
|
109 |
|
110 | function urlParse(url, parseQueryString, slashesDenoteHost) {
|
111 | if (url && typeof url === 'object' && url instanceof Url) { return url; }
|
112 |
|
113 | var u = new Url();
|
114 | u.parse(url, parseQueryString, slashesDenoteHost);
|
115 | return u;
|
116 | }
|
117 |
|
118 | Url.prototype.parse = function (url, parseQueryString, slashesDenoteHost) {
|
119 | if (typeof url !== 'string') {
|
120 | throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
|
121 | }
|
122 |
|
123 | |
124 |
|
125 |
|
126 |
|
127 |
|
128 | var queryIndex = url.indexOf('?'),
|
129 | splitter = queryIndex !== -1 && queryIndex < url.indexOf('#') ? '?' : '#',
|
130 | uSplit = url.split(splitter),
|
131 | slashRegex = /\\/g;
|
132 | uSplit[0] = uSplit[0].replace(slashRegex, '/');
|
133 | url = uSplit.join(splitter);
|
134 |
|
135 | var rest = url;
|
136 |
|
137 | |
138 |
|
139 |
|
140 |
|
141 | rest = rest.trim();
|
142 |
|
143 | if (!slashesDenoteHost && url.split('#').length === 1) {
|
144 |
|
145 | var simplePath = simplePathPattern.exec(rest);
|
146 | if (simplePath) {
|
147 | this.path = rest;
|
148 | this.href = rest;
|
149 | this.pathname = simplePath[1];
|
150 | if (simplePath[2]) {
|
151 | this.search = simplePath[2];
|
152 | if (parseQueryString) {
|
153 | this.query = querystring.parse(this.search.substr(1));
|
154 | } else {
|
155 | this.query = this.search.substr(1);
|
156 | }
|
157 | } else if (parseQueryString) {
|
158 | this.search = '';
|
159 | this.query = {};
|
160 | }
|
161 | return this;
|
162 | }
|
163 | }
|
164 |
|
165 | var proto = protocolPattern.exec(rest);
|
166 | if (proto) {
|
167 | proto = proto[0];
|
168 | var lowerProto = proto.toLowerCase();
|
169 | this.protocol = lowerProto;
|
170 | rest = rest.substr(proto.length);
|
171 | }
|
172 |
|
173 | |
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 | if (slashesDenoteHost || proto || rest.match(/^\/\/[^@/]+@[^@/]+/)) {
|
180 | var slashes = rest.substr(0, 2) === '//';
|
181 | if (slashes && !(proto && hostlessProtocol[proto])) {
|
182 | rest = rest.substr(2);
|
183 | this.slashes = true;
|
184 | }
|
185 | }
|
186 |
|
187 | if (!hostlessProtocol[proto] && (slashes || (proto && !slashedProtocol[proto]))) {
|
188 |
|
189 | |
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 | |
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 | var hostEnd = -1;
|
210 | for (var i = 0; i < hostEndingChars.length; i++) {
|
211 | var hec = rest.indexOf(hostEndingChars[i]);
|
212 | if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; }
|
213 | }
|
214 |
|
215 | |
216 |
|
217 |
|
218 |
|
219 | var auth, atSign;
|
220 | if (hostEnd === -1) {
|
221 |
|
222 | atSign = rest.lastIndexOf('@');
|
223 | } else {
|
224 | |
225 |
|
226 |
|
227 |
|
228 | atSign = rest.lastIndexOf('@', hostEnd);
|
229 | }
|
230 |
|
231 | |
232 |
|
233 |
|
234 |
|
235 | if (atSign !== -1) {
|
236 | auth = rest.slice(0, atSign);
|
237 | rest = rest.slice(atSign + 1);
|
238 | this.auth = decodeURIComponent(auth);
|
239 | }
|
240 |
|
241 |
|
242 | hostEnd = -1;
|
243 | for (var i = 0; i < nonHostChars.length; i++) {
|
244 | var hec = rest.indexOf(nonHostChars[i]);
|
245 | if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; }
|
246 | }
|
247 |
|
248 | if (hostEnd === -1) { hostEnd = rest.length; }
|
249 |
|
250 | this.host = rest.slice(0, hostEnd);
|
251 | rest = rest.slice(hostEnd);
|
252 |
|
253 |
|
254 | this.parseHost();
|
255 |
|
256 | |
257 |
|
258 |
|
259 |
|
260 | this.hostname = this.hostname || '';
|
261 |
|
262 | |
263 |
|
264 |
|
265 |
|
266 | var ipv6Hostname = this.hostname[0] === '[' && this.hostname[this.hostname.length - 1] === ']';
|
267 |
|
268 |
|
269 | if (!ipv6Hostname) {
|
270 | var hostparts = this.hostname.split(/\./);
|
271 | for (var i = 0, l = hostparts.length; i < l; i++) {
|
272 | var part = hostparts[i];
|
273 | if (!part) { continue; }
|
274 | if (!part.match(hostnamePartPattern)) {
|
275 | var newpart = '';
|
276 | for (var j = 0, k = part.length; j < k; j++) {
|
277 | if (part.charCodeAt(j) > 127) {
|
278 | |
279 |
|
280 |
|
281 |
|
282 |
|
283 | newpart += 'x';
|
284 | } else {
|
285 | newpart += part[j];
|
286 | }
|
287 | }
|
288 |
|
289 | if (!newpart.match(hostnamePartPattern)) {
|
290 | var validParts = hostparts.slice(0, i);
|
291 | var notHost = hostparts.slice(i + 1);
|
292 | var bit = part.match(hostnamePartStart);
|
293 | if (bit) {
|
294 | validParts.push(bit[1]);
|
295 | notHost.unshift(bit[2]);
|
296 | }
|
297 | if (notHost.length) {
|
298 | rest = '/' + notHost.join('.') + rest;
|
299 | }
|
300 | this.hostname = validParts.join('.');
|
301 | break;
|
302 | }
|
303 | }
|
304 | }
|
305 | }
|
306 |
|
307 | if (this.hostname.length > hostnameMaxLen) {
|
308 | this.hostname = '';
|
309 | } else {
|
310 |
|
311 | this.hostname = this.hostname.toLowerCase();
|
312 | }
|
313 |
|
314 | if (!ipv6Hostname) {
|
315 | |
316 |
|
317 |
|
318 |
|
319 |
|
320 |
|
321 | this.hostname = punycode.toASCII(this.hostname);
|
322 | }
|
323 |
|
324 | var p = this.port ? ':' + this.port : '';
|
325 | var h = this.hostname || '';
|
326 | this.host = h + p;
|
327 | this.href += this.host;
|
328 |
|
329 | |
330 |
|
331 |
|
332 |
|
333 | if (ipv6Hostname) {
|
334 | this.hostname = this.hostname.substr(1, this.hostname.length - 2);
|
335 | if (rest[0] !== '/') {
|
336 | rest = '/' + rest;
|
337 | }
|
338 | }
|
339 | }
|
340 |
|
341 | |
342 |
|
343 |
|
344 |
|
345 | if (!unsafeProtocol[lowerProto]) {
|
346 |
|
347 | |
348 |
|
349 |
|
350 |
|
351 |
|
352 | for (var i = 0, l = autoEscape.length; i < l; i++) {
|
353 | var ae = autoEscape[i];
|
354 | if (rest.indexOf(ae) === -1) { continue; }
|
355 | var esc = encodeURIComponent(ae);
|
356 | if (esc === ae) {
|
357 | esc = escape(ae);
|
358 | }
|
359 | rest = rest.split(ae).join(esc);
|
360 | }
|
361 | }
|
362 |
|
363 |
|
364 | var hash = rest.indexOf('#');
|
365 | if (hash !== -1) {
|
366 |
|
367 | this.hash = rest.substr(hash);
|
368 | rest = rest.slice(0, hash);
|
369 | }
|
370 | var qm = rest.indexOf('?');
|
371 | if (qm !== -1) {
|
372 | this.search = rest.substr(qm);
|
373 | this.query = rest.substr(qm + 1);
|
374 | if (parseQueryString) {
|
375 | this.query = querystring.parse(this.query);
|
376 | }
|
377 | rest = rest.slice(0, qm);
|
378 | } else if (parseQueryString) {
|
379 |
|
380 | this.search = '';
|
381 | this.query = {};
|
382 | }
|
383 | if (rest) { this.pathname = rest; }
|
384 | if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) {
|
385 | this.pathname = '/';
|
386 | }
|
387 |
|
388 |
|
389 | if (this.pathname || this.search) {
|
390 | var p = this.pathname || '';
|
391 | var s = this.search || '';
|
392 | this.path = p + s;
|
393 | }
|
394 |
|
395 |
|
396 | this.href = this.format();
|
397 | return this;
|
398 | };
|
399 |
|
400 |
|
401 | function urlFormat(obj) {
|
402 | |
403 |
|
404 |
|
405 |
|
406 |
|
407 |
|
408 | if (typeof obj === 'string') { obj = urlParse(obj); }
|
409 | if (!(obj instanceof Url)) { return Url.prototype.format.call(obj); }
|
410 | return obj.format();
|
411 | }
|
412 |
|
413 | Url.prototype.format = function () {
|
414 | var auth = this.auth || '';
|
415 | if (auth) {
|
416 | auth = encodeURIComponent(auth);
|
417 | auth = auth.replace(/%3A/i, ':');
|
418 | auth += '@';
|
419 | }
|
420 |
|
421 | var protocol = this.protocol || '',
|
422 | pathname = this.pathname || '',
|
423 | hash = this.hash || '',
|
424 | host = false,
|
425 | query = '';
|
426 |
|
427 | if (this.host) {
|
428 | host = auth + this.host;
|
429 | } else if (this.hostname) {
|
430 | host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']');
|
431 | if (this.port) {
|
432 | host += ':' + this.port;
|
433 | }
|
434 | }
|
435 |
|
436 | if (this.query && typeof this.query === 'object' && Object.keys(this.query).length) {
|
437 | query = querystring.stringify(this.query, {
|
438 | arrayFormat: 'repeat',
|
439 | addQueryPrefix: false
|
440 | });
|
441 | }
|
442 |
|
443 | var search = this.search || (query && ('?' + query)) || '';
|
444 |
|
445 | if (protocol && protocol.substr(-1) !== ':') { protocol += ':'; }
|
446 |
|
447 | |
448 |
|
449 |
|
450 |
|
451 | if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) {
|
452 | host = '//' + (host || '');
|
453 | if (pathname && pathname.charAt(0) !== '/') { pathname = '/' + pathname; }
|
454 | } else if (!host) {
|
455 | host = '';
|
456 | }
|
457 |
|
458 | if (hash && hash.charAt(0) !== '#') { hash = '#' + hash; }
|
459 | if (search && search.charAt(0) !== '?') { search = '?' + search; }
|
460 |
|
461 | pathname = pathname.replace(/[?#]/g, function (match) {
|
462 | return encodeURIComponent(match);
|
463 | });
|
464 | search = search.replace('#', '%23');
|
465 |
|
466 | return protocol + host + pathname + search + hash;
|
467 | };
|
468 |
|
469 | function urlResolve(source, relative) {
|
470 | return urlParse(source, false, true).resolve(relative);
|
471 | }
|
472 |
|
473 | Url.prototype.resolve = function (relative) {
|
474 | return this.resolveObject(urlParse(relative, false, true)).format();
|
475 | };
|
476 |
|
477 | function urlResolveObject(source, relative) {
|
478 | if (!source) { return relative; }
|
479 | return urlParse(source, false, true).resolveObject(relative);
|
480 | }
|
481 |
|
482 | Url.prototype.resolveObject = function (relative) {
|
483 | if (typeof relative === 'string') {
|
484 | var rel = new Url();
|
485 | rel.parse(relative, false, true);
|
486 | relative = rel;
|
487 | }
|
488 |
|
489 | var result = new Url();
|
490 | var tkeys = Object.keys(this);
|
491 | for (var tk = 0; tk < tkeys.length; tk++) {
|
492 | var tkey = tkeys[tk];
|
493 | result[tkey] = this[tkey];
|
494 | }
|
495 |
|
496 | |
497 |
|
498 |
|
499 |
|
500 | result.hash = relative.hash;
|
501 |
|
502 |
|
503 | if (relative.href === '') {
|
504 | result.href = result.format();
|
505 | return result;
|
506 | }
|
507 |
|
508 |
|
509 | if (relative.slashes && !relative.protocol) {
|
510 |
|
511 | var rkeys = Object.keys(relative);
|
512 | for (var rk = 0; rk < rkeys.length; rk++) {
|
513 | var rkey = rkeys[rk];
|
514 | if (rkey !== 'protocol') { result[rkey] = relative[rkey]; }
|
515 | }
|
516 |
|
517 |
|
518 | if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) {
|
519 | result.pathname = '/';
|
520 | result.path = result.pathname;
|
521 | }
|
522 |
|
523 | result.href = result.format();
|
524 | return result;
|
525 | }
|
526 |
|
527 | if (relative.protocol && relative.protocol !== result.protocol) {
|
528 | |
529 |
|
530 |
|
531 |
|
532 |
|
533 |
|
534 |
|
535 |
|
536 |
|
537 |
|
538 | if (!slashedProtocol[relative.protocol]) {
|
539 | var keys = Object.keys(relative);
|
540 | for (var v = 0; v < keys.length; v++) {
|
541 | var k = keys[v];
|
542 | result[k] = relative[k];
|
543 | }
|
544 | result.href = result.format();
|
545 | return result;
|
546 | }
|
547 |
|
548 | result.protocol = relative.protocol;
|
549 | if (!relative.host && !hostlessProtocol[relative.protocol]) {
|
550 | var relPath = (relative.pathname || '').split('/');
|
551 | while (relPath.length && !(relative.host = relPath.shift())) { }
|
552 | if (!relative.host) { relative.host = ''; }
|
553 | if (!relative.hostname) { relative.hostname = ''; }
|
554 | if (relPath[0] !== '') { relPath.unshift(''); }
|
555 | if (relPath.length < 2) { relPath.unshift(''); }
|
556 | result.pathname = relPath.join('/');
|
557 | } else {
|
558 | result.pathname = relative.pathname;
|
559 | }
|
560 | result.search = relative.search;
|
561 | result.query = relative.query;
|
562 | result.host = relative.host || '';
|
563 | result.auth = relative.auth;
|
564 | result.hostname = relative.hostname || relative.host;
|
565 | result.port = relative.port;
|
566 |
|
567 | if (result.pathname || result.search) {
|
568 | var p = result.pathname || '';
|
569 | var s = result.search || '';
|
570 | result.path = p + s;
|
571 | }
|
572 | result.slashes = result.slashes || relative.slashes;
|
573 | result.href = result.format();
|
574 | return result;
|
575 | }
|
576 |
|
577 | var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/',
|
578 | isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/',
|
579 | mustEndAbs = isRelAbs || isSourceAbs || (result.host && relative.pathname),
|
580 | removeAllDots = mustEndAbs,
|
581 | srcPath = result.pathname && result.pathname.split('/') || [],
|
582 | relPath = relative.pathname && relative.pathname.split('/') || [],
|
583 | psychotic = result.protocol && !slashedProtocol[result.protocol];
|
584 |
|
585 | |
586 |
|
587 |
|
588 |
|
589 |
|
590 |
|
591 |
|
592 | if (psychotic) {
|
593 | result.hostname = '';
|
594 | result.port = null;
|
595 | if (result.host) {
|
596 | if (srcPath[0] === '') { srcPath[0] = result.host; } else { srcPath.unshift(result.host); }
|
597 | }
|
598 | result.host = '';
|
599 | if (relative.protocol) {
|
600 | relative.hostname = null;
|
601 | relative.port = null;
|
602 | if (relative.host) {
|
603 | if (relPath[0] === '') { relPath[0] = relative.host; } else { relPath.unshift(relative.host); }
|
604 | }
|
605 | relative.host = null;
|
606 | }
|
607 | mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
|
608 | }
|
609 |
|
610 | if (isRelAbs) {
|
611 |
|
612 | result.host = relative.host || relative.host === '' ? relative.host : result.host;
|
613 | result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname;
|
614 | result.search = relative.search;
|
615 | result.query = relative.query;
|
616 | srcPath = relPath;
|
617 |
|
618 | } else if (relPath.length) {
|
619 | |
620 |
|
621 |
|
622 |
|
623 | if (!srcPath) { srcPath = []; }
|
624 | srcPath.pop();
|
625 | srcPath = srcPath.concat(relPath);
|
626 | result.search = relative.search;
|
627 | result.query = relative.query;
|
628 | } else if (relative.search != null) {
|
629 | |
630 |
|
631 |
|
632 |
|
633 |
|
634 | if (psychotic) {
|
635 | result.host = srcPath.shift();
|
636 | result.hostname = result.host;
|
637 | |
638 |
|
639 |
|
640 |
|
641 |
|
642 | var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false;
|
643 | if (authInHost) {
|
644 | result.auth = authInHost.shift();
|
645 | result.hostname = authInHost.shift();
|
646 | result.host = result.hostname;
|
647 | }
|
648 | }
|
649 | result.search = relative.search;
|
650 | result.query = relative.query;
|
651 |
|
652 | if (result.pathname !== null || result.search !== null) {
|
653 | result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : '');
|
654 | }
|
655 | result.href = result.format();
|
656 | return result;
|
657 | }
|
658 |
|
659 | if (!srcPath.length) {
|
660 | |
661 |
|
662 |
|
663 |
|
664 | result.pathname = null;
|
665 |
|
666 | if (result.search) {
|
667 | result.path = '/' + result.search;
|
668 | } else {
|
669 | result.path = null;
|
670 | }
|
671 | result.href = result.format();
|
672 | return result;
|
673 | }
|
674 |
|
675 | |
676 |
|
677 |
|
678 |
|
679 |
|
680 | var last = srcPath.slice(-1)[0];
|
681 | var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === '';
|
682 |
|
683 | |
684 |
|
685 |
|
686 |
|
687 | var up = 0;
|
688 | for (var i = srcPath.length; i >= 0; i--) {
|
689 | last = srcPath[i];
|
690 | if (last === '.') {
|
691 | srcPath.splice(i, 1);
|
692 | } else if (last === '..') {
|
693 | srcPath.splice(i, 1);
|
694 | up++;
|
695 | } else if (up) {
|
696 | srcPath.splice(i, 1);
|
697 | up--;
|
698 | }
|
699 | }
|
700 |
|
701 |
|
702 | if (!mustEndAbs && !removeAllDots) {
|
703 | for (; up--; up) {
|
704 | srcPath.unshift('..');
|
705 | }
|
706 | }
|
707 |
|
708 | if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
|
709 | srcPath.unshift('');
|
710 | }
|
711 |
|
712 | if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
|
713 | srcPath.push('');
|
714 | }
|
715 |
|
716 | var isAbsolute = srcPath[0] === '' || (srcPath[0] && srcPath[0].charAt(0) === '/');
|
717 |
|
718 |
|
719 | if (psychotic) {
|
720 | result.hostname = isAbsolute ? '' : srcPath.length ? srcPath.shift() : '';
|
721 | result.host = result.hostname;
|
722 | |
723 |
|
724 |
|
725 |
|
726 |
|
727 | var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false;
|
728 | if (authInHost) {
|
729 | result.auth = authInHost.shift();
|
730 | result.hostname = authInHost.shift();
|
731 | result.host = result.hostname;
|
732 | }
|
733 | }
|
734 |
|
735 | mustEndAbs = mustEndAbs || (result.host && srcPath.length);
|
736 |
|
737 | if (mustEndAbs && !isAbsolute) {
|
738 | srcPath.unshift('');
|
739 | }
|
740 |
|
741 | if (srcPath.length > 0) {
|
742 | result.pathname = srcPath.join('/');
|
743 | } else {
|
744 | result.pathname = null;
|
745 | result.path = null;
|
746 | }
|
747 |
|
748 |
|
749 | if (result.pathname !== null || result.search !== null) {
|
750 | result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : '');
|
751 | }
|
752 | result.auth = relative.auth || result.auth;
|
753 | result.slashes = result.slashes || relative.slashes;
|
754 | result.href = result.format();
|
755 | return result;
|
756 | };
|
757 |
|
758 | Url.prototype.parseHost = function () {
|
759 | var host = this.host;
|
760 | var port = portPattern.exec(host);
|
761 | if (port) {
|
762 | port = port[0];
|
763 | if (port !== ':') {
|
764 | this.port = port.substr(1);
|
765 | }
|
766 | host = host.substr(0, host.length - port.length);
|
767 | }
|
768 | if (host) { this.hostname = host; }
|
769 | };
|
770 |
|
771 | exports.parse = urlParse;
|
772 | exports.resolve = urlResolve;
|
773 | exports.resolveObject = urlResolveObject;
|
774 | exports.format = urlFormat;
|
775 |
|
776 | exports.Url = Url;
|