mongodb 3.6.2 → 3.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +24 -0
- package/lib/aggregation_cursor.js +0 -7
- package/lib/change_stream.js +1 -1
- package/lib/cmap/connection.js +1 -1
- package/lib/cmap/connection_pool.js +6 -10
- package/lib/core/auth/gssapi.js +66 -66
- package/lib/core/auth/x509.js +1 -1
- package/lib/core/connection/connect.js +1 -1
- package/lib/core/connection/connection.js +3 -4
- package/lib/core/connection/pool.js +3 -3
- package/lib/core/sdam/topology_description.js +1 -0
- package/lib/core/topologies/replset.js +1 -1
- package/lib/core/topologies/server.js +2 -2
- package/lib/core/uri_parser.js +0 -9
- package/lib/gridfs/grid_store.js +1 -0
- package/lib/mongo_client.js +4 -3
- package/lib/operations/add_user.js +3 -1
- package/lib/operations/admin_ops.js +1 -1
- package/lib/operations/command_v2.js +3 -1
- package/lib/operations/connect.js +2 -2
- package/lib/operations/validate_collection.js +1 -1
- package/lib/topologies/mongos.js +1 -1
- package/lib/topologies/server.js +1 -1
- package/lib/utils.js +17 -5
- package/package.json +29 -7
package/HISTORY.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
<a name="3.6.3"></a>
|
|
6
|
+
## [3.6.3](https://github.com/mongodb/node-mongodb-native/compare/v3.6.1...v3.6.3) (2020-11-06)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* add peerDependenciesMeta to mark optional deps ([#2606](https://github.com/mongodb/node-mongodb-native/issues/2606)) ([186090e](https://github.com/mongodb/node-mongodb-native/commit/186090e))
|
|
12
|
+
* adds topology discovery for sharded cluster ([f8fd310](https://github.com/mongodb/node-mongodb-native/commit/f8fd310))
|
|
13
|
+
* allow event loop to process during wait queue processing ([#2537](https://github.com/mongodb/node-mongodb-native/issues/2537)) ([4e03dfa](https://github.com/mongodb/node-mongodb-native/commit/4e03dfa))
|
|
14
|
+
* Change socket timeout default to 0 ([#2572](https://github.com/mongodb/node-mongodb-native/issues/2572)) ([89b77ed](https://github.com/mongodb/node-mongodb-native/commit/89b77ed))
|
|
15
|
+
* connection leak if wait queue member cancelled ([cafaa1b](https://github.com/mongodb/node-mongodb-native/commit/cafaa1b))
|
|
16
|
+
* correctly assign username to X509 auth command ([#2587](https://github.com/mongodb/node-mongodb-native/issues/2587)) ([9110a45](https://github.com/mongodb/node-mongodb-native/commit/9110a45))
|
|
17
|
+
* correctly re-establishes pipe destinations ([a6e7caf](https://github.com/mongodb/node-mongodb-native/commit/a6e7caf))
|
|
18
|
+
* Fix test filters and revert mocha version ([#2558](https://github.com/mongodb/node-mongodb-native/issues/2558)) ([0e5c45a](https://github.com/mongodb/node-mongodb-native/commit/0e5c45a))
|
|
19
|
+
* move kerberos client setup from prepare to auth ([#2608](https://github.com/mongodb/node-mongodb-native/issues/2608)) ([033b6e7](https://github.com/mongodb/node-mongodb-native/commit/033b6e7))
|
|
20
|
+
* permit waking async interval with unreliable clock ([e0e11bb](https://github.com/mongodb/node-mongodb-native/commit/e0e11bb))
|
|
21
|
+
* remove geoNear deprecation ([4955a52](https://github.com/mongodb/node-mongodb-native/commit/4955a52))
|
|
22
|
+
* revert use of setImmediate to process.nextTick ([#2611](https://github.com/mongodb/node-mongodb-native/issues/2611)) ([c9f9d5e](https://github.com/mongodb/node-mongodb-native/commit/c9f9d5e))
|
|
23
|
+
* sets primary read preference for writes ([ddcd03d](https://github.com/mongodb/node-mongodb-native/commit/ddcd03d))
|
|
24
|
+
* use options for readPreference in client ([6acced0](https://github.com/mongodb/node-mongodb-native/commit/6acced0))
|
|
25
|
+
* user roles take single string & DDL readPreference tests ([967de13](https://github.com/mongodb/node-mongodb-native/commit/967de13))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
5
29
|
<a name="3.6.2"></a>
|
|
6
30
|
## [3.6.2](https://github.com/mongodb/node-mongodb-native/compare/v3.6.1...v3.6.2) (2020-09-10)
|
|
7
31
|
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const MongoError = require('./core').MongoError;
|
|
4
4
|
const Cursor = require('./cursor');
|
|
5
5
|
const CursorState = require('./core/cursor').CursorState;
|
|
6
|
-
const deprecate = require('util').deprecate;
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* @fileOverview The **AggregationCursor** class is an internal class that embodies an aggregation cursor on MongoDB
|
|
@@ -225,12 +224,6 @@ class AggregationCursor extends Cursor {
|
|
|
225
224
|
// aliases
|
|
226
225
|
AggregationCursor.prototype.get = AggregationCursor.prototype.toArray;
|
|
227
226
|
|
|
228
|
-
// deprecated methods
|
|
229
|
-
deprecate(
|
|
230
|
-
AggregationCursor.prototype.geoNear,
|
|
231
|
-
'The `$geoNear` stage is deprecated in MongoDB 4.0, and removed in version 4.2.'
|
|
232
|
-
);
|
|
233
|
-
|
|
234
227
|
/**
|
|
235
228
|
* AggregationCursor stream data event, fired for each document in the cursor.
|
|
236
229
|
*
|
package/lib/change_stream.js
CHANGED
|
@@ -437,7 +437,7 @@ function createChangeStreamCursor(self, options) {
|
|
|
437
437
|
|
|
438
438
|
if (self.pipeDestinations) {
|
|
439
439
|
const cursorStream = changeStreamCursor.stream(self.streamOptions);
|
|
440
|
-
for (let pipeDestination
|
|
440
|
+
for (let pipeDestination of self.pipeDestinations) {
|
|
441
441
|
cursorStream.pipe(pipeDestination);
|
|
442
442
|
}
|
|
443
443
|
}
|
package/lib/cmap/connection.js
CHANGED
|
@@ -32,7 +32,7 @@ class Connection extends EventEmitter {
|
|
|
32
32
|
this.id = options.id;
|
|
33
33
|
this.address = streamIdentifier(stream);
|
|
34
34
|
this.bson = options.bson;
|
|
35
|
-
this.socketTimeout = typeof options.socketTimeout === 'number' ? options.socketTimeout :
|
|
35
|
+
this.socketTimeout = typeof options.socketTimeout === 'number' ? options.socketTimeout : 0;
|
|
36
36
|
this.host = options.host || 'localhost';
|
|
37
37
|
this.port = options.port || 27017;
|
|
38
38
|
this.monitorCommands =
|
|
@@ -95,7 +95,7 @@ const VALID_POOL_OPTIONS = new Set([
|
|
|
95
95
|
|
|
96
96
|
function resolveOptions(options, defaults) {
|
|
97
97
|
const newOptions = Array.from(VALID_POOL_OPTIONS).reduce((obj, key) => {
|
|
98
|
-
if (
|
|
98
|
+
if (Object.prototype.hasOwnProperty.call(options, key)) {
|
|
99
99
|
obj[key] = options[key];
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -233,7 +233,7 @@ class ConnectionPool extends EventEmitter {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
this[kWaitQueue].push(waitQueueMember);
|
|
236
|
-
|
|
236
|
+
process.nextTick(() => processWaitQueue(this));
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
/**
|
|
@@ -258,7 +258,7 @@ class ConnectionPool extends EventEmitter {
|
|
|
258
258
|
destroyConnection(this, connection, reason);
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
|
|
261
|
+
process.nextTick(() => processWaitQueue(this));
|
|
262
262
|
}
|
|
263
263
|
|
|
264
264
|
/**
|
|
@@ -428,7 +428,7 @@ function createConnection(pool, callback) {
|
|
|
428
428
|
|
|
429
429
|
// otherwise add it to the pool for later acquisition, and try to process the wait queue
|
|
430
430
|
pool[kConnections].push(connection);
|
|
431
|
-
|
|
431
|
+
process.nextTick(() => processWaitQueue(pool));
|
|
432
432
|
});
|
|
433
433
|
}
|
|
434
434
|
|
|
@@ -439,7 +439,7 @@ function destroyConnection(pool, connection, reason) {
|
|
|
439
439
|
pool[kPermits]++;
|
|
440
440
|
|
|
441
441
|
// destroy the connection
|
|
442
|
-
|
|
442
|
+
process.nextTick(() => connection.destroy());
|
|
443
443
|
}
|
|
444
444
|
|
|
445
445
|
function processWaitQueue(pool) {
|
|
@@ -477,7 +477,7 @@ function processWaitQueue(pool) {
|
|
|
477
477
|
if (pool.waitQueueSize && (maxPoolSize <= 0 || pool.totalConnectionCount < maxPoolSize)) {
|
|
478
478
|
createConnection(pool, (err, connection) => {
|
|
479
479
|
const waitQueueMember = pool[kWaitQueue].shift();
|
|
480
|
-
if (waitQueueMember == null) {
|
|
480
|
+
if (waitQueueMember == null || waitQueueMember[kCancelled]) {
|
|
481
481
|
if (err == null) {
|
|
482
482
|
pool[kConnections].push(connection);
|
|
483
483
|
}
|
|
@@ -485,10 +485,6 @@ function processWaitQueue(pool) {
|
|
|
485
485
|
return;
|
|
486
486
|
}
|
|
487
487
|
|
|
488
|
-
if (waitQueueMember[kCancelled]) {
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
488
|
if (err) {
|
|
493
489
|
pool.emit('connectionCheckOutFailed', new ConnectionCheckOutFailedEvent(pool, err));
|
|
494
490
|
} else {
|
package/lib/core/auth/gssapi.js
CHANGED
|
@@ -5,88 +5,44 @@ const AuthProvider = require('./auth_provider').AuthProvider;
|
|
|
5
5
|
const retrieveKerberos = require('../utils').retrieveKerberos;
|
|
6
6
|
const MongoError = require('../error').MongoError;
|
|
7
7
|
|
|
8
|
-
const kGssapiClient = Symbol('GSSAPI_CLIENT');
|
|
9
8
|
let kerberos;
|
|
10
9
|
|
|
11
10
|
class GSSAPI extends AuthProvider {
|
|
12
|
-
prepare(handshakeDoc, authContext, callback) {
|
|
13
|
-
const host = authContext.options.host;
|
|
14
|
-
const port = authContext.options.port;
|
|
15
|
-
const credentials = authContext.credentials;
|
|
16
|
-
if (!host || !port || !credentials) {
|
|
17
|
-
return callback(
|
|
18
|
-
new MongoError(
|
|
19
|
-
`Connection must specify: ${host ? 'host' : ''}, ${port ? 'port' : ''}, ${
|
|
20
|
-
credentials ? 'host' : 'credentials'
|
|
21
|
-
}.`
|
|
22
|
-
)
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
if (kerberos == null) {
|
|
26
|
-
try {
|
|
27
|
-
kerberos = retrieveKerberos();
|
|
28
|
-
} catch (e) {
|
|
29
|
-
return callback(e);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const username = credentials.username;
|
|
33
|
-
const password = credentials.password;
|
|
34
|
-
const mechanismProperties = credentials.mechanismProperties;
|
|
35
|
-
const serviceName =
|
|
36
|
-
mechanismProperties['gssapiservicename'] ||
|
|
37
|
-
mechanismProperties['gssapiServiceName'] ||
|
|
38
|
-
'mongodb';
|
|
39
|
-
performGssapiCanonicalizeHostName(host, mechanismProperties, (err, host) => {
|
|
40
|
-
if (err) return callback(err);
|
|
41
|
-
const initOptions = {};
|
|
42
|
-
if (password != null) {
|
|
43
|
-
Object.assign(initOptions, { user: username, password: password });
|
|
44
|
-
}
|
|
45
|
-
kerberos.initializeClient(
|
|
46
|
-
`${serviceName}${process.platform === 'win32' ? '/' : '@'}${host}`,
|
|
47
|
-
initOptions,
|
|
48
|
-
(err, client) => {
|
|
49
|
-
if (err) return callback(new MongoError(err));
|
|
50
|
-
if (client == null) return callback();
|
|
51
|
-
this[kGssapiClient] = client;
|
|
52
|
-
callback(undefined, handshakeDoc);
|
|
53
|
-
}
|
|
54
|
-
);
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
11
|
auth(authContext, callback) {
|
|
58
12
|
const connection = authContext.connection;
|
|
59
13
|
const credentials = authContext.credentials;
|
|
60
14
|
if (credentials == null) return callback(new MongoError('credentials required'));
|
|
61
15
|
const username = credentials.username;
|
|
62
|
-
const client = this[kGssapiClient];
|
|
63
|
-
if (client == null) return callback(new MongoError('gssapi client missing'));
|
|
64
16
|
function externalCommand(command, cb) {
|
|
65
17
|
return connection.command('$external.$cmd', command, cb);
|
|
66
18
|
}
|
|
67
|
-
|
|
19
|
+
makeKerberosClient(authContext, (err, client) => {
|
|
68
20
|
if (err) return callback(err);
|
|
69
|
-
|
|
70
|
-
|
|
21
|
+
if (client == null) return callback(new MongoError('gssapi client missing'));
|
|
22
|
+
client.step('', (err, payload) => {
|
|
71
23
|
if (err) return callback(err);
|
|
72
|
-
|
|
24
|
+
externalCommand(saslStart(payload), (err, response) => {
|
|
73
25
|
if (err) return callback(err);
|
|
74
|
-
|
|
75
|
-
|
|
26
|
+
const result = response.result;
|
|
27
|
+
negotiate(client, 10, result.payload, (err, payload) => {
|
|
76
28
|
if (err) return callback(err);
|
|
77
|
-
|
|
29
|
+
externalCommand(saslContinue(payload, result.conversationId), (err, response) => {
|
|
78
30
|
if (err) return callback(err);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
31
|
+
const result = response.result;
|
|
32
|
+
finalize(client, username, result.payload, (err, payload) => {
|
|
33
|
+
if (err) return callback(err);
|
|
34
|
+
externalCommand(
|
|
35
|
+
{
|
|
36
|
+
saslContinue: 1,
|
|
37
|
+
conversationId: result.conversationId,
|
|
38
|
+
payload
|
|
39
|
+
},
|
|
40
|
+
(err, result) => {
|
|
41
|
+
if (err) return callback(err);
|
|
42
|
+
callback(undefined, result);
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
});
|
|
90
46
|
});
|
|
91
47
|
});
|
|
92
48
|
});
|
|
@@ -96,6 +52,50 @@ class GSSAPI extends AuthProvider {
|
|
|
96
52
|
}
|
|
97
53
|
module.exports = GSSAPI;
|
|
98
54
|
|
|
55
|
+
function makeKerberosClient(authContext, callback) {
|
|
56
|
+
const host = authContext.options.host;
|
|
57
|
+
const port = authContext.options.port;
|
|
58
|
+
const credentials = authContext.credentials;
|
|
59
|
+
if (!host || !port || !credentials) {
|
|
60
|
+
return callback(
|
|
61
|
+
new MongoError(
|
|
62
|
+
`Connection must specify: ${host ? 'host' : ''}, ${port ? 'port' : ''}, ${
|
|
63
|
+
credentials ? 'host' : 'credentials'
|
|
64
|
+
}.`
|
|
65
|
+
)
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (kerberos == null) {
|
|
69
|
+
try {
|
|
70
|
+
kerberos = retrieveKerberos();
|
|
71
|
+
} catch (e) {
|
|
72
|
+
return callback(e);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const username = credentials.username;
|
|
76
|
+
const password = credentials.password;
|
|
77
|
+
const mechanismProperties = credentials.mechanismProperties;
|
|
78
|
+
const serviceName =
|
|
79
|
+
mechanismProperties['gssapiservicename'] ||
|
|
80
|
+
mechanismProperties['gssapiServiceName'] ||
|
|
81
|
+
'mongodb';
|
|
82
|
+
performGssapiCanonicalizeHostName(host, mechanismProperties, (err, host) => {
|
|
83
|
+
if (err) return callback(err);
|
|
84
|
+
const initOptions = {};
|
|
85
|
+
if (password != null) {
|
|
86
|
+
Object.assign(initOptions, { user: username, password: password });
|
|
87
|
+
}
|
|
88
|
+
kerberos.initializeClient(
|
|
89
|
+
`${serviceName}${process.platform === 'win32' ? '/' : '@'}${host}`,
|
|
90
|
+
initOptions,
|
|
91
|
+
(err, client) => {
|
|
92
|
+
if (err) return callback(new MongoError(err));
|
|
93
|
+
callback(null, client);
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
99
|
function saslStart(payload) {
|
|
100
100
|
return {
|
|
101
101
|
saslStart: 1,
|
package/lib/core/auth/x509.js
CHANGED
|
@@ -26,7 +26,7 @@ class X509 extends AuthProvider {
|
|
|
26
26
|
function x509AuthenticateCommand(credentials) {
|
|
27
27
|
const command = { authenticate: 1, mechanism: 'MONGODB-X509' };
|
|
28
28
|
if (credentials.username) {
|
|
29
|
-
Object.
|
|
29
|
+
Object.assign(command, { user: credentials.username });
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
return command;
|
|
@@ -263,7 +263,7 @@ function makeConnection(family, options, cancellationToken, _callback) {
|
|
|
263
263
|
: typeof options.connectTimeoutMS === 'number'
|
|
264
264
|
? options.connectTimeoutMS
|
|
265
265
|
: 30000;
|
|
266
|
-
const socketTimeout = typeof options.socketTimeout === 'number' ? options.socketTimeout :
|
|
266
|
+
const socketTimeout = typeof options.socketTimeout === 'number' ? options.socketTimeout : 0;
|
|
267
267
|
const rejectUnauthorized =
|
|
268
268
|
typeof options.rejectUnauthorized === 'boolean' ? options.rejectUnauthorized : true;
|
|
269
269
|
|
|
@@ -69,7 +69,7 @@ class Connection extends EventEmitter {
|
|
|
69
69
|
* @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
|
|
70
70
|
* @param {number} [options.keepAliveInitialDelay=120000] Initial delay before TCP keep alive enabled
|
|
71
71
|
* @param {number} [options.connectionTimeout=30000] TCP Connection timeout setting
|
|
72
|
-
* @param {number} [options.socketTimeout=
|
|
72
|
+
* @param {number} [options.socketTimeout=0] TCP Socket timeout setting
|
|
73
73
|
* @param {boolean} [options.promoteLongs] Convert Long values from the db into Numbers if they fit into 53 bits
|
|
74
74
|
* @param {boolean} [options.promoteValues] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
|
|
75
75
|
* @param {boolean} [options.promoteBuffers] Promotes Binary BSON values to native Node Buffers.
|
|
@@ -92,7 +92,7 @@ class Connection extends EventEmitter {
|
|
|
92
92
|
|
|
93
93
|
this.port = options.port || 27017;
|
|
94
94
|
this.host = options.host || 'localhost';
|
|
95
|
-
this.socketTimeout = typeof options.socketTimeout === 'number' ? options.socketTimeout :
|
|
95
|
+
this.socketTimeout = typeof options.socketTimeout === 'number' ? options.socketTimeout : 0;
|
|
96
96
|
|
|
97
97
|
// These values are inspected directly in tests, but maybe not necessary to keep around
|
|
98
98
|
this.keepAlive = typeof options.keepAlive === 'boolean' ? options.keepAlive : true;
|
|
@@ -316,8 +316,7 @@ class Connection extends EventEmitter {
|
|
|
316
316
|
if (typeof options === 'function') (callback = options), (options = {});
|
|
317
317
|
|
|
318
318
|
const conn = this;
|
|
319
|
-
const socketTimeout =
|
|
320
|
-
typeof options.socketTimeout === 'number' ? options.socketTimeout : 360000;
|
|
319
|
+
const socketTimeout = typeof options.socketTimeout === 'number' ? options.socketTimeout : 0;
|
|
321
320
|
const bson = conn.options.bson;
|
|
322
321
|
const query = new Query(bson, ns, command, {
|
|
323
322
|
numberToSkip: 0,
|
|
@@ -63,8 +63,8 @@ var _id = 0;
|
|
|
63
63
|
* @param {number} [options.keepAliveInitialDelay=120000] Initial delay before TCP keep alive enabled
|
|
64
64
|
* @param {boolean} [options.noDelay=true] TCP Connection no delay
|
|
65
65
|
* @param {number} [options.connectionTimeout=30000] TCP Connection timeout setting
|
|
66
|
-
* @param {number} [options.socketTimeout=
|
|
67
|
-
* @param {number} [options.monitoringSocketTimeout=
|
|
66
|
+
* @param {number} [options.socketTimeout=0] TCP Socket timeout setting
|
|
67
|
+
* @param {number} [options.monitoringSocketTimeout=0] TCP Socket timeout setting for replicaset monitoring socket
|
|
68
68
|
* @param {boolean} [options.ssl=false] Use SSL for connection
|
|
69
69
|
* @param {boolean|function} [options.checkServerIdentity=true] Ensure we check server identify during SSL, set to false to disable checking. Only works for Node 0.12.x or higher. You can pass in a boolean or your own checkServerIdentity override function.
|
|
70
70
|
* @param {Buffer} [options.ca] SSL Certificate store binary buffer
|
|
@@ -111,7 +111,7 @@ var Pool = function(topology, options) {
|
|
|
111
111
|
minSize: 0,
|
|
112
112
|
// socket settings
|
|
113
113
|
connectionTimeout: 30000,
|
|
114
|
-
socketTimeout:
|
|
114
|
+
socketTimeout: 0,
|
|
115
115
|
keepAlive: true,
|
|
116
116
|
keepAliveInitialDelay: 120000,
|
|
117
117
|
noDelay: true,
|
|
@@ -919,7 +919,7 @@ ReplSet.prototype.connect = function(options) {
|
|
|
919
919
|
);
|
|
920
920
|
});
|
|
921
921
|
|
|
922
|
-
// Error out as high
|
|
922
|
+
// Error out as high availability interval must be < than socketTimeout
|
|
923
923
|
if (
|
|
924
924
|
this.s.options.socketTimeout > 0 &&
|
|
925
925
|
this.s.options.socketTimeout <= this.s.options.haInterval
|
|
@@ -75,7 +75,7 @@ function topologyId(server) {
|
|
|
75
75
|
* @param {number} [options.keepAliveInitialDelay=120000] Initial delay before TCP keep alive enabled
|
|
76
76
|
* @param {boolean} [options.noDelay=true] TCP Connection no delay
|
|
77
77
|
* @param {number} [options.connectionTimeout=30000] TCP Connection timeout setting
|
|
78
|
-
* @param {number} [options.socketTimeout=
|
|
78
|
+
* @param {number} [options.socketTimeout=0] TCP Socket timeout setting
|
|
79
79
|
* @param {boolean} [options.ssl=false] Use SSL for connection
|
|
80
80
|
* @param {boolean|function} [options.checkServerIdentity=true] Ensure we check server identify during SSL, set to false to disable checking. Only works for Node 0.12.x or higher. You can pass in a boolean or your own checkServerIdentity override function.
|
|
81
81
|
* @param {Buffer} [options.ca] SSL Certificate store binary buffer
|
|
@@ -389,7 +389,7 @@ var eventHandler = function(self, event) {
|
|
|
389
389
|
event === 'timeout' ||
|
|
390
390
|
event === 'reconnect' ||
|
|
391
391
|
event === 'attemptReconnect' ||
|
|
392
|
-
'reconnectFailed'
|
|
392
|
+
event === 'reconnectFailed'
|
|
393
393
|
) {
|
|
394
394
|
// Remove server instance from accounting
|
|
395
395
|
if (
|
package/lib/core/uri_parser.js
CHANGED
|
@@ -687,15 +687,6 @@ function parseConnectionString(uri, options, callback) {
|
|
|
687
687
|
return callback(new MongoParseError('directConnection option requires exactly one host'));
|
|
688
688
|
}
|
|
689
689
|
|
|
690
|
-
// NOTE: this behavior will go away in v4.0, we will always auto discover there
|
|
691
|
-
if (
|
|
692
|
-
parsedOptions.directConnection == null &&
|
|
693
|
-
hosts.length === 1 &&
|
|
694
|
-
parsedOptions.replicaSet == null
|
|
695
|
-
) {
|
|
696
|
-
parsedOptions.directConnection = true;
|
|
697
|
-
}
|
|
698
|
-
|
|
699
690
|
const result = {
|
|
700
691
|
hosts: hosts,
|
|
701
692
|
auth: auth.db || auth.username ? auth : null,
|
package/lib/gridfs/grid_store.js
CHANGED
|
@@ -153,6 +153,7 @@ var GridStore = function GridStore(db, id, filename, mode, options) {
|
|
|
153
153
|
},
|
|
154
154
|
set: function(value) {
|
|
155
155
|
if (!(this.mode[0] === 'w' && this.position === 0 && this.uploadDate == null)) {
|
|
156
|
+
// eslint-disable-next-line no-self-assign
|
|
156
157
|
this.internalChunkSize = this.internalChunkSize;
|
|
157
158
|
} else {
|
|
158
159
|
this.internalChunkSize = value;
|
package/lib/mongo_client.js
CHANGED
|
@@ -97,7 +97,7 @@ const validOptions = require('./operations/connect').validOptions;
|
|
|
97
97
|
* @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
|
|
98
98
|
* @param {number} [options.keepAliveInitialDelay=120000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
|
|
99
99
|
* @param {number} [options.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
|
|
100
|
-
* @param {number} [options.socketTimeoutMS=
|
|
100
|
+
* @param {number} [options.socketTimeoutMS=0] How long a send or receive on a socket can take before timing out
|
|
101
101
|
* @param {number} [options.family] Version of IP stack. Can be 4, 6 or null (default).
|
|
102
102
|
* If null, will attempt to connect with IPv6, and will fall back to IPv4 on failure
|
|
103
103
|
* @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
|
|
@@ -169,6 +169,7 @@ function MongoClient(url, options) {
|
|
|
169
169
|
dbCache: new Map(),
|
|
170
170
|
sessions: new Set(),
|
|
171
171
|
writeConcern: WriteConcern.fromOptions(options),
|
|
172
|
+
readPreference: ReadPreference.fromOptions(options) || ReadPreference.primary,
|
|
172
173
|
namespace: new MongoDBNamespace('admin')
|
|
173
174
|
};
|
|
174
175
|
}
|
|
@@ -188,7 +189,7 @@ Object.defineProperty(MongoClient.prototype, 'writeConcern', {
|
|
|
188
189
|
Object.defineProperty(MongoClient.prototype, 'readPreference', {
|
|
189
190
|
enumerable: true,
|
|
190
191
|
get: function() {
|
|
191
|
-
return
|
|
192
|
+
return this.s.readPreference;
|
|
192
193
|
}
|
|
193
194
|
});
|
|
194
195
|
|
|
@@ -371,7 +372,7 @@ MongoClient.prototype.isConnected = function(options) {
|
|
|
371
372
|
* @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
|
|
372
373
|
* @param {number} [options.keepAliveInitialDelay=120000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
|
|
373
374
|
* @param {number} [options.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
|
|
374
|
-
* @param {number} [options.socketTimeoutMS=
|
|
375
|
+
* @param {number} [options.socketTimeoutMS=0] How long a send or receive on a socket can take before timing out
|
|
375
376
|
* @param {number} [options.family] Version of IP stack. Can be 4, 6 or null (default).
|
|
376
377
|
* If null, will attempt to connect with IPv6, and will fall back to IPv4 on failure
|
|
377
378
|
* @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
|
|
@@ -22,7 +22,9 @@ class AddUserOperation extends CommandOperation {
|
|
|
22
22
|
const options = this.options;
|
|
23
23
|
|
|
24
24
|
// Get additional values
|
|
25
|
-
let roles =
|
|
25
|
+
let roles = [];
|
|
26
|
+
if (Array.isArray(options.roles)) roles = options.roles;
|
|
27
|
+
if (typeof options.roles === 'string') roles = [options.roles];
|
|
26
28
|
|
|
27
29
|
// If not roles defined print deprecated message
|
|
28
30
|
// TODO: handle deprecation properly
|
|
@@ -39,7 +39,7 @@ function validateCollection(admin, collectionName, options, callback) {
|
|
|
39
39
|
|
|
40
40
|
// Decorate command with extra options
|
|
41
41
|
for (let i = 0; i < keys.length; i++) {
|
|
42
|
-
if (
|
|
42
|
+
if (Object.prototype.hasOwnProperty.call(options, keys[i]) && keys[i] !== 'session') {
|
|
43
43
|
command[keys[i]] = options[keys[i]];
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -17,7 +17,9 @@ class CommandOperationV2 extends OperationBase {
|
|
|
17
17
|
|
|
18
18
|
this.ns = parent.s.namespace.withCollection('$cmd');
|
|
19
19
|
const propertyProvider = this.hasAspect(Aspect.NO_INHERIT_OPTIONS) ? undefined : parent;
|
|
20
|
-
this.readPreference =
|
|
20
|
+
this.readPreference = this.hasAspect(Aspect.WRITE_OPERATION)
|
|
21
|
+
? ReadPreference.primary
|
|
22
|
+
: ReadPreference.resolve(propertyProvider, this.options);
|
|
21
23
|
this.readConcern = resolveReadConcern(propertyProvider, this.options);
|
|
22
24
|
this.writeConcern = resolveWriteConcern(propertyProvider, this.options);
|
|
23
25
|
this.explain = false;
|
|
@@ -290,7 +290,7 @@ function connect(mongoClient, url, options, callback) {
|
|
|
290
290
|
const _finalOptions = createUnifiedOptions(object, options);
|
|
291
291
|
|
|
292
292
|
// Check if we have connection and socket timeout set
|
|
293
|
-
if (_finalOptions.socketTimeoutMS == null) _finalOptions.socketTimeoutMS =
|
|
293
|
+
if (_finalOptions.socketTimeoutMS == null) _finalOptions.socketTimeoutMS = 0;
|
|
294
294
|
if (_finalOptions.connectTimeoutMS == null) _finalOptions.connectTimeoutMS = 10000;
|
|
295
295
|
if (_finalOptions.retryWrites == null) _finalOptions.retryWrites = true;
|
|
296
296
|
if (_finalOptions.useRecoveryToken == null) _finalOptions.useRecoveryToken = true;
|
|
@@ -788,7 +788,7 @@ function translateOptions(options, translationOptions) {
|
|
|
788
788
|
}
|
|
789
789
|
|
|
790
790
|
// Set the socket and connection timeouts
|
|
791
|
-
if (options.socketTimeoutMS == null) options.socketTimeoutMS =
|
|
791
|
+
if (options.socketTimeoutMS == null) options.socketTimeoutMS = 0;
|
|
792
792
|
if (options.connectTimeoutMS == null) options.connectTimeoutMS = 10000;
|
|
793
793
|
|
|
794
794
|
if (!translationOptions.createServers) {
|
|
@@ -8,7 +8,7 @@ class ValidateCollectionOperation extends CommandOperation {
|
|
|
8
8
|
let command = { validate: collectionName };
|
|
9
9
|
const keys = Object.keys(options);
|
|
10
10
|
for (let i = 0; i < keys.length; i++) {
|
|
11
|
-
if (
|
|
11
|
+
if (Object.prototype.hasOwnProperty.call(options, keys[i]) && keys[i] !== 'session') {
|
|
12
12
|
command[keys[i]] = options[keys[i]];
|
|
13
13
|
}
|
|
14
14
|
}
|
package/lib/topologies/mongos.js
CHANGED
|
@@ -84,7 +84,7 @@ var legalOptionNames = [
|
|
|
84
84
|
* @param {boolean} [options.socketOptions.keepAlive=true] TCP Connection keep alive enabled
|
|
85
85
|
* @param {number} [options.socketOptions.keepAliveInitialDelay=120000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
|
|
86
86
|
* @param {number} [options.socketOptions.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
|
|
87
|
-
* @param {number} [options.socketOptions.socketTimeoutMS=
|
|
87
|
+
* @param {number} [options.socketOptions.socketTimeoutMS=0] How long a send or receive on a socket can take before timing out
|
|
88
88
|
* @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit.
|
|
89
89
|
* @param {boolean} [options.monitorCommands=false] Enable command monitoring for this topology
|
|
90
90
|
* @fires Mongos#connect
|
package/lib/topologies/server.js
CHANGED
|
@@ -86,7 +86,7 @@ var legalOptionNames = [
|
|
|
86
86
|
* @param {boolean} [options.socketOptions.keepAlive=true] TCP Connection keep alive enabled
|
|
87
87
|
* @param {number} [options.socketOptions.keepAliveInitialDelay=120000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
|
|
88
88
|
* @param {number} [options.socketOptions.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
|
|
89
|
-
* @param {number} [options.socketOptions.socketTimeoutMS=
|
|
89
|
+
* @param {number} [options.socketOptions.socketTimeoutMS=0] How long a send or receive on a socket can take before timing out
|
|
90
90
|
* @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
|
|
91
91
|
* @param {number} [options.reconnectInterval=1000] Server will wait # milliseconds between retries
|
|
92
92
|
* @param {boolean} [options.monitoring=true] Triggers the server instance to call ismaster
|
package/lib/utils.js
CHANGED
|
@@ -565,7 +565,10 @@ function deprecateOptions(config, fn) {
|
|
|
565
565
|
}
|
|
566
566
|
|
|
567
567
|
config.deprecatedOptions.forEach(deprecatedOption => {
|
|
568
|
-
if (
|
|
568
|
+
if (
|
|
569
|
+
Object.prototype.hasOwnProperty.call(options, deprecatedOption) &&
|
|
570
|
+
!optionsWarned.has(deprecatedOption)
|
|
571
|
+
) {
|
|
569
572
|
optionsWarned.add(deprecatedOption);
|
|
570
573
|
const msg = msgHandler(config.name, deprecatedOption);
|
|
571
574
|
emitDeprecationWarning(msg);
|
|
@@ -713,12 +716,13 @@ function makeInterruptableAsyncInterval(fn, options) {
|
|
|
713
716
|
const interval = options.interval || 1000;
|
|
714
717
|
const minInterval = options.minInterval || 500;
|
|
715
718
|
const immediate = typeof options.immediate === 'boolean' ? options.immediate : false;
|
|
719
|
+
const clock = typeof options.clock === 'function' ? options.clock : now;
|
|
716
720
|
|
|
717
721
|
function wake() {
|
|
718
|
-
const currentTime =
|
|
722
|
+
const currentTime = clock();
|
|
719
723
|
const timeSinceLastWake = currentTime - lastWakeTime;
|
|
720
724
|
const timeSinceLastCall = currentTime - lastCallTime;
|
|
721
|
-
const timeUntilNextCall =
|
|
725
|
+
const timeUntilNextCall = interval - timeSinceLastCall;
|
|
722
726
|
lastWakeTime = currentTime;
|
|
723
727
|
|
|
724
728
|
// For the streaming protocol: there is nothing obviously stopping this
|
|
@@ -737,6 +741,14 @@ function makeInterruptableAsyncInterval(fn, options) {
|
|
|
737
741
|
if (timeUntilNextCall > minInterval) {
|
|
738
742
|
reschedule(minInterval);
|
|
739
743
|
}
|
|
744
|
+
|
|
745
|
+
// This is possible in virtualized environments like AWS Lambda where our
|
|
746
|
+
// clock is unreliable. In these cases the timer is "running" but never
|
|
747
|
+
// actually completes, so we want to execute immediately and then attempt
|
|
748
|
+
// to reschedule.
|
|
749
|
+
if (timeUntilNextCall < 0) {
|
|
750
|
+
executeAndReschedule();
|
|
751
|
+
}
|
|
740
752
|
}
|
|
741
753
|
|
|
742
754
|
function stop() {
|
|
@@ -758,7 +770,7 @@ function makeInterruptableAsyncInterval(fn, options) {
|
|
|
758
770
|
|
|
759
771
|
function executeAndReschedule() {
|
|
760
772
|
lastWakeTime = 0;
|
|
761
|
-
lastCallTime =
|
|
773
|
+
lastCallTime = clock();
|
|
762
774
|
|
|
763
775
|
fn(err => {
|
|
764
776
|
if (err) throw err;
|
|
@@ -769,7 +781,7 @@ function makeInterruptableAsyncInterval(fn, options) {
|
|
|
769
781
|
if (immediate) {
|
|
770
782
|
executeAndReschedule();
|
|
771
783
|
} else {
|
|
772
|
-
lastCallTime =
|
|
784
|
+
lastCallTime = clock();
|
|
773
785
|
reschedule();
|
|
774
786
|
}
|
|
775
787
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongodb",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.3",
|
|
4
4
|
"description": "The official MongoDB driver for Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -23,6 +23,26 @@
|
|
|
23
23
|
"snappy": "^6.3.4",
|
|
24
24
|
"bson-ext": "^2.0.0"
|
|
25
25
|
},
|
|
26
|
+
"peerDependenciesMeta": {
|
|
27
|
+
"kerberos": {
|
|
28
|
+
"optional": true
|
|
29
|
+
},
|
|
30
|
+
"mongodb-client-encryption": {
|
|
31
|
+
"optional": true
|
|
32
|
+
},
|
|
33
|
+
"mongodb-extjson": {
|
|
34
|
+
"optional": true
|
|
35
|
+
},
|
|
36
|
+
"snappy": {
|
|
37
|
+
"optional": true
|
|
38
|
+
},
|
|
39
|
+
"bson-ext": {
|
|
40
|
+
"optional": true
|
|
41
|
+
},
|
|
42
|
+
"aws4": {
|
|
43
|
+
"optional": true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
26
46
|
"dependencies": {
|
|
27
47
|
"bl": "^2.2.1",
|
|
28
48
|
"bson": "^1.1.4",
|
|
@@ -36,8 +56,10 @@
|
|
|
36
56
|
"chalk": "^2.4.2",
|
|
37
57
|
"co": "4.6.0",
|
|
38
58
|
"coveralls": "^2.11.6",
|
|
39
|
-
"eslint": "^
|
|
40
|
-
"eslint-
|
|
59
|
+
"eslint": "^7.10.0",
|
|
60
|
+
"eslint-config-prettier": "^6.11.0",
|
|
61
|
+
"eslint-plugin-es": "^3.0.1",
|
|
62
|
+
"eslint-plugin-prettier": "^3.1.3",
|
|
41
63
|
"istanbul": "^0.4.5",
|
|
42
64
|
"jsdoc": "3.5.5",
|
|
43
65
|
"lodash.camelcase": "^4.3.0",
|
|
@@ -68,11 +90,11 @@
|
|
|
68
90
|
"check:kerberos": "mocha --opts '{}' -t 60000 test/manual/kerberos.test.js",
|
|
69
91
|
"check:ldap": "mocha --opts '{}' test/manual/ldap.test.js",
|
|
70
92
|
"check:tls": "mocha --opts '{}' test/manual/tls_support.test.js",
|
|
71
|
-
"test": "npm run lint && mocha --recursive test/functional test/unit
|
|
72
|
-
"test-nolint": "mocha --recursive test/functional test/unit
|
|
73
|
-
"coverage": "istanbul cover mongodb-test-runner -- -t 60000 test/
|
|
93
|
+
"test": "npm run lint && mocha --recursive test/functional test/unit",
|
|
94
|
+
"test-nolint": "mocha --recursive test/functional test/unit",
|
|
95
|
+
"coverage": "istanbul cover mongodb-test-runner -- -t 60000 test/unit test/functional",
|
|
74
96
|
"lint": "eslint -v && eslint lib test",
|
|
75
|
-
"format": "
|
|
97
|
+
"format": "npm run lint -- --fix",
|
|
76
98
|
"bench": "node test/benchmarks/driverBench/",
|
|
77
99
|
"generate-evergreen": "node .evergreen/generate_evergreen_tasks.js",
|
|
78
100
|
"release": "standard-version -i HISTORY.md"
|