Skip to content

Commit 50c412a

Browse files
committed
NODE-500 Accidental repeat of hostname in seed list multiplies total connections persistently
1 parent 34f620b commit 50c412a

File tree

2 files changed

+67
-34
lines changed

2 files changed

+67
-34
lines changed

lib/url_parser.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ module.exports = function(url, options) {
3333
if(connection_part.indexOf(".sock/") != -1) {
3434
dbName = connection_part.split(".sock/")[1];
3535
connection_part = connection_part.split("/", connection_part.indexOf(".sock") + ".sock".length);
36-
}
36+
}
3737
} else if(connection_part.indexOf("/") != -1) {
3838
dbName = connection_part.split("/")[1];
3939
connection_part = connection_part.split("/")[0];
@@ -80,6 +80,9 @@ module.exports = function(url, options) {
8080
} else {
8181
// Split up the db
8282
hostPart = connection_part;
83+
// Deduplicate servers
84+
var deduplicatedServers = {};
85+
8386
// Parse all server results
8487
servers = hostPart.split(',').map(function(h) {
8588
var _host, _port, ipv6match;
@@ -95,15 +98,22 @@ module.exports = function(url, options) {
9598
// Check for localhost?safe=true style case
9699
if(_host.indexOf("?") != -1) _host = _host.split(/\?/)[0];
97100
}
101+
102+
// No entry returned for duplicate servr
103+
if(deduplicatedServers[_host + "_" + _port]) return null;
104+
deduplicatedServers[_host + "_" + _port] = 1;
105+
98106
// Return the mapped object
99107
return {host: _host, port: _port};
108+
}).filter(function(x) {
109+
return x != null;
100110
});
101111
}
102112

103113
// Get the db name
104114
object.dbName = dbName || 'admin';
105115
// Split up all the options
106-
urlOptions = (query_string_part || '').split(/[&;]/);
116+
urlOptions = (query_string_part || '').split(/[&;]/);
107117
// Ugh, we have to figure out which options go to which constructor manually.
108118
urlOptions.forEach(function(opt) {
109119
if(!opt) return;
@@ -201,15 +211,15 @@ module.exports = function(url, options) {
201211
} else if(value == 'MONGODB-X509') {
202212
object.auth = {user: decodeURIComponent(authPart)};
203213
}
204-
214+
205215
// Only support GSSAPI or MONGODB-CR for now
206-
if(value != 'GSSAPI'
216+
if(value != 'GSSAPI'
207217
&& value != 'MONGODB-X509'
208218
&& value != 'MONGODB-CR'
209219
&& value != 'SCRAM-SHA-1'
210-
&& value != 'PLAIN')
220+
&& value != 'PLAIN')
211221
throw new Error("only GSSAPI, PLAIN, MONGODB-X509, SCRAM-SHA-1 or MONGODB-CR is supported by authMechanism");
212-
222+
213223
// Authentication mechanism
214224
dbOptions.authMechanism = value;
215225
break;

test/functional/url_parser_tests.js

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var parse = require('../../lib/url_parser');
1010
*/
1111
exports['Should correctly parse mongodb://localhost'] = {
1212
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
13-
13+
1414
// The actual test we wish to run
1515
test: function(configure, test) {
1616
// console.dir(parse)
@@ -28,7 +28,7 @@ exports['Should correctly parse mongodb://localhost'] = {
2828
*/
2929
exports['Should correctly parse mongodb://localhost:27017'] = {
3030
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
31-
31+
3232
// The actual test we wish to run
3333
test: function(configure, test) {
3434
// console.dir(parse)
@@ -46,7 +46,7 @@ exports['Should correctly parse mongodb://localhost:27017'] = {
4646
*/
4747
exports['Should correctly parse mongodb://localhost?safe=true&readPreference=secondary'] = {
4848
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
49-
49+
5050
// The actual test we wish to run
5151
test: function(configure, test) {
5252
// console.dir(parse)
@@ -65,7 +65,7 @@ exports['Should correctly parse mongodb://localhost?safe=true&readPreference=sec
6565
*/
6666
exports['Should correctly parse mongodb://localhost:28101'] = {
6767
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
68-
68+
6969
// The actual test we wish to run
7070
test: function(configure, test) {
7171
// console.dir(parse)
@@ -83,7 +83,7 @@ exports['Should correctly parse mongodb://localhost:28101'] = {
8383
*/
8484
exports['Should correctly parse mongodb://fred:foobar@localhost/baz'] = {
8585
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
86-
86+
8787
// The actual test we wish to run
8888
test: function(configure, test) {
8989
// console.dir(parse)
@@ -103,7 +103,7 @@ exports['Should correctly parse mongodb://fred:foobar@localhost/baz'] = {
103103
*/
104104
exports['Should correctly parse mongodb://fred:foo%20bar@localhost/baz'] = {
105105
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
106-
106+
107107
// The actual test we wish to run
108108
test: function(configure, test) {
109109
// console.dir(parse)
@@ -123,7 +123,7 @@ exports['Should correctly parse mongodb://fred:foo%20bar@localhost/baz'] = {
123123
*/
124124
exports['Should correctly parse mongodb:///tmp/mongodb-27017.sock'] = {
125125
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
126-
126+
127127
// The actual test we wish to run
128128
test: function(configure, test) {
129129
// console.dir(parse)
@@ -140,7 +140,7 @@ exports['Should correctly parse mongodb:///tmp/mongodb-27017.sock'] = {
140140
*/
141141
exports['Should correctly parse mongodb://fred:foo@/tmp/mongodb-27017.sock'] = {
142142
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
143-
143+
144144
// The actual test we wish to run
145145
test: function(configure, test) {
146146
// console.dir(parse)
@@ -159,7 +159,7 @@ exports['Should correctly parse mongodb://fred:foo@/tmp/mongodb-27017.sock'] = {
159159
*/
160160
exports['Should correctly parse mongodb://fred:foo@/tmp/mongodb-27017.sock/somedb'] = {
161161
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
162-
162+
163163
// The actual test we wish to run
164164
test: function(configure, test) {
165165
// console.dir(parse)
@@ -178,7 +178,7 @@ exports['Should correctly parse mongodb://fred:foo@/tmp/mongodb-27017.sock/somed
178178
*/
179179
exports['Should correctly parse mongodb://fred:foo@/tmp/mongodb-27017.sock/somedb?safe=true'] = {
180180
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
181-
181+
182182
// The actual test we wish to run
183183
test: function(configure, test) {
184184
// console.dir(parse)
@@ -198,7 +198,7 @@ exports['Should correctly parse mongodb://fred:foo@/tmp/mongodb-27017.sock/somed
198198
*/
199199
exports['Should correctly parse mongodb://example1.com:27017,example2.com:27018'] = {
200200
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
201-
201+
202202
// The actual test we wish to run
203203
test: function(configure, test) {
204204
// console.dir(parse)
@@ -218,7 +218,7 @@ exports['Should correctly parse mongodb://example1.com:27017,example2.com:27018'
218218
*/
219219
exports['Should correctly parse mongodb://localhost,localhost:27018,localhost:27019'] = {
220220
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
221-
221+
222222
// The actual test we wish to run
223223
test: function(configure, test) {
224224
// console.dir(parse)
@@ -240,7 +240,7 @@ exports['Should correctly parse mongodb://localhost,localhost:27018,localhost:27
240240
*/
241241
exports['Should correctly parse mongodb://host1,host2,host3/?slaveOk=true'] = {
242242
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
243-
243+
244244
// The actual test we wish to run
245245
test: function(configure, test) {
246246
// console.dir(parse)
@@ -258,12 +258,35 @@ exports['Should correctly parse mongodb://host1,host2,host3/?slaveOk=true'] = {
258258
}
259259
}
260260

261+
/**
262+
* @ignore
263+
*/
264+
exports['Should correctly parse mongodb://host1,host2,host3,host1/?slaveOk=true and de-duplicate names'] = {
265+
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
266+
267+
// The actual test we wish to run
268+
test: function(configure, test) {
269+
// console.dir(parse)
270+
var object = parse("mongodb://host1,host2,host3,host1/?slaveOk=true");
271+
test.equal(3, object.servers.length);
272+
test.equal("host1", object.servers[0].host);
273+
test.equal('27017', object.servers[0].port);
274+
test.equal("host2", object.servers[1].host);
275+
test.equal('27017', object.servers[1].port);
276+
test.equal("host3", object.servers[2].host);
277+
test.equal('27017', object.servers[2].port);
278+
test.equal('admin', object.dbName);
279+
test.equal(true, object.server_options.slave_ok);
280+
test.done();
281+
}
282+
}
283+
261284
/**
262285
* @ignore
263286
*/
264287
exports['Should correctly parse mongodb://localhost/?safe=true'] = {
265288
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
266-
289+
267290
// The actual test we wish to run
268291
test: function(configure, test) {
269292
// console.dir(parse)
@@ -282,7 +305,7 @@ exports['Should correctly parse mongodb://localhost/?safe=true'] = {
282305
*/
283306
exports['Should correctly parse mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000'] = {
284307
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
285-
308+
286309
// The actual test we wish to run
287310
test: function(configure, test) {
288311
// console.dir(parse)
@@ -307,7 +330,7 @@ exports['Should correctly parse mongodb://host1,host2,host3/?safe=true;w=2;wtime
307330
*/
308331
exports['Parse mongodb://localhost/db?replicaSet=hello&ssl=prefer&connectTimeoutMS=1000&socketTimeoutMS=2000'] = {
309332
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
310-
333+
311334
// The actual test we wish to run
312335
test: function(configure, test) {
313336
// console.dir(parse)
@@ -332,7 +355,7 @@ exports['Parse mongodb://localhost/db?replicaSet=hello&ssl=prefer&connectTimeout
332355
*/
333356
exports['Parse mongodb://localhost/db?ssl=true'] = {
334357
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
335-
358+
336359
// The actual test we wish to run
337360
test: function(configure, test) {
338361
// console.dir(parse)
@@ -352,7 +375,7 @@ exports['Parse mongodb://localhost/db?ssl=true'] = {
352375
*/
353376
exports['Parse mongodb://localhost/db?maxPoolSize=100'] = {
354377
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
355-
378+
356379
// The actual test we wish to run
357380
test: function(configure, test) {
358381
// console.dir(parse)
@@ -372,7 +395,7 @@ exports['Parse mongodb://localhost/db?maxPoolSize=100'] = {
372395
*/
373396
exports['Parse mongodb://localhost/db?w=-1'] = {
374397
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
375-
398+
376399
// The actual test we wish to run
377400
test: function(configure, test) {
378401
// console.dir(parse)
@@ -391,7 +414,7 @@ exports['Parse mongodb://localhost/db?w=-1'] = {
391414
*/
392415
exports['Throw on unsuported options'] = {
393416
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
394-
417+
395418
// The actual test we wish to run
396419
test: function(configure, test) {
397420
// console.dir(parse)
@@ -409,7 +432,7 @@ exports['Throw on unsuported options'] = {
409432
*/
410433
exports['Write concerns parsing'] = {
411434
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
412-
435+
413436
// The actual test we wish to run
414437
test: function(configure, test) {
415438
var object = parse("mongodb://localhost/db?safe=true&w=1");
@@ -430,7 +453,7 @@ exports['Write concerns parsing'] = {
430453
*/
431454
exports['GSSAPI parsing'] = {
432455
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
433-
456+
434457
// The actual test we wish to run
435458
test: function(configure, test) {
436459
var object = parse("mongodb://dev1%[email protected]/test?authMechanism=GSSAPI");
@@ -463,7 +486,7 @@ exports['GSSAPI parsing'] = {
463486
*/
464487
exports['Read preferences parsing'] = {
465488
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
466-
489+
467490
// The actual test we wish to run
468491
test: function(configure, test) {
469492
var object = parse("mongodb://localhost/db?slaveOk=true");
@@ -497,7 +520,7 @@ exports['Read preferences parsing'] = {
497520
*/
498521
exports['Read preferences tag parsing'] = {
499522
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
500-
523+
501524
// The actual test we wish to run
502525
test: function(configure, test) {
503526
var object = parse("mongodb://localhost/db");
@@ -523,7 +546,7 @@ exports['Read preferences tag parsing'] = {
523546
*/
524547
exports['Should correctly parse mongodb://[::1]:1234'] = {
525548
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
526-
549+
527550
// The actual test we wish to run
528551
test: function(configure, test) {
529552
// console.dir(parse)
@@ -541,7 +564,7 @@ exports['Should correctly parse mongodb://[::1]:1234'] = {
541564
*/
542565
exports['Should correctly parse mongodb://[::1]'] = {
543566
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
544-
567+
545568
// The actual test we wish to run
546569
test: function(configure, test) {
547570
// console.dir(parse)
@@ -559,7 +582,7 @@ exports['Should correctly parse mongodb://[::1]'] = {
559582
*/
560583
exports['Should correctly parse mongodb://localhost,[::1]:27018,[2607:f0d0:1002:51::41]'] = {
561584
metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] } },
562-
585+
563586
// The actual test we wish to run
564587
test: function(configure, test) {
565588
// console.dir(parse)
@@ -574,4 +597,4 @@ exports['Should correctly parse mongodb://localhost,[::1]:27018,[2607:f0d0:1002:
574597
test.equal('admin', object.dbName);
575598
test.done();
576599
}
577-
}
600+
}

0 commit comments

Comments
 (0)