@@ -24,7 +24,6 @@ var cluster;
2424const errnoException = util . _errnoException ;
2525const exceptionWithHostPort = util . _exceptionWithHostPort ;
2626const isLegalPort = internalNet . isLegalPort ;
27- const assertPort = internalNet . assertPort ;
2827
2928function noop ( ) { }
3029
@@ -60,46 +59,60 @@ exports.createServer = function(options, connectionListener) {
6059// connect(path, [cb]);
6160//
6261exports . connect = exports . createConnection = function ( ) {
63- var args = new Array ( arguments . length ) ;
62+ const args = new Array ( arguments . length ) ;
6463 for ( var i = 0 ; i < arguments . length ; i ++ )
6564 args [ i ] = arguments [ i ] ;
66- args = normalizeArgs ( args ) ;
67- debug ( 'createConnection' , args ) ;
68- var s = new Socket ( args [ 0 ] ) ;
65+ // TODO(joyeecheung): use destructuring when V8 is fast enough
66+ const normalized = normalizeArgs ( args ) ;
67+ const options = normalized [ 0 ] ;
68+ const cb = normalized [ 1 ] ;
69+ debug ( 'createConnection' , normalized ) ;
70+ const socket = new Socket ( options ) ;
6971
70- if ( args [ 0 ] . timeout ) {
71- s . setTimeout ( args [ 0 ] . timeout ) ;
72+ if ( options . timeout ) {
73+ socket . setTimeout ( options . timeout ) ;
7274 }
7375
74- return Socket . prototype . connect . apply ( s , args ) ;
76+ return Socket . prototype . connect . call ( socket , options , cb ) ;
7577} ;
7678
77- // Returns an array [options, cb], where cb can be null.
78- // It is the same as the argument of Socket.prototype.connect().
79- // This is used by Server.prototype.listen() and Socket.prototype.connect().
80- function normalizeArgs ( args ) {
81- var options = { } ;
8279
80+ // Returns an array [options, cb], where options is an object,
81+ // cb is either a funciton or null.
82+ // Used to normalize arguments of Socket.prototype.connect() and
83+ // Server.prototype.listen(). Possible combinations of paramters:
84+ // (options[...][, cb])
85+ // (path[...][, cb])
86+ // ([port][, host][...][, cb])
87+ // For Socket.prototype.connect(), the [...] part is ignored
88+ // For Server.prototype.listen(), the [...] part is [, backlog]
89+ // but will not be handled here (handled in listen())
90+ function normalizeArgs ( args ) {
8391 if ( args . length === 0 ) {
84- return [ options ] ;
85- } else if ( args [ 0 ] !== null && typeof args [ 0 ] === 'object' ) {
86- // connect(options, [cb])
87- options = args [ 0 ] ;
88- } else if ( isPipeName ( args [ 0 ] ) ) {
89- // connect(path, [cb]);
90- options . path = args [ 0 ] ;
92+ return [ { } , null ] ;
93+ }
94+
95+ const arg0 = args [ 0 ] ;
96+ var options = { } ;
97+ if ( typeof arg0 === 'object' && arg0 !== null ) {
98+ // (options[...][, cb])
99+ options = arg0 ;
100+ } else if ( isPipeName ( arg0 ) ) {
101+ // (path[...][, cb])
102+ options . path = arg0 ;
91103 } else {
92- // connect( port, [ host], [ cb])
93- options . port = args [ 0 ] ;
104+ // ([ port][, host][...][, cb])
105+ options . port = arg0 ;
94106 if ( args . length > 1 && typeof args [ 1 ] === 'string' ) {
95107 options . host = args [ 1 ] ;
96108 }
97109 }
98110
99111 var cb = args [ args . length - 1 ] ;
100112 if ( typeof cb !== 'function' )
101- cb = null ;
102- return [ options , cb ] ;
113+ return [ options , null ] ;
114+ else
115+ return [ options , cb ] ;
103116}
104117exports . _normalizeArgs = normalizeArgs ;
105118
@@ -892,13 +905,16 @@ Socket.prototype.connect = function(options, cb) {
892905
893906 if ( options === null || typeof options !== 'object' ) {
894907 // Old API:
895- // connect(port, [ host], [ cb])
896- // connect(path, [ cb]);
897- var args = new Array ( arguments . length ) ;
908+ // connect(port[, host][, cb])
909+ // connect(path[, cb]);
910+ const args = new Array ( arguments . length ) ;
898911 for ( var i = 0 ; i < arguments . length ; i ++ )
899912 args [ i ] = arguments [ i ] ;
900- args = normalizeArgs ( args ) ;
901- return Socket . prototype . connect . apply ( this , args ) ;
913+ const normalized = normalizeArgs ( args ) ;
914+ const normalizedOptions = normalized [ 0 ] ;
915+ const normalizedCb = normalized [ 1 ] ;
916+ return Socket . prototype . connect . call ( this ,
917+ normalizedOptions , normalizedCb ) ;
902918 }
903919
904920 if ( this . destroyed ) {
@@ -923,7 +939,7 @@ Socket.prototype.connect = function(options, cb) {
923939 initSocketHandle ( this ) ;
924940 }
925941
926- if ( typeof cb === 'function' ) {
942+ if ( cb !== null ) {
927943 this . once ( 'connect' , cb ) ;
928944 }
929945
@@ -1334,57 +1350,73 @@ function listen(self, address, port, addressType, backlog, fd, exclusive) {
13341350
13351351
13361352Server . prototype . listen = function ( ) {
1337- var args = new Array ( arguments . length ) ;
1353+ const args = new Array ( arguments . length ) ;
13381354 for ( var i = 0 ; i < arguments . length ; i ++ )
13391355 args [ i ] = arguments [ i ] ;
1340- var [ options , cb ] = normalizeArgs ( args ) ;
1356+ // TODO(joyeecheung): use destructuring when V8 is fast enough
1357+ const normalized = normalizeArgs ( args ) ;
1358+ var options = normalized [ 0 ] ;
1359+ const cb = normalized [ 1 ] ;
13411360
1342- if ( typeof cb === 'function' ) {
1361+ var hasCallback = ( cb !== null ) ;
1362+ if ( hasCallback ) {
13431363 this . once ( 'listening' , cb ) ;
13441364 }
1345-
1346- if ( args . length === 0 || typeof args [ 0 ] === 'function' ) {
1347- // Bind to a random port.
1348- options . port = 0 ;
1349- }
1350-
1351- // The third optional argument is the backlog size.
1352- // When the ip is omitted it can be the second argument.
1353- var backlog = toNumber ( args . length > 1 && args [ 1 ] ) ||
1354- toNumber ( args . length > 2 && args [ 2 ] ) ;
1365+ const backlogFromArgs =
1366+ // (handle, backlog) or (path, backlog) or (port, backlog)
1367+ toNumber ( args . length > 1 && args [ 1 ] ) ||
1368+ toNumber ( args . length > 2 && args [ 2 ] ) ; // (port, host, backlog)
13551369
13561370 options = options . _handle || options . handle || options ;
1357-
1371+ // (handle[, backlog][, cb]) where handle is an object with a handle
13581372 if ( options instanceof TCP ) {
13591373 this . _handle = options ;
1360- listen ( this , null , - 1 , - 1 , backlog ) ;
1361- } else if ( typeof options . fd === 'number' && options . fd >= 0 ) {
1362- listen ( this , null , null , null , backlog , options . fd ) ;
1363- } else {
1364- backlog = options . backlog || backlog ;
1365-
1366- if ( typeof options . port === 'number' || typeof options . port === 'string' ||
1367- ( typeof options . port === 'undefined' && 'port' in options ) ) {
1368- // Undefined is interpreted as zero (random port) for consistency
1369- // with net.connect().
1370- assertPort ( options . port ) ;
1371- if ( options . host ) {
1372- lookupAndListen ( this , options . port | 0 , options . host , backlog ,
1373- options . exclusive ) ;
1374- } else {
1375- listen ( this , null , options . port | 0 , 4 , backlog , undefined ,
1376- options . exclusive ) ;
1377- }
1378- } else if ( options . path && isPipeName ( options . path ) ) {
1379- // UNIX socket or Windows pipe.
1380- const pipeName = this . _pipeName = options . path ;
1381- listen ( this , pipeName , - 1 , - 1 , backlog , undefined , options . exclusive ) ;
1382- } else {
1383- throw new Error ( 'Invalid listen argument: ' + options ) ;
1374+ listen ( this , null , - 1 , - 1 , backlogFromArgs ) ;
1375+ return this ;
1376+ }
1377+ // (handle[, backlog][, cb]) where handle is an object with a fd
1378+ if ( typeof options . fd === 'number' && options . fd >= 0 ) {
1379+ listen ( this , null , null , null , backlogFromArgs , options . fd ) ;
1380+ return this ;
1381+ }
1382+
1383+ // ([port][, host][, backlog][, cb]) where port is omitted,
1384+ // that is, listen() or listen(cb),
1385+ // or (options[, cb]) where options.port is explicitly set as undefined,
1386+ // bind to an arbitrary unused port
1387+ if ( args . length === 0 || typeof args [ 0 ] === 'function' ||
1388+ ( typeof options . port === 'undefined' && 'port' in options ) ) {
1389+ options . port = 0 ;
1390+ }
1391+ // ([port][, host][, backlog][, cb]) where port is specified
1392+ // or (options[, cb]) where options.port is specified
1393+ // or if options.port is normalized as 0 before
1394+ if ( typeof options . port === 'number' || typeof options . port === 'string' ) {
1395+ if ( ! isLegalPort ( options . port ) ) {
1396+ throw new RangeError ( '"port" argument must be >= 0 and < 65536' ) ;
1397+ }
1398+ const backlog = options . backlog || backlogFromArgs ;
1399+ // start TCP server listening on host:port
1400+ if ( options . host ) {
1401+ lookupAndListen ( this , options . port | 0 , options . host , backlog ,
1402+ options . exclusive ) ;
1403+ } else { // Undefined host, listens on unspecified address
1404+ listen ( this , null , options . port | 0 , 4 , // addressType will be ignored
1405+ backlog , undefined , options . exclusive ) ;
13841406 }
1407+ return this ;
13851408 }
13861409
1387- return this ;
1410+ // (path[, backlog][, cb]) or (options[, cb])
1411+ // where path or options.path is a UNIX domain socket or Windows pipe
1412+ if ( options . path && isPipeName ( options . path ) ) {
1413+ const pipeName = this . _pipeName = options . path ;
1414+ const backlog = options . backlog || backlogFromArgs ;
1415+ listen ( this , pipeName , - 1 , - 1 , backlog , undefined , options . exclusive ) ;
1416+ return this ;
1417+ }
1418+
1419+ throw new Error ( 'Invalid listen argument: ' + options ) ;
13881420} ;
13891421
13901422function lookupAndListen ( self , port , address , backlog , exclusive ) {
0 commit comments