@@ -27,7 +27,7 @@ function matchesParentDomain(srvAddress, parentDomain) {
27
27
}
28
28
29
29
/**
30
- * Lookup an `mongodb+srv` connection string, combine the parts and reparse it as a normal
30
+ * Lookup a `mongodb+srv` connection string, combine the parts and reparse it as a normal
31
31
* connection string.
32
32
*
33
33
* @param {string } uri The connection string to parse
@@ -50,8 +50,9 @@ function parseSrvConnectionString(uri, options, callback) {
50
50
return callback ( new MongoParseError ( `Ports not accepted with '${ PROTOCOL_MONGODB_SRV } ' URIs` ) ) ;
51
51
}
52
52
53
- let srvAddress = `_mongodb._tcp.${ result . host } ` ;
54
- dns . resolveSrv ( srvAddress , ( err , addresses ) => {
53
+ // Resolve the SRV record and use the result as the list of hosts to connect to.
54
+ const lookupAddress = result . host ;
55
+ dns . resolveSrv ( `_mongodb._tcp.${ lookupAddress } ` , ( err , addresses ) => {
55
56
if ( err ) return callback ( err ) ;
56
57
57
58
if ( addresses . length === 0 ) {
@@ -66,36 +67,20 @@ function parseSrvConnectionString(uri, options, callback) {
66
67
}
67
68
}
68
69
69
- let base = result . auth ? `mongodb://${ result . auth } @` : `mongodb://` ;
70
- let connectionStrings = addresses . map (
71
- ( address , i ) =>
72
- i === 0 ? `${ base } ${ address . name } :${ address . port } ` : `${ address . name } :${ address . port } `
73
- ) ;
74
-
75
- let connectionString = `${ connectionStrings . join ( ',' ) } /` ;
76
- let connectionStringOptions = [ ] ;
77
-
78
- // Add the default database if needed
79
- if ( result . path ) {
80
- let defaultDb = result . path . slice ( 1 ) ;
81
- if ( defaultDb . indexOf ( '?' ) !== - 1 ) {
82
- defaultDb = defaultDb . slice ( 0 , defaultDb . indexOf ( '?' ) ) ;
83
- }
84
-
85
- connectionString += defaultDb ;
86
- }
70
+ // Convert the original URL to a non-SRV URL.
71
+ result . protocol = 'mongodb' ;
72
+ result . host = addresses . map ( address => `${ address . name } :${ address . port } ` ) . join ( ',' ) ;
87
73
88
- // Default to SSL true
89
- if ( ! options . ssl && ( ! result . search || result . query [ 'ssl' ] == null ) ) {
90
- connectionStringOptions . push ( 'ssl=true' ) ;
91
- }
92
-
93
- // Keep original uri options
94
- if ( result . search ) {
95
- connectionStringOptions . push ( result . search . replace ( '?' , '' ) ) ;
74
+ // Default to SSL true if it's not specified.
75
+ if (
76
+ ! ( 'ssl' in options ) &&
77
+ ( ! result . search || ! ( 'ssl' in result . query ) || result . query . ssl === null )
78
+ ) {
79
+ result . query . ssl = true ;
96
80
}
97
81
98
- dns . resolveTxt ( result . host , ( err , record ) => {
82
+ // Resolve TXT record and add options from there if they exist.
83
+ dns . resolveTxt ( lookupAddress , ( err , record ) => {
99
84
if ( err ) {
100
85
if ( err . code !== 'ENODATA' ) {
101
86
return callback ( err ) ;
@@ -108,23 +93,21 @@ function parseSrvConnectionString(uri, options, callback) {
108
93
return callback ( new MongoParseError ( 'Multiple text records not allowed' ) ) ;
109
94
}
110
95
111
- record = record [ 0 ] ;
112
- record = record . length > 1 ? record . join ( '' ) : record [ 0 ] ;
113
- if ( record . indexOf ( 'authSource' ) === - 1 && record . indexOf ( 'replicaSet' ) === - 1 ) {
96
+ record = qs . parse ( record [ 0 ] . join ( '' ) ) ;
97
+ if ( Object . keys ( record ) . some ( key => key !== 'authSource' && key !== 'replicaSet' ) ) {
114
98
return callback (
115
99
new MongoParseError ( 'Text record must only set `authSource` or `replicaSet`' )
116
100
) ;
117
101
}
118
102
119
- connectionStringOptions . push ( record ) ;
103
+ Object . assign ( result . query , record ) ;
120
104
}
121
105
122
- // Add any options to the connection string
123
- if ( connectionStringOptions . length ) {
124
- connectionString += `?${ connectionStringOptions . join ( '&' ) } ` ;
125
- }
106
+ // Set completed options back into the URL object.
107
+ result . search = qs . stringify ( result . query ) ;
126
108
127
- parseConnectionString ( connectionString , options , callback ) ;
109
+ const finalString = URL . format ( result ) ;
110
+ parseConnectionString ( finalString , options , callback ) ;
128
111
} ) ;
129
112
} ) ;
130
113
}
0 commit comments