@ -24,7 +24,6 @@ var protocolPattern = /^([a-z0-9]+:)/,
'gopher:' : true ,
'gopher:' : true ,
'file:' : true
'file:' : true
} ,
} ,
path = require ( 'path' ) , // internal module, guaranteed to be loaded already.
querystring = require ( 'querystring' ) ;
querystring = require ( 'querystring' ) ;
function urlParse ( url , parseQueryString , slashesDenoteHost ) {
function urlParse ( url , parseQueryString , slashesDenoteHost ) {
@ -280,7 +279,6 @@ function urlResolveObject(source, relative) {
return source ;
return source ;
}
}
// resolve dots.
// if a url ENDs in . or .., then it must 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,
// however, if it ends in anything else non-slashy,
// then it must NOT get a trailing slash.
// then it must NOT get a trailing slash.
@ -289,27 +287,34 @@ function urlResolveObject(source, relative) {
( source . host || relative . host ) && ( last === '.' || last === '..' ) ||
( source . host || relative . host ) && ( last === '.' || last === '..' ) ||
last === '' ) ;
last === '' ) ;
// Figure out if this has to end up as an absolute url,
// strip single dots, resolve double dots to parent dir
// or should continue to be relative.
// if the path tries to go above the root, `up` ends up > 0
srcPath = path . normalizeArray ( srcPath , true ) ;
var up = 0 ;
if ( srcPath . length === 1 && srcPath [ 0 ] === '.' ) srcPath = [ ] ;
for ( var i = srcPath . length ; i >= 0 ; i -- ) {
if ( mustEndAbs || removeAllDots ) {
last = srcPath [ i ] ;
// all dots must go.
if ( last == '.' ) {
var dirs = [ ] ;
srcPath . splice ( i , 1 ) ;
srcPath . forEach ( function ( dir , i ) {
} else if ( last === '..' ) {
if ( dir === '..' ) {
srcPath . splice ( i , 1 ) ;
dirs . pop ( ) ;
up ++ ;
} else if ( dir !== '.' ) {
} else if ( up ) {
dirs . push ( dir ) ;
srcPath . splice ( i , 1 ) ;
}
up -- ;
} ) ;
}
}
if ( mustEndAbs && dirs [ 0 ] !== '' &&
// if the path is allowed to go above the root, restore leading ..s
( ! dirs [ 0 ] || dirs [ 0 ] . charAt ( 0 ) !== '/' ) ) {
if ( ! mustEndAbs && ! removeAllDots ) {
dirs . unshift ( '' ) ;
for ( ; up -- ; up ) {
srcPath . unshift ( '..' ) ;
}
}
srcPath = dirs ;
}
}
if ( mustEndAbs && srcPath [ 0 ] !== '' &&
( ! srcPath [ 0 ] || srcPath [ 0 ] . charAt ( 0 ) !== '/' ) ) {
srcPath . unshift ( '' ) ;
}
if ( hasTrailingSlash && ( srcPath . join ( '/' ) . substr ( - 1 ) !== '/' ) ) {
if ( hasTrailingSlash && ( srcPath . join ( '/' ) . substr ( - 1 ) !== '/' ) ) {
srcPath . push ( '' ) ;
srcPath . push ( '' ) ;
}
}