@ -42,6 +42,7 @@ var protocolPattern = /^([a-z0-9]+:)/i,
// them.
nonHostChars = [ '%' , '/' , '?' , ';' , '#' ]
. concat ( unwise ) . concat ( autoEscape ) ,
nonAuthChars = [ '/' , '@' , '?' , '#' ] . concat ( delims ) ,
hostnameMaxLen = 255 ,
hostnamePartPattern = /^[a-zA-Z0-9][a-z0-9A-Z-]{0,62}$/ ,
hostnamePartStart = /^([a-zA-Z0-9][a-z0-9A-Z-]{0,62})(.*)$/ ,
@ -123,12 +124,37 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
// there's a hostname.
// the first instance of /, ?, ;, or # ends the host.
// don't enforce full RFC correctness, just be unstupid about it.
// If there is an @ in the hostname, then non-host chars *are* allowed
// to the left of the first @ sign, unless some non-auth character
// comes *before* the @-sign.
// URLs are obnoxious.
var atSign = rest . indexOf ( '@' ) ;
if ( atSign !== - 1 ) {
// there *may be* an auth
var hasAuth = true ;
for ( var i = 0 , l = nonAuthChars . length ; i < l ; i ++ ) {
var index = rest . indexOf ( nonAuthChars [ i ] ) ;
if ( index !== - 1 && index < atSign ) {
// not a valid auth. Something like http://foo.com/bar@baz/
hasAuth = false ;
break ;
}
}
if ( hasAuth ) {
// pluck off the auth portion.
out . auth = rest . substr ( 0 , atSign ) ;
rest = rest . substr ( atSign + 1 ) ;
}
}
var firstNonHost = - 1 ;
for ( var i = 0 , l = nonHostChars . length ; i < l ; i ++ ) {
var index = rest . indexOf ( nonHostChars [ i ] ) ;
if ( index !== - 1 &&
( firstNonHost < 0 || index < firstNonHost ) ) firstNonHost = index ;
}
if ( firstNonHost !== - 1 ) {
out . host = rest . substr ( 0 , firstNonHost ) ;
rest = rest . substr ( firstNonHost ) ;
@ -137,8 +163,9 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
rest = '' ;
}
// pull out the auth and port.
// pull out port.
var p = parseHost ( out . host ) ;
if ( out . auth ) out . host = out . auth + '@' + out . host ;
var keys = Object . keys ( p ) ;
for ( var i = 0 , l = keys . length ; i < l ; i ++ ) {
var key = keys [ i ] ;
@ -250,10 +277,19 @@ function urlFormat(obj) {
// to clean up potentially wonky urls.
if ( typeof ( obj ) === 'string' ) obj = urlParse ( obj ) ;
var auth = obj . auth ;
if ( auth ) {
auth = auth . split ( '@' ) . join ( '%40' ) ;
for ( var i = 0 , l = nonAuthChars . length ; i < l ; i ++ ) {
var nAC = nonAuthChars [ i ] ;
auth = auth . split ( nAC ) . join ( encodeURIComponent ( nAC ) ) ;
}
}
var protocol = obj . protocol || '' ,
host = ( obj . host !== undefined ) ? obj . host :
obj . hostname !== undefined ? (
( obj . auth ? obj . auth + '@' : '' ) +
( auth ? auth + '@' : '' ) +
obj . hostname +
( obj . port ? ':' + obj . port : '' )
) :
@ -476,11 +512,6 @@ function urlResolveObject(source, relative) {
function parseHost ( host ) {
var out = { } ;
var at = host . indexOf ( '@' ) ;
if ( at !== - 1 ) {
out . auth = host . substr ( 0 , at ) ;
host = host . substr ( at + 1 ) ; // drop the @
}
var port = portPattern . exec ( host ) ;
if ( port ) {
port = port [ 0 ] ;