@@ -331,7 +331,7 @@ interface ErrorWithCode extends Error {
331331}
332332
333333interface InternalConnectionConfig {
334- server : string ;
334+ server : undefined | string ;
335335 authentication : DefaultAuthentication | NtlmAuthentication | AzureActiveDirectoryPasswordAuthentication | AzureActiveDirectoryMsiAppServiceAuthentication | AzureActiveDirectoryMsiVmAuthentication | AzureActiveDirectoryAccessTokenAuthentication | AzureActiveDirectoryServicePrincipalSecret | AzureActiveDirectoryDefaultAuthentication ;
336336 options : InternalConnectionOptions ;
337337}
@@ -1061,7 +1061,7 @@ class Connection extends EventEmitter {
10611061 throw new TypeError ( 'The "config" argument is required and must be of type Object.' ) ;
10621062 }
10631063
1064- if ( typeof config . server !== 'string' ) {
1064+ if ( typeof config . server !== 'string' && ! config . options ! . connector ) {
10651065 throw new TypeError ( 'The "config.server" property is required and must be of type string.' ) ;
10661066 }
10671067
@@ -1352,8 +1352,15 @@ class Connection extends EventEmitter {
13521352 if ( typeof config . options . connector !== 'function' ) {
13531353 throw new TypeError ( 'The "config.options.connector" property must be a function.' ) ;
13541354 }
1355+ if ( config . server ) {
1356+ throw new Error ( 'Server and connector are mutually exclusive, but ' + config . server + ' and a connector function were provided' ) ;
1357+ }
1358+ if ( config . options . port ) {
1359+ throw new Error ( 'Port and connector are mutually exclusive, but ' + config . options . port + ' and a connector function were provided' ) ;
1360+ }
13551361
13561362 this . config . options . connector = config . options . connector ;
1363+ this . config . options . port = undefined ;
13571364 }
13581365
13591366 if ( config . options . cryptoCredentialsDetails !== undefined ) {
@@ -1917,7 +1924,10 @@ class Connection extends EventEmitter {
19171924 initialiseConnection ( ) {
19181925 const signal = this . createConnectTimer ( ) ;
19191926
1920- if ( this . config . options . port ) {
1927+ if ( this . config . options . connector ) {
1928+ // port and multiSubnetFailover are not used when using a custom connector
1929+ return this . connectOnPort ( 0 , false , signal , this . config . options . connector ) ;
1930+ } else if ( this . config . options . port ) {
19211931 return this . connectOnPort ( this . config . options . port , this . config . options . multiSubnetFailover , signal , this . config . options . connector ) ;
19221932 } else {
19231933 return instanceLookup ( {
@@ -1990,7 +2000,7 @@ class Connection extends EventEmitter {
19902000 return new TokenStreamParser ( message , this . debug , handler , this . config . options ) ;
19912001 }
19922002
1993- socketHandlingForSendPreLogin ( socket : net . Socket ) {
2003+ socketHandlingForSendPreLogin ( socket : net . Socket , customConnector : boolean ) {
19942004 socket . on ( 'error' , ( error ) => { this . socketError ( error ) ; } ) ;
19952005 socket . on ( 'close' , ( ) => { this . socketClose ( ) ; } ) ;
19962006 socket . on ( 'end' , ( ) => { this . socketEnd ( ) ; } ) ;
@@ -2002,19 +2012,24 @@ class Connection extends EventEmitter {
20022012 this . socket = socket ;
20032013
20042014 this . closed = false ;
2005- this . debug . log ( 'connected to ' + this . config . server + ':' + this . config . options . port ) ;
2015+ const message =
2016+ 'connected to ' + this . config . server + ':' + this . config . options . port ;
2017+ const customConnectorMessage =
2018+ 'connected via custom connector' ;
2019+ this . debug . log ( customConnector ? customConnectorMessage : message ) ;
20062020
20072021 this . sendPreLogin ( ) ;
20082022 this . transitionTo ( this . STATE . SENT_PRELOGIN ) ;
20092023 }
20102024
20112025 wrapWithTls ( socket : net . Socket ) : Promise < tls . TLSSocket > {
20122026 return new Promise ( ( resolve , reject ) => {
2027+ const server = String ( this . config . server ) ;
20132028 const secureContext = tls . createSecureContext ( this . secureContextOptions ) ;
20142029 // If connect to an ip address directly,
20152030 // need to set the servername to an empty string
20162031 // if the user has not given a servername explicitly
2017- const serverName = ! net . isIP ( this . config . server ) ? this . config . server : '' ;
2032+ const serverName = ! net . isIP ( server ) ? server : '' ;
20182033 const encryptOptions = {
20192034 host : this . config . server ,
20202035 socket : socket ,
@@ -2034,7 +2049,7 @@ class Connection extends EventEmitter {
20342049
20352050 connectOnPort ( port : number , multiSubnetFailover : boolean , signal : AbortSignal , customConnector ?: ( ) => Promise < net . Socket > ) {
20362051 const connectOpts = {
2037- host : this . routingData ? this . routingData . server : this . config . server ,
2052+ host : this . routingData ? this . routingData . server : String ( this . config . server ) ,
20382053 port : this . routingData ? this . routingData . port : port ,
20392054 localAddress : this . config . options . localAddress
20402055 } ;
@@ -2055,7 +2070,7 @@ class Connection extends EventEmitter {
20552070 }
20562071 }
20572072
2058- this . socketHandlingForSendPreLogin ( socket ) ;
2073+ this . socketHandlingForSendPreLogin ( socket , Boolean ( customConnector ) ) ;
20592074 } ) ( ) . catch ( ( err ) => {
20602075 this . clearConnectTimer ( ) ;
20612076
@@ -2137,8 +2152,10 @@ class Connection extends EventEmitter {
21372152 // otherwise, leave the message empty.
21382153 const routingMessage = this . routingData ? ` (redirected from ${ this . config . server } ${ hostPostfix } )` : '' ;
21392154 const message = `Failed to connect to ${ server } ${ port } ${ routingMessage } in ${ this . config . options . connectTimeout } ms` ;
2140- this . debug . log ( message ) ;
2141- this . emit ( 'connect' , new ConnectionError ( message , 'ETIMEOUT' ) ) ;
2155+ const customConnectorMessage = `Failed to connect using custom connector in ${ this . config . options . connectTimeout } ms` ;
2156+ const errMessage = this . config . options . connector ? customConnectorMessage : message ;
2157+ this . debug . log ( errMessage ) ;
2158+ this . emit ( 'connect' , new ConnectionError ( errMessage , 'ETIMEOUT' ) ) ;
21422159 this . connectTimer = undefined ;
21432160 this . dispatchEvent ( 'connectTimeout' ) ;
21442161 }
@@ -2273,8 +2290,10 @@ class Connection extends EventEmitter {
22732290 // otherwise, leave the message empty.
22742291 const routingMessage = this . routingData ? ` (redirected from ${ this . config . server } ${ hostPostfix } )` : '' ;
22752292 const message = `Failed to connect to ${ server } ${ port } ${ routingMessage } - ${ error . message } ` ;
2276- this . debug . log ( message ) ;
2277- this . emit ( 'connect' , new ConnectionError ( message , 'ESOCKET' ) ) ;
2293+ const customConnectorMessage = `Failed to connect using custom connector - ${ error . message } ` ;
2294+ const errMessage = this . config . options . connector ? customConnectorMessage : message ;
2295+ this . debug . log ( errMessage ) ;
2296+ this . emit ( 'connect' , new ConnectionError ( errMessage , 'ESOCKET' ) ) ;
22782297 } else {
22792298 const message = `Connection lost - ${ error . message } ` ;
22802299 this . debug . log ( message ) ;
@@ -2299,15 +2318,21 @@ class Connection extends EventEmitter {
22992318 * @private
23002319 */
23012320 socketClose ( ) {
2302- this . debug . log ( 'connection to ' + this . config . server + ':' + this . config . options . port + ' closed' ) ;
2321+ const message = 'connection to ' + this . config . server + ':' + this . config . options . port + ' closed' ;
2322+ const customConnectorMessage = 'connection closed' ;
2323+ this . debug . log ( this . config . options . connector ? customConnectorMessage : message ) ;
23032324 if ( this . state === this . STATE . REROUTING ) {
2304- this . debug . log ( 'Rerouting to ' + this . routingData ! . server + ':' + this . routingData ! . port ) ;
2325+ const message = 'Rerouting to ' + this . routingData ! . server + ':' + this . routingData ! . port ;
2326+ const customConnectorMessage = 'Rerouting' ;
2327+ this . debug . log ( this . config . options . connector ? customConnectorMessage : message ) ;
23052328
23062329 this . dispatchEvent ( 'reconnect' ) ;
23072330 } else if ( this . state === this . STATE . TRANSIENT_FAILURE_RETRY ) {
23082331 const server = this . routingData ? this . routingData . server : this . config . server ;
23092332 const port = this . routingData ? this . routingData . port : this . config . options . port ;
2310- this . debug . log ( 'Retry after transient failure connecting to ' + server + ':' + port ) ;
2333+ const message = 'Retry after transient failure connecting to ' + server + ':' + port ;
2334+ const customConnectorMessage = 'Retry after transient failure connecting' ;
2335+ this . debug . log ( this . config . options . connector ? customConnectorMessage : message ) ;
23112336
23122337 this . dispatchEvent ( 'retry' ) ;
23132338 } else {
@@ -3254,7 +3279,8 @@ Connection.prototype.STATE = {
32543279
32553280 try {
32563281 this . transitionTo ( this . STATE . SENT_TLSSSLNEGOTIATION ) ;
3257- await this . messageIo . startTls ( this . secureContextOptions , this . config . options . serverName ? this . config . options . serverName : this . routingData ?. server ?? this . config . server , this . config . options . trustServerCertificate ) ;
3282+ const serverName = this . config . options . serverName ? this . config . options . serverName : String ( this . routingData ?. server ?? this . config . server ) ;
3283+ await this . messageIo . startTls ( this . secureContextOptions , serverName , this . config . options . trustServerCertificate ) ;
32583284 } catch ( err : any ) {
32593285 return this . socketError ( err ) ;
32603286 }
0 commit comments