@ -10,8 +10,8 @@ function importPunycode() {
const { toASCII } = importPunycode ( ) ;
const { StorageObject , hexTable } = require ( 'internal/querystring' ) ;
const internalUrl = require ( 'internal/url' ) ;
const encodeAuth = internalUrl . encodeAuth ;
exports . parse = urlParse ;
exports . resolve = urlResolve ;
exports . resolveObject = urlResolveObject ;
@ -76,12 +76,6 @@ const slashedProtocol = {
} ;
const querystring = require ( 'querystring' ) ;
// This constructor is used to store parsed query string values. Instantiating
// this is faster than explicitly calling `Object.create(null)` to get a
// "clean" empty object (tested with v8 v4.9).
function ParsedQueryString ( ) { }
ParsedQueryString . prototype = Object . create ( null ) ;
function urlParse ( url , parseQueryString , slashesDenoteHost ) {
if ( url instanceof Url ) return url ;
@ -190,7 +184,7 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
}
} else if ( parseQueryString ) {
this . search = '' ;
this . query = new ParsedQueryString ( ) ;
this . query = new StorageObject ( ) ;
}
return this ;
}
@ -380,7 +374,7 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
} else if ( parseQueryString ) {
// no query string, but parseQueryString still requested
this . search = '' ;
this . query = new ParsedQueryString ( ) ;
this . query = new StorageObject ( ) ;
}
var firstIdx = ( questionIdx !== - 1 &&
@ -948,3 +942,75 @@ function spliceOne(list, index) {
list [ i ] = list [ k ] ;
list . pop ( ) ;
}
// These characters do not need escaping:
// ! - . _ ~
// ' ( ) * :
// digits
// alpha (uppercase)
// alpha (lowercase)
const noEscapeAuth = [
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 0x00 - 0x0F
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 0x10 - 0x1F
0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , // 0x20 - 0x2F
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , // 0x30 - 0x3F
0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0x40 - 0x4F
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , // 0x50 - 0x5F
0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0x60 - 0x6F
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 0 // 0x70 - 0x7F
] ;
function encodeAuth ( str ) {
// faster encodeURIComponent alternative for encoding auth uri components
var out = '' ;
var lastPos = 0 ;
for ( var i = 0 ; i < str . length ; ++ i ) {
var c = str . charCodeAt ( i ) ;
// ASCII
if ( c < 0x80 ) {
if ( noEscapeAuth [ c ] === 1 )
continue ;
if ( lastPos < i )
out += str . slice ( lastPos , i ) ;
lastPos = i + 1 ;
out += hexTable [ c ] ;
continue ;
}
if ( lastPos < i )
out += str . slice ( lastPos , i ) ;
// Multi-byte characters ...
if ( c < 0x800 ) {
lastPos = i + 1 ;
out += hexTable [ 0xC0 | ( c >> 6 ) ] + hexTable [ 0x80 | ( c & 0x3F ) ] ;
continue ;
}
if ( c < 0xD800 || c >= 0xE000 ) {
lastPos = i + 1 ;
out += hexTable [ 0xE0 | ( c >> 12 ) ] +
hexTable [ 0x80 | ( ( c >> 6 ) & 0x3F ) ] +
hexTable [ 0x80 | ( c & 0x3F ) ] ;
continue ;
}
// Surrogate pair
++ i ;
var c2 ;
if ( i < str . length )
c2 = str . charCodeAt ( i ) & 0x3FF ;
else
c2 = 0 ;
lastPos = i + 1 ;
c = 0x10000 + ( ( ( c & 0x3FF ) << 10 ) | c2 ) ;
out += hexTable [ 0xF0 | ( c >> 18 ) ] +
hexTable [ 0x80 | ( ( c >> 12 ) & 0x3F ) ] +
hexTable [ 0x80 | ( ( c >> 6 ) & 0x3F ) ] +
hexTable [ 0x80 | ( c & 0x3F ) ] ;
}
if ( lastPos === 0 )
return str ;
if ( lastPos < str . length )
return out + str . slice ( lastPos ) ;
return out ;
}