@@ -32,7 +32,7 @@ const ThinResultSetImpl = require('./resultSet.js');
3232const ThinLobImpl = require ( "./lob.js" ) ;
3333const Protocol = require ( "./protocol/protocol.js" ) ;
3434const { BaseBuffer } = require ( './protocol/buffer.js' ) ;
35- const { NetworkSession :nsi , getConnectionInfo } = require ( "./sqlnet/networkSession.js" ) ;
35+ const { NetworkSession :nsi } = require ( "./sqlnet/networkSession.js" ) ;
3636const { Statement } = require ( "./statement" ) ;
3737const thinUtil = require ( './util' ) ;
3838const sqlNetConstants = require ( './sqlnet/constants.js' ) ;
@@ -49,6 +49,8 @@ const finalizationRegistry = new global.FinalizationRegistry((heldValue) => {
4949class TDSBuffer extends BaseBuffer {
5050}
5151
52+ const connectionCookies = new Map ( ) ;
53+
5254class ThinConnectionImpl extends ConnectionImpl {
5355
5456 /**
@@ -457,6 +459,26 @@ class ThinConnectionImpl extends ConnectionImpl {
457459 return ( this . _pool ) ? true : false ;
458460 }
459461
462+ //---------------------------------------------------------------------------
463+ // getConnectionCookieByUUID()
464+ //
465+ // It fetches from map which keeps keyname as UUID+ServiceName.
466+ // UUID identifies the CDB instance and ServiceName identifies the
467+ // entity within a PDB which uniquely identifies a pdb instance.
468+ //---------------------------------------------------------------------------
469+ getConnectionCookieByUUID ( uuid ) {
470+ let cookie ;
471+ if ( uuid ) {
472+ const key = uuid + ( ( this . serviceName ) ? this . serviceName : this . sid ) ;
473+ cookie = connectionCookies . get ( key ) ;
474+ if ( ! cookie ) {
475+ cookie = { } ;
476+ connectionCookies . set ( key , cookie ) ;
477+ }
478+ }
479+ return cookie ;
480+ }
481+
460482 /**
461483 *
462484 * @param {object } params Configuration of the connection
@@ -495,6 +517,7 @@ class ThinConnectionImpl extends ConnectionImpl {
495517 this . _clientInfoModified = false ;
496518 this . _module = "" ;
497519 this . _moduleModified = false ;
520+ this . _drcpEnabled = false ;
498521 this . serviceName = '' ;
499522 this . remoteAddress = '' ;
500523 this . comboKey = null ; // used in changePassword API
@@ -503,11 +526,21 @@ class ThinConnectionImpl extends ConnectionImpl {
503526 finalizationRegistry . register ( this , this . nscon ) ;
504527 await this . nscon . connect ( params ) ;
505528
506- this . _connInfo = ( this . isPooled ( ) ) ? params . _connInfo . map ( ( x ) => x ) :
507- await getConnectionInfo ( params ) ;
508- this . _drcpEnabled = String ( this . _connInfo [ 0 ] ) . toLowerCase ( ) === 'pooled' ;
509- this . serviceName = this . _connInfo [ 2 ] ;
510- this . purity = this . _connInfo [ 3 ] | constants . PURITY_DEFAULT ;
529+ let serverType ;
530+ if ( this . isPooled ( ) ) {
531+ serverType = params . _connInfo [ 0 ] ;
532+ this . serviceName = params . _connInfo [ 2 ] ;
533+ this . purity = params . _connInfo [ 3 ] | constants . PURITY_DEFAULT ;
534+ this . sid = params . _connInfo [ 4 ] ;
535+ } else {
536+ serverType = this . nscon . getOption ( sqlNetConstants . SERVERTYPE ) ;
537+ this . serviceName = this . nscon . getOption ( sqlNetConstants . SVCNAME ) ;
538+ this . sid = this . nscon . getOption ( sqlNetConstants . SID ) ;
539+ this . purity = this . nscon . getOption ( sqlNetConstants . PURITY ) | constants . PURITY_DEFAULT ;
540+ }
541+ if ( serverType ) {
542+ this . _drcpEnabled = serverType . toLowerCase ( ) === 'pooled' ;
543+ }
511544 this . remoteAddress = this . nscon . getOption ( sqlNetConstants . REMOTEADDR ) ;
512545 this . connectionClass = params . connectionClass ;
513546
@@ -533,15 +566,40 @@ class ThinConnectionImpl extends ConnectionImpl {
533566 }
534567
535568 try {
536- let message = new messages . ProtocolMessage ( this ) ;
537- await this . _protocol . _processMessage ( message ) ;
538- message = new messages . DataTypeMessage ( this ) ;
539- await this . _protocol . _processMessage ( message ) ;
540- message = new messages . AuthMessage ( this , params ) ;
541- // Does OSESSKEY for non-token Authentication else OAUTH
542- await this . _protocol . _processMessage ( message ) ;
569+ const cookie = this . getConnectionCookieByUUID ( this . nscon . dbUUID ) ;
570+ this . nscon . dbUUID = null ;
571+ const protocolMessage = new messages . ProtocolMessage ( this ) ;
572+ const dataTypeMessage = new messages . DataTypeMessage ( this ) ;
573+ const authMessage = new messages . AuthMessage ( this , params ) ;
574+ let sentCookie = false ;
575+ if ( cookie && cookie . populated ) {
576+ const cookieMessage = new messages . ConnectionCookieMessage ( this ) ;
577+ cookieMessage . cookie = cookie ;
578+ cookieMessage . protocolMessage = protocolMessage ;
579+ cookieMessage . dataTypeMessage = dataTypeMessage ;
580+ cookieMessage . authMessage = authMessage ;
581+ await this . _protocol . _processMessage ( cookieMessage ) ;
582+ sentCookie = true ;
583+ } else {
584+ await this . _protocol . _processMessage ( protocolMessage ) ;
585+ }
586+ if ( ! sentCookie || ! cookie . populated ) {
587+ await this . _protocol . _processMessage ( dataTypeMessage ) ;
588+ // Does OSESSKEY for non-token Authentication else OAUTH
589+ await this . _protocol . _processMessage ( authMessage ) ;
590+ if ( cookie && ! cookie . populated ) {
591+ cookie . protocolVersion = protocolMessage . serverVersion ;
592+ cookie . serverBanner = protocolMessage . serverBanner ;
593+ cookie . charsetID = this . _protocol . caps . charSetID ;
594+ cookie . ncharsetID = this . _protocol . caps . nCharsetId ;
595+ cookie . flags = protocolMessage . serverFlags ;
596+ cookie . compileCaps = Buffer . from ( protocolMessage . serverCompileCaps ) ;
597+ cookie . runtimeCaps = Buffer . from ( protocolMessage . serverRunTimeCaps ) ;
598+ cookie . populated = true ;
599+ }
600+ }
543601 if ( ! params . token ) { // non-token Authentication
544- await this . _protocol . _processMessage ( message ) ; // OAUTH
602+ await this . _protocol . _processMessage ( authMessage ) ; // OAUTH
545603 }
546604 } catch ( err ) {
547605 this . nscon . disconnect ( ) ;
0 commit comments