Comparing version 0.11.0 to 0.11.1
{ | ||
"name": "url", | ||
"description": "The core `url` packaged standalone for use with Browserify.", | ||
"version": "0.11.0", | ||
"version": "0.11.1", | ||
"author": "defunctzombie", | ||
"dependencies": { | ||
"punycode": "1.3.2", | ||
"querystring": "0.2.0" | ||
"punycode": "^1.4.1", | ||
"qs": "^6.11.0" | ||
}, | ||
"main": "./url.js", | ||
"keywords": [ | ||
"parsing", | ||
"url", | ||
"analyze" | ||
], | ||
"devDependencies": { | ||
"assert": "1.1.1", | ||
"mocha": "1.18.2", | ||
"zuul": "3.3.0" | ||
"@ljharb/eslint-config": "^21.1.0", | ||
"acorn": "^8.8.2", | ||
"aud": "^2.0.2", | ||
"eslint": "=8.8.0", | ||
"mocha": "^3.5.3", | ||
"nyc": "^10.3.2", | ||
"zuul": "^3.12.0" | ||
}, | ||
"scripts": { | ||
"test": "mocha --ui qunit test.js && zuul -- test.js", | ||
"test-local": "zuul --local -- test.js" | ||
"lint": "eslint .", | ||
"pretest": "npm run lint", | ||
"tests-only": "nyc mocha", | ||
"test": "npm run tests-only", | ||
"posttest": "aud --production", | ||
"zuul": "zuul -- test/index.js", | ||
"test-local": "zuul --local -- test/index.js" | ||
}, | ||
@@ -19,0 +34,0 @@ "repository": { |
583
url.js
@@ -1,21 +0,23 @@ | ||
// Copyright Joyent, Inc. and other Node contributors. | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a | ||
// copy of this software and associated documentation files (the | ||
// "Software"), to deal in the Software without restriction, including | ||
// without limitation the rights to use, copy, modify, merge, publish, | ||
// distribute, sublicense, and/or sell copies of the Software, and to permit | ||
// persons to whom the Software is furnished to do so, subject to the | ||
// following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included | ||
// in all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
// USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
/* | ||
* Copyright Joyent, Inc. and other Node contributors. | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a | ||
* copy of this software and associated documentation files (the | ||
* "Software"), to deal in the Software without restriction, including | ||
* without limitation the rights to use, copy, modify, merge, publish, | ||
* distribute, sublicense, and/or sell copies of the Software, and to permit | ||
* persons to whom the Software is furnished to do so, subject to the | ||
* following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included | ||
* in all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
@@ -25,11 +27,3 @@ 'use strict'; | ||
var punycode = require('punycode'); | ||
var util = require('./util'); | ||
exports.parse = urlParse; | ||
exports.resolve = urlResolve; | ||
exports.resolveObject = urlResolveObject; | ||
exports.format = urlFormat; | ||
exports.Url = Url; | ||
function Url() { | ||
@@ -52,57 +46,71 @@ this.protocol = null; | ||
// define these here so at least they only have to be | ||
// compiled once on the first module load. | ||
/* | ||
* define these here so at least they only have to be | ||
* compiled once on the first module load. | ||
*/ | ||
var protocolPattern = /^([a-z0-9.+-]+:)/i, | ||
portPattern = /:[0-9]*$/, | ||
portPattern = /:[0-9]*$/, | ||
// Special case for a simple path URL | ||
simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/, | ||
// Special case for a simple path URL | ||
simplePathPattern = /^(\/\/?(?!\/)[^?\s]*)(\?[^\s]*)?$/, | ||
// RFC 2396: characters reserved for delimiting URLs. | ||
// We actually just auto-escape these. | ||
delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], | ||
/* | ||
* RFC 2396: characters reserved for delimiting URLs. | ||
* We actually just auto-escape these. | ||
*/ | ||
delims = [ | ||
'<', '>', '"', '`', ' ', '\r', '\n', '\t' | ||
], | ||
// RFC 2396: characters not allowed for various reasons. | ||
unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), | ||
// RFC 2396: characters not allowed for various reasons. | ||
unwise = [ | ||
'{', '}', '|', '\\', '^', '`' | ||
].concat(delims), | ||
// Allowed by RFCs, but cause of XSS attacks. Always escape these. | ||
autoEscape = ['\''].concat(unwise), | ||
// Characters that are never ever allowed in a hostname. | ||
// Note that any invalid chars are also handled, but these | ||
// are the ones that are *expected* to be seen, so we fast-path | ||
// them. | ||
nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), | ||
hostEndingChars = ['/', '?', '#'], | ||
hostnameMaxLen = 255, | ||
hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, | ||
hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, | ||
// protocols that can allow "unsafe" and "unwise" chars. | ||
unsafeProtocol = { | ||
'javascript': true, | ||
'javascript:': true | ||
}, | ||
// protocols that never have a hostname. | ||
hostlessProtocol = { | ||
'javascript': true, | ||
'javascript:': true | ||
}, | ||
// protocols that always contain a // bit. | ||
slashedProtocol = { | ||
'http': true, | ||
'https': true, | ||
'ftp': true, | ||
'gopher': true, | ||
'file': true, | ||
'http:': true, | ||
'https:': true, | ||
'ftp:': true, | ||
'gopher:': true, | ||
'file:': true | ||
}, | ||
querystring = require('querystring'); | ||
// Allowed by RFCs, but cause of XSS attacks. Always escape these. | ||
autoEscape = ['\''].concat(unwise), | ||
/* | ||
* Characters that are never ever allowed in a hostname. | ||
* Note that any invalid chars are also handled, but these | ||
* are the ones that are *expected* to be seen, so we fast-path | ||
* them. | ||
*/ | ||
nonHostChars = [ | ||
'%', '/', '?', ';', '#' | ||
].concat(autoEscape), | ||
hostEndingChars = [ | ||
'/', '?', '#' | ||
], | ||
hostnameMaxLen = 255, | ||
hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, | ||
hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, | ||
// protocols that can allow "unsafe" and "unwise" chars. | ||
unsafeProtocol = { | ||
javascript: true, | ||
'javascript:': true | ||
}, | ||
// protocols that never have a hostname. | ||
hostlessProtocol = { | ||
javascript: true, | ||
'javascript:': true | ||
}, | ||
// protocols that always contain a // bit. | ||
slashedProtocol = { | ||
http: true, | ||
https: true, | ||
ftp: true, | ||
gopher: true, | ||
file: true, | ||
'http:': true, | ||
'https:': true, | ||
'ftp:': true, | ||
'gopher:': true, | ||
'file:': true | ||
}, | ||
querystring = require('qs'); | ||
function urlParse(url, parseQueryString, slashesDenoteHost) { | ||
if (url && util.isObject(url) && url instanceof Url) return url; | ||
if (url && typeof url === 'object' && url instanceof Url) { return url; } | ||
var u = new Url; | ||
var u = new Url(); | ||
u.parse(url, parseQueryString, slashesDenoteHost); | ||
@@ -112,15 +120,16 @@ return u; | ||
Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { | ||
if (!util.isString(url)) { | ||
Url.prototype.parse = function (url, parseQueryString, slashesDenoteHost) { | ||
if (typeof url !== 'string') { | ||
throw new TypeError("Parameter 'url' must be a string, not " + typeof url); | ||
} | ||
// Copy chrome, IE, opera backslash-handling behavior. | ||
// Back slashes before the query string get converted to forward slashes | ||
// See: https://code.google.com/p/chromium/issues/detail?id=25916 | ||
/* | ||
* Copy chrome, IE, opera backslash-handling behavior. | ||
* Back slashes before the query string get converted to forward slashes | ||
* See: https://code.google.com/p/chromium/issues/detail?id=25916 | ||
*/ | ||
var queryIndex = url.indexOf('?'), | ||
splitter = | ||
(queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#', | ||
uSplit = url.split(splitter), | ||
slashRegex = /\\/g; | ||
splitter = queryIndex !== -1 && queryIndex < url.indexOf('#') ? '?' : '#', | ||
uSplit = url.split(splitter), | ||
slashRegex = /\\/g; | ||
uSplit[0] = uSplit[0].replace(slashRegex, '/'); | ||
@@ -131,4 +140,6 @@ url = uSplit.join(splitter); | ||
// trim before proceeding. | ||
// This is to support parse stuff like " http://foo.com \n" | ||
/* | ||
* trim before proceeding. | ||
* This is to support parse stuff like " http://foo.com \n" | ||
*/ | ||
rest = rest.trim(); | ||
@@ -166,7 +177,9 @@ | ||
// figure out if it's got a host | ||
// user@server is *always* interpreted as a hostname, and url | ||
// resolution will treat //foo/bar as host=foo,path=bar because that's | ||
// how the browser resolves relative URLs. | ||
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { | ||
/* | ||
* figure out if it's got a host | ||
* user@server is *always* interpreted as a hostname, and url | ||
* resolution will treat //foo/bar as host=foo,path=bar because that's | ||
* how the browser resolves relative URLs. | ||
*/ | ||
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@/]+@[^@/]+/)) { | ||
var slashes = rest.substr(0, 2) === '//'; | ||
@@ -179,19 +192,22 @@ if (slashes && !(proto && hostlessProtocol[proto])) { | ||
if (!hostlessProtocol[proto] && | ||
(slashes || (proto && !slashedProtocol[proto]))) { | ||
if (!hostlessProtocol[proto] && (slashes || (proto && !slashedProtocol[proto]))) { | ||
// there's a hostname. | ||
// the first instance of /, ?, ;, or # ends the host. | ||
// | ||
// If there is an @ in the hostname, then non-host chars *are* allowed | ||
// to the left of the last @ sign, unless some host-ending character | ||
// comes *before* the @-sign. | ||
// URLs are obnoxious. | ||
// | ||
// ex: | ||
// http://a@b@c/ => user:a@b host:c | ||
// http://a@b?@c => user:a host:c path:/?@c | ||
/* | ||
* there's a hostname. | ||
* the first instance of /, ?, ;, or # ends the host. | ||
* | ||
* If there is an @ in the hostname, then non-host chars *are* allowed | ||
* to the left of the last @ sign, unless some host-ending character | ||
* comes *before* the @-sign. | ||
* URLs are obnoxious. | ||
* | ||
* ex: | ||
* http://a@b@c/ => user:a@b host:c | ||
* http://a@b?@c => user:a host:c path:/?@c | ||
*/ | ||
// v0.12 TODO(isaacs): This is not quite how Chrome does things. | ||
// Review our test case against browsers more comprehensively. | ||
/* | ||
* v0.12 TODO(isaacs): This is not quite how Chrome does things. | ||
* Review our test case against browsers more comprehensively. | ||
*/ | ||
@@ -202,8 +218,9 @@ // find the first instance of any hostEndingChars | ||
var hec = rest.indexOf(hostEndingChars[i]); | ||
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) | ||
hostEnd = hec; | ||
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; } | ||
} | ||
// at this point, either we have an explicit point where the | ||
// auth portion cannot go past, or the last @ char is the decider. | ||
/* | ||
* at this point, either we have an explicit point where the | ||
* auth portion cannot go past, or the last @ char is the decider. | ||
*/ | ||
var auth, atSign; | ||
@@ -214,9 +231,13 @@ if (hostEnd === -1) { | ||
} else { | ||
// atSign must be in auth portion. | ||
// http://a@b/c@d => host:b auth:a path:/c@d | ||
/* | ||
* atSign must be in auth portion. | ||
* http://a@b/c@d => host:b auth:a path:/c@d | ||
*/ | ||
atSign = rest.lastIndexOf('@', hostEnd); | ||
} | ||
// Now we have a portion which is definitely the auth. | ||
// Pull that off. | ||
/* | ||
* Now we have a portion which is definitely the auth. | ||
* Pull that off. | ||
*/ | ||
if (atSign !== -1) { | ||
@@ -232,8 +253,6 @@ auth = rest.slice(0, atSign); | ||
var hec = rest.indexOf(nonHostChars[i]); | ||
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) | ||
hostEnd = hec; | ||
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; } | ||
} | ||
// if we still have not hit it, then the entire thing is a host. | ||
if (hostEnd === -1) | ||
hostEnd = rest.length; | ||
if (hostEnd === -1) { hostEnd = rest.length; } | ||
@@ -246,10 +265,13 @@ this.host = rest.slice(0, hostEnd); | ||
// we've indicated that there is a hostname, | ||
// so even if it's empty, it has to be present. | ||
/* | ||
* we've indicated that there is a hostname, | ||
* so even if it's empty, it has to be present. | ||
*/ | ||
this.hostname = this.hostname || ''; | ||
// if hostname begins with [ and ends with ] | ||
// assume that it's an IPv6 address. | ||
var ipv6Hostname = this.hostname[0] === '[' && | ||
this.hostname[this.hostname.length - 1] === ']'; | ||
/* | ||
* if hostname begins with [ and ends with ] | ||
* assume that it's an IPv6 address. | ||
*/ | ||
var ipv6Hostname = this.hostname[0] === '[' && this.hostname[this.hostname.length - 1] === ']'; | ||
@@ -261,3 +283,3 @@ // validate a little. | ||
var part = hostparts[i]; | ||
if (!part) continue; | ||
if (!part) { continue; } | ||
if (!part.match(hostnamePartPattern)) { | ||
@@ -267,5 +289,7 @@ var newpart = ''; | ||
if (part.charCodeAt(j) > 127) { | ||
// we replace non-ASCII char with a temporary placeholder | ||
// we need this to make sure size of hostname is not | ||
// broken by replacing non-ASCII by nothing | ||
/* | ||
* we replace non-ASCII char with a temporary placeholder | ||
* we need this to make sure size of hostname is not | ||
* broken by replacing non-ASCII by nothing | ||
*/ | ||
newpart += 'x'; | ||
@@ -303,6 +327,8 @@ } else { | ||
if (!ipv6Hostname) { | ||
// IDNA Support: Returns a punycoded representation of "domain". | ||
// It only converts parts of the domain name that | ||
// have non-ASCII characters, i.e. it doesn't matter if | ||
// you call it with a domain that already is ASCII-only. | ||
/* | ||
* IDNA Support: Returns a punycoded representation of "domain". | ||
* It only converts parts of the domain name that | ||
* have non-ASCII characters, i.e. it doesn't matter if | ||
* you call it with a domain that already is ASCII-only. | ||
*/ | ||
this.hostname = punycode.toASCII(this.hostname); | ||
@@ -316,4 +342,6 @@ } | ||
// strip [ and ] from the hostname | ||
// the host field still retains them, though | ||
/* | ||
* strip [ and ] from the hostname | ||
* the host field still retains them, though | ||
*/ | ||
if (ipv6Hostname) { | ||
@@ -327,13 +355,16 @@ this.hostname = this.hostname.substr(1, this.hostname.length - 2); | ||
// now rest is set to the post-host stuff. | ||
// chop off any delim chars. | ||
/* | ||
* now rest is set to the post-host stuff. | ||
* chop off any delim chars. | ||
*/ | ||
if (!unsafeProtocol[lowerProto]) { | ||
// First, make 100% sure that any "autoEscape" chars get | ||
// escaped, even if encodeURIComponent doesn't think they | ||
// need to be. | ||
/* | ||
* First, make 100% sure that any "autoEscape" chars get | ||
* escaped, even if encodeURIComponent doesn't think they | ||
* need to be. | ||
*/ | ||
for (var i = 0, l = autoEscape.length; i < l; i++) { | ||
var ae = autoEscape[i]; | ||
if (rest.indexOf(ae) === -1) | ||
continue; | ||
if (rest.indexOf(ae) === -1) { continue; } | ||
var esc = encodeURIComponent(ae); | ||
@@ -347,3 +378,2 @@ if (esc === ae) { | ||
// chop off from the tail first. | ||
@@ -369,9 +399,8 @@ var hash = rest.indexOf('#'); | ||
} | ||
if (rest) this.pathname = rest; | ||
if (slashedProtocol[lowerProto] && | ||
this.hostname && !this.pathname) { | ||
if (rest) { this.pathname = rest; } | ||
if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { | ||
this.pathname = '/'; | ||
} | ||
//to support http.request | ||
// to support http.request | ||
if (this.pathname || this.search) { | ||
@@ -390,12 +419,14 @@ var p = this.pathname || ''; | ||
function urlFormat(obj) { | ||
// ensure it's an object, and not a string url. | ||
// If it's an obj, this is a no-op. | ||
// this way, you can call url_format() on strings | ||
// to clean up potentially wonky urls. | ||
if (util.isString(obj)) obj = urlParse(obj); | ||
if (!(obj instanceof Url)) return Url.prototype.format.call(obj); | ||
/* | ||
* ensure it's an object, and not a string url. | ||
* If it's an obj, this is a no-op. | ||
* this way, you can call url_format() on strings | ||
* to clean up potentially wonky urls. | ||
*/ | ||
if (typeof obj === 'string') { obj = urlParse(obj); } | ||
if (!(obj instanceof Url)) { return Url.prototype.format.call(obj); } | ||
return obj.format(); | ||
} | ||
Url.prototype.format = function() { | ||
Url.prototype.format = function () { | ||
var auth = this.auth || ''; | ||
@@ -409,6 +440,6 @@ if (auth) { | ||
var protocol = this.protocol || '', | ||
pathname = this.pathname || '', | ||
hash = this.hash || '', | ||
host = false, | ||
query = ''; | ||
pathname = this.pathname || '', | ||
hash = this.hash || '', | ||
host = false, | ||
query = ''; | ||
@@ -418,5 +449,3 @@ if (this.host) { | ||
} else if (this.hostname) { | ||
host = auth + (this.hostname.indexOf(':') === -1 ? | ||
this.hostname : | ||
'[' + this.hostname + ']'); | ||
host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); | ||
if (this.port) { | ||
@@ -427,5 +456,3 @@ host += ':' + this.port; | ||
if (this.query && | ||
util.isObject(this.query) && | ||
Object.keys(this.query).length) { | ||
if (this.query && typeof this.query === 'object' && Object.keys(this.query).length) { | ||
query = querystring.stringify(this.query); | ||
@@ -436,10 +463,11 @@ } | ||
if (protocol && protocol.substr(-1) !== ':') protocol += ':'; | ||
if (protocol && protocol.substr(-1) !== ':') { protocol += ':'; } | ||
// only the slashedProtocols get the //. Not mailto:, xmpp:, etc. | ||
// unless they had them to begin with. | ||
if (this.slashes || | ||
(!protocol || slashedProtocol[protocol]) && host !== false) { | ||
/* | ||
* only the slashedProtocols get the //. Not mailto:, xmpp:, etc. | ||
* unless they had them to begin with. | ||
*/ | ||
if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { | ||
host = '//' + (host || ''); | ||
if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; | ||
if (pathname && pathname.charAt(0) !== '/') { pathname = '/' + pathname; } | ||
} else if (!host) { | ||
@@ -449,6 +477,6 @@ host = ''; | ||
if (hash && hash.charAt(0) !== '#') hash = '#' + hash; | ||
if (search && search.charAt(0) !== '?') search = '?' + search; | ||
if (hash && hash.charAt(0) !== '#') { hash = '#' + hash; } | ||
if (search && search.charAt(0) !== '?') { search = '?' + search; } | ||
pathname = pathname.replace(/[?#]/g, function(match) { | ||
pathname = pathname.replace(/[?#]/g, function (match) { | ||
return encodeURIComponent(match); | ||
@@ -465,3 +493,3 @@ }); | ||
Url.prototype.resolve = function(relative) { | ||
Url.prototype.resolve = function (relative) { | ||
return this.resolveObject(urlParse(relative, false, true)).format(); | ||
@@ -471,8 +499,8 @@ }; | ||
function urlResolveObject(source, relative) { | ||
if (!source) return relative; | ||
if (!source) { return relative; } | ||
return urlParse(source, false, true).resolveObject(relative); | ||
} | ||
Url.prototype.resolveObject = function(relative) { | ||
if (util.isString(relative)) { | ||
Url.prototype.resolveObject = function (relative) { | ||
if (typeof relative === 'string') { | ||
var rel = new Url(); | ||
@@ -490,4 +518,6 @@ rel.parse(relative, false, true); | ||
// hash is always overridden, no matter what. | ||
// even href="" will remove it. | ||
/* | ||
* hash is always overridden, no matter what. | ||
* even href="" will remove it. | ||
*/ | ||
result.hash = relative.hash; | ||
@@ -507,10 +537,9 @@ | ||
var rkey = rkeys[rk]; | ||
if (rkey !== 'protocol') | ||
result[rkey] = relative[rkey]; | ||
if (rkey !== 'protocol') { result[rkey] = relative[rkey]; } | ||
} | ||
//urlParse appends trailing / to urls like http://www.example.com | ||
if (slashedProtocol[result.protocol] && | ||
result.hostname && !result.pathname) { | ||
result.path = result.pathname = '/'; | ||
// urlParse appends trailing / to urls like http://www.example.com | ||
if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { | ||
result.pathname = '/'; | ||
result.path = result.pathname; | ||
} | ||
@@ -523,10 +552,12 @@ | ||
if (relative.protocol && relative.protocol !== result.protocol) { | ||
// if it's a known url protocol, then changing | ||
// the protocol does weird things | ||
// first, if it's not file:, then we MUST have a host, | ||
// and if there was a path | ||
// to begin with, then we MUST have a path. | ||
// if it is file:, then the host is dropped, | ||
// because that's known to be hostless. | ||
// anything else is assumed to be absolute. | ||
/* | ||
* if it's a known url protocol, then changing | ||
* the protocol does weird things | ||
* first, if it's not file:, then we MUST have a host, | ||
* and if there was a path | ||
* to begin with, then we MUST have a path. | ||
* if it is file:, then the host is dropped, | ||
* because that's known to be hostless. | ||
* anything else is assumed to be absolute. | ||
*/ | ||
if (!slashedProtocol[relative.protocol]) { | ||
@@ -545,7 +576,7 @@ var keys = Object.keys(relative); | ||
var relPath = (relative.pathname || '').split('/'); | ||
while (relPath.length && !(relative.host = relPath.shift())); | ||
if (!relative.host) relative.host = ''; | ||
if (!relative.hostname) relative.hostname = ''; | ||
if (relPath[0] !== '') relPath.unshift(''); | ||
if (relPath.length < 2) relPath.unshift(''); | ||
while (relPath.length && !(relative.host = relPath.shift())) { } | ||
if (!relative.host) { relative.host = ''; } | ||
if (!relative.hostname) { relative.hostname = ''; } | ||
if (relPath[0] !== '') { relPath.unshift(''); } | ||
if (relPath.length < 2) { relPath.unshift(''); } | ||
result.pathname = relPath.join('/'); | ||
@@ -572,19 +603,17 @@ } else { | ||
var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), | ||
isRelAbs = ( | ||
relative.host || | ||
relative.pathname && relative.pathname.charAt(0) === '/' | ||
), | ||
mustEndAbs = (isRelAbs || isSourceAbs || | ||
(result.host && relative.pathname)), | ||
removeAllDots = mustEndAbs, | ||
srcPath = result.pathname && result.pathname.split('/') || [], | ||
relPath = relative.pathname && relative.pathname.split('/') || [], | ||
psychotic = result.protocol && !slashedProtocol[result.protocol]; | ||
var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/', | ||
isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/', | ||
mustEndAbs = isRelAbs || isSourceAbs || (result.host && relative.pathname), | ||
removeAllDots = mustEndAbs, | ||
srcPath = result.pathname && result.pathname.split('/') || [], | ||
relPath = relative.pathname && relative.pathname.split('/') || [], | ||
psychotic = result.protocol && !slashedProtocol[result.protocol]; | ||
// if the url is a non-slashed url, then relative | ||
// links like ../.. should be able | ||
// to crawl up to the hostname, as well. This is strange. | ||
// result.protocol has already been set by now. | ||
// Later on, put the first path part into the host field. | ||
/* | ||
* if the url is a non-slashed url, then relative | ||
* links like ../.. should be able | ||
* to crawl up to the hostname, as well. This is strange. | ||
* result.protocol has already been set by now. | ||
* Later on, put the first path part into the host field. | ||
*/ | ||
if (psychotic) { | ||
@@ -594,4 +623,3 @@ result.hostname = ''; | ||
if (result.host) { | ||
if (srcPath[0] === '') srcPath[0] = result.host; | ||
else srcPath.unshift(result.host); | ||
if (srcPath[0] === '') { srcPath[0] = result.host; } else { srcPath.unshift(result.host); } | ||
} | ||
@@ -603,4 +631,3 @@ result.host = ''; | ||
if (relative.host) { | ||
if (relPath[0] === '') relPath[0] = relative.host; | ||
else relPath.unshift(relative.host); | ||
if (relPath[0] === '') { relPath[0] = relative.host; } else { relPath.unshift(relative.host); } | ||
} | ||
@@ -614,6 +641,4 @@ relative.host = null; | ||
// it's absolute. | ||
result.host = (relative.host || relative.host === '') ? | ||
relative.host : result.host; | ||
result.hostname = (relative.hostname || relative.hostname === '') ? | ||
relative.hostname : result.hostname; | ||
result.host = relative.host || relative.host === '' ? relative.host : result.host; | ||
result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname; | ||
result.search = relative.search; | ||
@@ -624,5 +649,7 @@ result.query = relative.query; | ||
} else if (relPath.length) { | ||
// it's relative | ||
// throw away the existing file, and take the new path instead. | ||
if (!srcPath) srcPath = []; | ||
/* | ||
* it's relative | ||
* throw away the existing file, and take the new path instead. | ||
*/ | ||
if (!srcPath) { srcPath = []; } | ||
srcPath.pop(); | ||
@@ -632,16 +659,21 @@ srcPath = srcPath.concat(relPath); | ||
result.query = relative.query; | ||
} else if (!util.isNullOrUndefined(relative.search)) { | ||
// just pull out the search. | ||
// like href='?foo'. | ||
// Put this after the other two cases because it simplifies the booleans | ||
} else if (relative.search != null) { | ||
/* | ||
* just pull out the search. | ||
* like href='?foo'. | ||
* Put this after the other two cases because it simplifies the booleans | ||
*/ | ||
if (psychotic) { | ||
result.hostname = result.host = srcPath.shift(); | ||
//occationaly the auth can get stuck only in host | ||
//this especially happens in cases like | ||
//url.resolveObject('mailto:local1@domain1', 'local2@domain2') | ||
var authInHost = result.host && result.host.indexOf('@') > 0 ? | ||
result.host.split('@') : false; | ||
result.host = srcPath.shift(); | ||
result.hostname = result.host; | ||
/* | ||
* occationaly the auth can get stuck only in host | ||
* this especially happens in cases like | ||
* url.resolveObject('mailto:local1@domain1', 'local2@domain2') | ||
*/ | ||
var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; | ||
if (authInHost) { | ||
result.auth = authInHost.shift(); | ||
result.host = result.hostname = authInHost.shift(); | ||
result.hostname = authInHost.shift(); | ||
result.host = result.hostname; | ||
} | ||
@@ -651,6 +683,5 @@ } | ||
result.query = relative.query; | ||
//to support http.request | ||
if (!util.isNull(result.pathname) || !util.isNull(result.search)) { | ||
result.path = (result.pathname ? result.pathname : '') + | ||
(result.search ? result.search : ''); | ||
// to support http.request | ||
if (result.pathname !== null || result.search !== null) { | ||
result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); | ||
} | ||
@@ -662,6 +693,8 @@ result.href = result.format(); | ||
if (!srcPath.length) { | ||
// no path at all. easy. | ||
// we've already handled the other stuff above. | ||
/* | ||
* no path at all. easy. | ||
* we've already handled the other stuff above. | ||
*/ | ||
result.pathname = null; | ||
//to support http.request | ||
// to support http.request | ||
if (result.search) { | ||
@@ -676,12 +709,14 @@ result.path = '/' + result.search; | ||
// if a url ENDs in . or .., then it must get a trailing slash. | ||
// however, if it ends in anything else non-slashy, | ||
// then it must NOT get a trailing slash. | ||
/* | ||
* if a url ENDs in . or .., then it must get a trailing slash. | ||
* however, if it ends in anything else non-slashy, | ||
* then it must NOT get a trailing slash. | ||
*/ | ||
var last = srcPath.slice(-1)[0]; | ||
var hasTrailingSlash = ( | ||
(result.host || relative.host || srcPath.length > 1) && | ||
(last === '.' || last === '..') || last === ''); | ||
var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''; | ||
// strip single dots, resolve double dots to parent dir | ||
// if the path tries to go above the root, `up` ends up > 0 | ||
/* | ||
* strip single dots, resolve double dots to parent dir | ||
* if the path tries to go above the root, `up` ends up > 0 | ||
*/ | ||
var up = 0; | ||
@@ -708,4 +743,3 @@ for (var i = srcPath.length; i >= 0; i--) { | ||
if (mustEndAbs && srcPath[0] !== '' && | ||
(!srcPath[0] || srcPath[0].charAt(0) !== '/')) { | ||
if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { | ||
srcPath.unshift(''); | ||
@@ -718,17 +752,18 @@ } | ||
var isAbsolute = srcPath[0] === '' || | ||
(srcPath[0] && srcPath[0].charAt(0) === '/'); | ||
var isAbsolute = srcPath[0] === '' || (srcPath[0] && srcPath[0].charAt(0) === '/'); | ||
// put the host back | ||
if (psychotic) { | ||
result.hostname = result.host = isAbsolute ? '' : | ||
srcPath.length ? srcPath.shift() : ''; | ||
//occationaly the auth can get stuck only in host | ||
//this especially happens in cases like | ||
//url.resolveObject('mailto:local1@domain1', 'local2@domain2') | ||
var authInHost = result.host && result.host.indexOf('@') > 0 ? | ||
result.host.split('@') : false; | ||
result.hostname = isAbsolute ? '' : srcPath.length ? srcPath.shift() : ''; | ||
result.host = result.hostname; | ||
/* | ||
* occationaly the auth can get stuck only in host | ||
* this especially happens in cases like | ||
* url.resolveObject('mailto:local1@domain1', 'local2@domain2') | ||
*/ | ||
var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; | ||
if (authInHost) { | ||
result.auth = authInHost.shift(); | ||
result.host = result.hostname = authInHost.shift(); | ||
result.hostname = authInHost.shift(); | ||
result.host = result.hostname; | ||
} | ||
@@ -743,13 +778,12 @@ } | ||
if (!srcPath.length) { | ||
if (srcPath.length > 0) { | ||
result.pathname = srcPath.join('/'); | ||
} else { | ||
result.pathname = null; | ||
result.path = null; | ||
} else { | ||
result.pathname = srcPath.join('/'); | ||
} | ||
//to support request.http | ||
if (!util.isNull(result.pathname) || !util.isNull(result.search)) { | ||
result.path = (result.pathname ? result.pathname : '') + | ||
(result.search ? result.search : ''); | ||
// to support request.http | ||
if (result.pathname !== null || result.search !== null) { | ||
result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); | ||
} | ||
@@ -762,3 +796,3 @@ result.auth = relative.auth || result.auth; | ||
Url.prototype.parseHost = function() { | ||
Url.prototype.parseHost = function () { | ||
var host = this.host; | ||
@@ -773,3 +807,10 @@ var port = portPattern.exec(host); | ||
} | ||
if (host) this.hostname = host; | ||
if (host) { this.hostname = host; } | ||
}; | ||
exports.parse = urlParse; | ||
exports.resolve = urlResolve; | ||
exports.resolveObject = urlResolveObject; | ||
exports.format = urlFormat; | ||
exports.Url = Url; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
77547
2622
1
7
2
+ Addedqs@^6.11.0
+ Addedcall-bind@1.0.7(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedgopd@1.0.1(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.0.3(transitive)
+ Addedhas-symbols@1.0.3(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedobject-inspect@1.13.2(transitive)
+ Addedpunycode@1.4.1(transitive)
+ Addedqs@6.13.0(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedside-channel@1.0.6(transitive)
- Removedquerystring@0.2.0
- Removedpunycode@1.3.2(transitive)
- Removedquerystring@0.2.0(transitive)
Updatedpunycode@^1.4.1