@@ -155,9 +155,6 @@ pub struct ClientOptions {
155
155
}]" ) ]
156
156
pub hosts : Vec < StreamAddress > ,
157
157
158
- #[ builder( default = false ) ]
159
- pub srv : bool ,
160
-
161
158
#[ builder( default ) ]
162
159
pub app_name : Option < String > ,
163
160
@@ -383,7 +380,6 @@ impl From<ClientOptionsParser> for ClientOptions {
383
380
fn from ( parser : ClientOptionsParser ) -> Self {
384
381
Self {
385
382
hosts : parser. hosts ,
386
- srv : parser. srv ,
387
383
app_name : parser. app_name ,
388
384
tls : parser. tls ,
389
385
heartbeat_freq : parser. heartbeat_freq ,
@@ -417,31 +413,48 @@ impl ClientOptions {
417
413
/// Parses a MongoDB connection string into a ClientOptions struct. If the string is malformed
418
414
/// or one of the options has an invalid value, an error will be returned.
419
415
///
420
- /// In the case that "mongodb+srv" is used, SRV and TXT record lookups will _not_ be done as
421
- /// part of this method. To manually update the ClientOptions hosts and options with the SRV
422
- /// and TXT records, call `ClientOptions::resolve_srv`. Note that calling
423
- /// `Client::with_options` will also automatically call `resolve_srv` if needed.
424
- pub fn parse_uri ( s : & str ) -> Result < Self > {
425
- ClientOptionsParser :: parse ( s ) . map ( Into :: into )
426
- }
416
+ /// In the case that "mongodb+srv" is used, SRV and TXT record lookups will be done as
417
+ /// part of this method.
418
+ pub fn parse ( s : & str ) -> Result < Self > {
419
+ let parser = ClientOptionsParser :: parse ( s ) ? ;
420
+ let srv = parser . srv ;
421
+ let auth_source_present = parser . auth_source . is_some ( ) ;
422
+ let mut options : Self = parser . into ( ) ;
427
423
428
- /// If self.srv is true, then the SRV and TXT records for the host will be looked up, and the
429
- /// ClientOptions will be updated with the hosts found in the SRV records and the options found
430
- /// in the TXT record. After returning, self.srv will be set to false.
431
- ///
432
- /// If self.srv is false, this method will not change the ClientOptions.
433
- ///
434
- /// Note that MongoDB requires that exactly one address is present in an SRV configuration, and
435
- /// that address must not have a port. If more a port or more than one address is present, an
436
- /// error will be returned.
437
- ///
438
- /// See [the MongoDB documentation](https://docs.mongodb.com/manual/reference/connection-string/#dns-seedlist-connection-format) for more details.
439
- pub fn resolve_srv ( & mut self ) -> Result < ( ) > {
440
- let resolver = SrvResolver :: new ( ) ?;
441
- resolver. resolve_and_update_client_opts ( self ) ?;
442
- self . srv = false ;
424
+ if srv {
425
+ let resolver = SrvResolver :: new ( ) ?;
426
+ let mut config = resolver. resolve_client_options ( & options. hosts [ 0 ] . hostname ) ?;
443
427
444
- Ok ( ( ) )
428
+ // Set the ClientOptions hosts to those found during the SRV lookup.
429
+ options. hosts = config. hosts ;
430
+
431
+ // Enable TLS unless the user explicitly disabled it.
432
+ if options. tls . is_none ( ) {
433
+ options. tls = Some ( Tls :: Enabled ( Default :: default ( ) ) ) ;
434
+ }
435
+
436
+ // Set the authSource TXT option found during SRV lookup unless the user already set it.
437
+ // Note that this _does_ override the default database specified in the URI, since it is
438
+ // supposed to be overriden by authSource.
439
+ if !auth_source_present {
440
+ if let Some ( auth_source) = config. auth_source . take ( ) {
441
+ options
442
+ . credential
443
+ . get_or_insert_with ( Default :: default)
444
+ . source = Some ( auth_source) ;
445
+ }
446
+ }
447
+
448
+ // Set the replica set name TXT option found during SRV lookup unless the user already
449
+ // set it.
450
+ if options. repl_set_name . is_none ( ) {
451
+ if let Some ( replica_set) = config. replica_set . take ( ) {
452
+ options. repl_set_name = Some ( replica_set) ;
453
+ }
454
+ }
455
+ }
456
+
457
+ Ok ( options)
445
458
}
446
459
447
460
pub ( crate ) fn tls_options ( & self ) -> Option < TlsOptions > {
@@ -692,7 +705,7 @@ impl ClientOptionsParser {
692
705
693
706
credential. source = options
694
707
. auth_source
695
- . take ( )
708
+ . clone ( )
696
709
. or_else ( || Some ( mechanism. default_source ( db_str) . into ( ) ) ) ;
697
710
698
711
if let Some ( mut doc) = options. auth_mechanism_properties . take ( ) {
@@ -725,7 +738,7 @@ impl ClientOptionsParser {
725
738
// SCRAM default (i.e. "admin").
726
739
credential. source = options
727
740
. auth_source
728
- . take ( )
741
+ . clone ( )
729
742
. or ( db)
730
743
. or_else ( || Some ( "admin" . into ( ) ) ) ;
731
744
} else if authentication_requested {
@@ -1102,7 +1115,9 @@ impl ClientOptionsParser {
1102
1115
"authmechanism" => {
1103
1116
self . auth_mechanism = Some ( AuthMechanism :: from_str ( value) ?) ;
1104
1117
}
1105
- "authsource" => self . auth_source = Some ( value. to_string ( ) ) ,
1118
+ "authsource" => {
1119
+ self . auth_source = Some ( value. to_string ( ) ) ;
1120
+ }
1106
1121
"authmechanismproperties" => {
1107
1122
let mut doc = Document :: new ( ) ;
1108
1123
let err_func = || {
@@ -1223,35 +1238,35 @@ mod tests {
1223
1238
1224
1239
#[ test]
1225
1240
fn fails_without_scheme ( ) {
1226
- assert ! ( ClientOptions :: parse_uri ( "localhost:27017" ) . is_err( ) ) ;
1241
+ assert ! ( ClientOptions :: parse ( "localhost:27017" ) . is_err( ) ) ;
1227
1242
}
1228
1243
1229
1244
#[ test]
1230
1245
fn fails_with_invalid_scheme ( ) {
1231
- assert ! ( ClientOptions :: parse_uri ( "mangodb://localhost:27017" ) . is_err( ) ) ;
1246
+ assert ! ( ClientOptions :: parse ( "mangodb://localhost:27017" ) . is_err( ) ) ;
1232
1247
}
1233
1248
1234
1249
#[ test]
1235
1250
fn fails_with_nothing_after_scheme ( ) {
1236
- assert ! ( ClientOptions :: parse_uri ( "mongodb://" ) . is_err( ) ) ;
1251
+ assert ! ( ClientOptions :: parse ( "mongodb://" ) . is_err( ) ) ;
1237
1252
}
1238
1253
1239
1254
#[ test]
1240
1255
fn fails_with_only_slash_after_scheme ( ) {
1241
- assert ! ( ClientOptions :: parse_uri ( "mongodb:///" ) . is_err( ) ) ;
1256
+ assert ! ( ClientOptions :: parse ( "mongodb:///" ) . is_err( ) ) ;
1242
1257
}
1243
1258
1244
1259
#[ test]
1245
1260
fn fails_with_no_host ( ) {
1246
- assert ! ( ClientOptions :: parse_uri ( "mongodb://:27017" ) . is_err( ) ) ;
1261
+ assert ! ( ClientOptions :: parse ( "mongodb://:27017" ) . is_err( ) ) ;
1247
1262
}
1248
1263
1249
1264
#[ test]
1250
1265
fn no_port ( ) {
1251
1266
let uri = "mongodb://localhost" ;
1252
1267
1253
1268
assert_eq ! (
1254
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1269
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1255
1270
ClientOptions {
1256
1271
hosts: vec![ host_without_port( "localhost" ) ] ,
1257
1272
original_uri: Some ( uri. into( ) ) ,
@@ -1265,7 +1280,7 @@ mod tests {
1265
1280
let uri = "mongodb://localhost/" ;
1266
1281
1267
1282
assert_eq ! (
1268
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1283
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1269
1284
ClientOptions {
1270
1285
hosts: vec![ host_without_port( "localhost" ) ] ,
1271
1286
original_uri: Some ( uri. into( ) ) ,
@@ -1279,7 +1294,7 @@ mod tests {
1279
1294
let uri = "mongodb://localhost/" ;
1280
1295
1281
1296
assert_eq ! (
1282
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1297
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1283
1298
ClientOptions {
1284
1299
hosts: vec![ StreamAddress {
1285
1300
hostname: "localhost" . to_string( ) ,
@@ -1296,7 +1311,7 @@ mod tests {
1296
1311
let uri = "mongodb://localhost:27017/" ;
1297
1312
1298
1313
assert_eq ! (
1299
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1314
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1300
1315
ClientOptions {
1301
1316
hosts: vec![ StreamAddress {
1302
1317
hostname: "localhost" . to_string( ) ,
@@ -1313,7 +1328,7 @@ mod tests {
1313
1328
let uri = "mongodb://localhost:27017/?readConcernLevel=foo" ;
1314
1329
1315
1330
assert_eq ! (
1316
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1331
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1317
1332
ClientOptions {
1318
1333
hosts: vec![ StreamAddress {
1319
1334
hostname: "localhost" . to_string( ) ,
@@ -1328,7 +1343,7 @@ mod tests {
1328
1343
1329
1344
#[ test]
1330
1345
fn with_w_negative_int ( ) {
1331
- assert ! ( ClientOptions :: parse_uri ( "mongodb://localhost:27017/?w=-1" ) . is_err( ) ) ;
1346
+ assert ! ( ClientOptions :: parse ( "mongodb://localhost:27017/?w=-1" ) . is_err( ) ) ;
1332
1347
}
1333
1348
1334
1349
#[ test]
@@ -1337,7 +1352,7 @@ mod tests {
1337
1352
let write_concern = WriteConcern :: builder ( ) . w ( Acknowledgment :: from ( 1 ) ) . build ( ) ;
1338
1353
1339
1354
assert_eq ! (
1340
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1355
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1341
1356
ClientOptions {
1342
1357
hosts: vec![ StreamAddress {
1343
1358
hostname: "localhost" . to_string( ) ,
@@ -1358,7 +1373,7 @@ mod tests {
1358
1373
. build ( ) ;
1359
1374
1360
1375
assert_eq ! (
1361
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1376
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1362
1377
ClientOptions {
1363
1378
hosts: vec![ StreamAddress {
1364
1379
hostname: "localhost" . to_string( ) ,
@@ -1373,7 +1388,7 @@ mod tests {
1373
1388
1374
1389
#[ test]
1375
1390
fn with_invalid_j ( ) {
1376
- assert ! ( ClientOptions :: parse_uri ( "mongodb://localhost:27017/?journal=foo" ) . is_err( ) ) ;
1391
+ assert ! ( ClientOptions :: parse ( "mongodb://localhost:27017/?journal=foo" ) . is_err( ) ) ;
1377
1392
}
1378
1393
1379
1394
#[ test]
@@ -1382,7 +1397,7 @@ mod tests {
1382
1397
let write_concern = WriteConcern :: builder ( ) . journal ( true ) . build ( ) ;
1383
1398
1384
1399
assert_eq ! (
1385
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1400
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1386
1401
ClientOptions {
1387
1402
hosts: vec![ StreamAddress {
1388
1403
hostname: "localhost" . to_string( ) ,
@@ -1397,12 +1412,12 @@ mod tests {
1397
1412
1398
1413
#[ test]
1399
1414
fn with_wtimeout_non_int ( ) {
1400
- assert ! ( ClientOptions :: parse_uri ( "mongodb://localhost:27017/?wtimeoutMS=foo" ) . is_err( ) ) ;
1415
+ assert ! ( ClientOptions :: parse ( "mongodb://localhost:27017/?wtimeoutMS=foo" ) . is_err( ) ) ;
1401
1416
}
1402
1417
1403
1418
#[ test]
1404
1419
fn with_wtimeout_negative_int ( ) {
1405
- assert ! ( ClientOptions :: parse_uri ( "mongodb://localhost:27017/?wtimeoutMS=-1" ) . is_err( ) ) ;
1420
+ assert ! ( ClientOptions :: parse ( "mongodb://localhost:27017/?wtimeoutMS=-1" ) . is_err( ) ) ;
1406
1421
}
1407
1422
1408
1423
#[ test]
@@ -1413,7 +1428,7 @@ mod tests {
1413
1428
. build ( ) ;
1414
1429
1415
1430
assert_eq ! (
1416
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1431
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1417
1432
ClientOptions {
1418
1433
hosts: vec![ StreamAddress {
1419
1434
hostname: "localhost" . to_string( ) ,
@@ -1436,7 +1451,7 @@ mod tests {
1436
1451
. build ( ) ;
1437
1452
1438
1453
assert_eq ! (
1439
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1454
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1440
1455
ClientOptions {
1441
1456
hosts: vec![ StreamAddress {
1442
1457
hostname: "localhost" . to_string( ) ,
@@ -1466,7 +1481,7 @@ mod tests {
1466
1481
. build ( ) ;
1467
1482
1468
1483
assert_eq ! (
1469
- ClientOptions :: parse_uri ( uri) . unwrap( ) ,
1484
+ ClientOptions :: parse ( uri) . unwrap( ) ,
1470
1485
ClientOptions {
1471
1486
hosts: vec![
1472
1487
StreamAddress {
0 commit comments