mongodb 4.1.4 → 4.3.0
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/README.md +16 -15
- package/lib/admin.js +3 -3
- package/lib/admin.js.map +1 -1
- package/lib/bson.js +16 -14
- package/lib/bson.js.map +1 -1
- package/lib/bulk/common.js +3 -4
- package/lib/bulk/common.js.map +1 -1
- package/lib/bulk/ordered.js +1 -1
- package/lib/bulk/ordered.js.map +1 -1
- package/lib/bulk/unordered.js +1 -1
- package/lib/bulk/unordered.js.map +1 -1
- package/lib/change_stream.js +6 -7
- package/lib/change_stream.js.map +1 -1
- package/lib/cmap/auth/auth_provider.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +3 -3
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +16 -18
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/auth/mongocr.js +2 -2
- package/lib/cmap/auth/mongocr.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +6 -6
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/plain.js +1 -1
- package/lib/cmap/auth/plain.js.map +1 -1
- package/lib/cmap/auth/providers.js +21 -0
- package/lib/cmap/auth/providers.js.map +1 -0
- package/lib/cmap/auth/scram.js +4 -4
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js +1 -1
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +1 -1
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +20 -11
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +102 -15
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +27 -26
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +19 -30
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/message_stream.js +3 -3
- package/lib/cmap/message_stream.js.map +1 -1
- package/lib/cmap/stream_description.js +4 -4
- package/lib/cmap/stream_description.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/cmap/wire_protocol/constants.js +4 -4
- package/lib/cmap/wire_protocol/shared.js +4 -3
- package/lib/cmap/wire_protocol/shared.js.map +1 -1
- package/lib/collection.js +46 -47
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +106 -49
- package/lib/connection_string.js.map +1 -1
- package/lib/constants.js +108 -1
- package/lib/constants.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +10 -7
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +1 -1
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +1 -1
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/db.js +23 -13
- package/lib/db.js.map +1 -1
- package/lib/deps.js +0 -1
- package/lib/deps.js.map +1 -1
- package/lib/encrypter.js +12 -4
- package/lib/encrypter.js.map +1 -1
- package/lib/error.js +47 -24
- package/lib/error.js.map +1 -1
- package/lib/gridfs/download.js +1 -1
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/index.js +3 -3
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js +3 -2
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/index.js +81 -81
- package/lib/index.js.map +1 -1
- package/lib/logger.js +1 -1
- package/lib/logger.js.map +1 -1
- package/lib/mongo_client.js +5 -5
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_types.js.map +1 -1
- package/lib/operations/add_user.js +2 -2
- package/lib/operations/add_user.js.map +1 -1
- package/lib/operations/aggregate.js +2 -3
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/bulk_write.js.map +1 -1
- package/lib/operations/collections.js +1 -1
- package/lib/operations/collections.js.map +1 -1
- package/lib/operations/command.js +9 -6
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/common_functions.js.map +1 -1
- package/lib/operations/connect.js +4 -13
- package/lib/operations/connect.js.map +1 -1
- package/lib/operations/count.js +1 -1
- package/lib/operations/count.js.map +1 -1
- package/lib/operations/count_documents.js.map +1 -1
- package/lib/operations/create_collection.js +3 -2
- package/lib/operations/create_collection.js.map +1 -1
- package/lib/operations/delete.js +3 -3
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/distinct.js +3 -3
- package/lib/operations/distinct.js.map +1 -1
- package/lib/operations/drop.js +1 -1
- package/lib/operations/drop.js.map +1 -1
- package/lib/operations/estimated_document_count.js +2 -2
- package/lib/operations/estimated_document_count.js.map +1 -1
- package/lib/operations/eval.js +2 -2
- package/lib/operations/eval.js.map +1 -1
- package/lib/operations/execute_operation.js +23 -7
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +5 -5
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/find_and_modify.js +2 -2
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/get_more.js +28 -0
- package/lib/operations/get_more.js.map +1 -0
- package/lib/operations/indexes.js +4 -4
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +3 -3
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/is_capped.js +1 -1
- package/lib/operations/is_capped.js.map +1 -1
- package/lib/operations/list_collections.js +11 -6
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/list_databases.js +1 -1
- package/lib/operations/list_databases.js.map +1 -1
- package/lib/operations/map_reduce.js +4 -3
- package/lib/operations/map_reduce.js.map +1 -1
- package/lib/operations/operation.js +4 -2
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/options_operation.js +1 -1
- package/lib/operations/options_operation.js.map +1 -1
- package/lib/operations/profiling_level.js +1 -1
- package/lib/operations/profiling_level.js.map +1 -1
- package/lib/operations/remove_user.js +1 -1
- package/lib/operations/remove_user.js.map +1 -1
- package/lib/operations/rename.js +3 -3
- package/lib/operations/rename.js.map +1 -1
- package/lib/operations/run_command.js +1 -1
- package/lib/operations/run_command.js.map +1 -1
- package/lib/operations/set_profiling_level.js +2 -2
- package/lib/operations/set_profiling_level.js.map +1 -1
- package/lib/operations/stats.js +1 -1
- package/lib/operations/stats.js.map +1 -1
- package/lib/operations/update.js +2 -2
- package/lib/operations/update.js.map +1 -1
- package/lib/operations/validate_collection.js +1 -1
- package/lib/operations/validate_collection.js.map +1 -1
- package/lib/read_preference.js +15 -5
- package/lib/read_preference.js.map +1 -1
- package/lib/sdam/monitor.js +4 -4
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server.js +31 -31
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_description.js +1 -1
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/server_selection.js +38 -3
- package/lib/sdam/server_selection.js.map +1 -1
- package/lib/sdam/srv_polling.js +11 -11
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +40 -62
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +36 -14
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +13 -28
- package/lib/sessions.js.map +1 -1
- package/lib/transactions.js +1 -1
- package/lib/transactions.js.map +1 -1
- package/lib/utils.js +90 -23
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +159 -65
- package/mongodb.ts34.d.ts +184 -65
- package/package.json +26 -24
- package/src/admin.ts +9 -9
- package/src/bson.ts +26 -17
- package/src/bulk/common.ts +26 -20
- package/src/bulk/ordered.ts +4 -4
- package/src/bulk/unordered.ts +5 -5
- package/src/change_stream.ts +35 -32
- package/src/cmap/auth/auth_provider.ts +3 -3
- package/src/cmap/auth/gssapi.ts +8 -8
- package/src/cmap/auth/mongo_credentials.ts +2 -6
- package/src/cmap/auth/mongocr.ts +3 -2
- package/src/cmap/auth/mongodb_aws.ts +10 -11
- package/src/cmap/auth/plain.ts +1 -1
- package/src/cmap/auth/providers.ts +21 -0
- package/src/cmap/auth/scram.ts +9 -9
- package/src/cmap/auth/x509.ts +3 -3
- package/src/cmap/command_monitoring_events.ts +2 -2
- package/src/cmap/commands.ts +30 -19
- package/src/cmap/connect.ts +142 -22
- package/src/cmap/connection.ts +73 -52
- package/src/cmap/connection_pool.ts +39 -39
- package/src/cmap/connection_pool_events.ts +1 -1
- package/src/cmap/message_stream.ts +9 -8
- package/src/cmap/stream_description.ts +5 -5
- package/src/cmap/wire_protocol/compression.ts +2 -2
- package/src/cmap/wire_protocol/constants.ts +4 -4
- package/src/cmap/wire_protocol/shared.ts +10 -9
- package/src/collection.ts +133 -106
- package/src/connection_string.ts +141 -60
- package/src/constants.ts +116 -0
- package/src/cursor/abstract_cursor.ts +21 -22
- package/src/cursor/aggregation_cursor.ts +6 -6
- package/src/cursor/find_cursor.ts +2 -2
- package/src/db.ts +49 -39
- package/src/deps.ts +3 -1
- package/src/encrypter.ts +12 -3
- package/src/error.ts +52 -24
- package/src/gridfs/download.ts +10 -8
- package/src/gridfs/index.ts +11 -11
- package/src/gridfs/upload.ts +13 -10
- package/src/index.ts +204 -199
- package/src/logger.ts +2 -1
- package/src/mongo_client.ts +58 -32
- package/src/mongo_types.ts +98 -20
- package/src/operations/add_user.ts +6 -5
- package/src/operations/aggregate.ts +6 -7
- package/src/operations/bulk_write.ts +5 -5
- package/src/operations/collections.ts +2 -2
- package/src/operations/command.ts +19 -8
- package/src/operations/common_functions.ts +4 -4
- package/src/operations/connect.ts +4 -14
- package/src/operations/count.ts +4 -4
- package/src/operations/count_documents.ts +3 -3
- package/src/operations/create_collection.ts +8 -7
- package/src/operations/delete.ts +5 -5
- package/src/operations/distinct.ts +4 -4
- package/src/operations/drop.ts +4 -4
- package/src/operations/estimated_document_count.ts +5 -5
- package/src/operations/eval.ts +5 -5
- package/src/operations/execute_operation.ts +30 -11
- package/src/operations/find.ts +14 -14
- package/src/operations/find_and_modify.ts +7 -7
- package/src/operations/get_more.ts +49 -0
- package/src/operations/indexes.ts +16 -16
- package/src/operations/insert.ts +9 -9
- package/src/operations/is_capped.ts +3 -3
- package/src/operations/list_collections.ts +18 -10
- package/src/operations/list_databases.ts +4 -4
- package/src/operations/map_reduce.ts +10 -9
- package/src/operations/operation.ts +8 -4
- package/src/operations/options_operation.ts +3 -3
- package/src/operations/profiling_level.ts +4 -4
- package/src/operations/remove_user.ts +4 -4
- package/src/operations/rename.ts +6 -6
- package/src/operations/run_command.ts +3 -3
- package/src/operations/set_profiling_level.ts +6 -5
- package/src/operations/stats.ts +4 -4
- package/src/operations/update.ts +10 -10
- package/src/operations/validate_collection.ts +4 -4
- package/src/read_preference.ts +18 -7
- package/src/sdam/common.ts +2 -2
- package/src/sdam/events.ts +1 -1
- package/src/sdam/monitor.ts +13 -14
- package/src/sdam/server.ts +71 -61
- package/src/sdam/server_description.ts +4 -4
- package/src/sdam/server_selection.ts +46 -3
- package/src/sdam/srv_polling.ts +15 -13
- package/src/sdam/topology.ts +89 -90
- package/src/sdam/topology_description.ts +39 -15
- package/src/sessions.ts +31 -48
- package/src/transactions.ts +6 -6
- package/src/utils.ts +123 -43
- package/lib/cmap/auth/defaultAuthProviders.js +0 -30
- package/lib/cmap/auth/defaultAuthProviders.js.map +0 -1
- package/src/cmap/auth/defaultAuthProviders.ts +0 -32
package/src/cmap/commands.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BSONSerializeOptions, Document, Long } from '../bson';
|
|
2
2
|
import * as BSON from '../bson';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import type { Long, Document, BSONSerializeOptions } from '../bson';
|
|
3
|
+
import { MongoInvalidArgumentError, MongoRuntimeError } from '../error';
|
|
4
|
+
import { ReadPreference } from '../read_preference';
|
|
6
5
|
import type { ClientSession } from '../sessions';
|
|
6
|
+
import { databaseNamespace } from '../utils';
|
|
7
7
|
import type { CommandOptions } from './connection';
|
|
8
|
-
import {
|
|
8
|
+
import { OP_GETMORE, OP_KILL_CURSORS, OP_MSG, OP_QUERY } from './wire_protocol/constants';
|
|
9
9
|
|
|
10
10
|
// Incrementing request id
|
|
11
11
|
let _requestId = 0;
|
|
12
12
|
|
|
13
13
|
// Query flags
|
|
14
14
|
const OPTS_TAILABLE_CURSOR = 2;
|
|
15
|
-
const
|
|
15
|
+
const OPTS_SECONDARY = 4;
|
|
16
16
|
const OPTS_OPLOG_REPLAY = 8;
|
|
17
17
|
const OPTS_NO_CURSOR_TIMEOUT = 16;
|
|
18
18
|
const OPTS_AWAIT_DATA = 32;
|
|
@@ -41,7 +41,7 @@ export interface OpQueryOptions extends CommandOptions {
|
|
|
41
41
|
ignoreUndefined?: boolean;
|
|
42
42
|
maxBsonSize?: number;
|
|
43
43
|
checkKeys?: boolean;
|
|
44
|
-
|
|
44
|
+
secondaryOk?: boolean;
|
|
45
45
|
|
|
46
46
|
requestId?: number;
|
|
47
47
|
moreToCome?: boolean;
|
|
@@ -67,7 +67,7 @@ export class Query {
|
|
|
67
67
|
checkKeys: boolean;
|
|
68
68
|
batchSize: number;
|
|
69
69
|
tailable: boolean;
|
|
70
|
-
|
|
70
|
+
secondaryOk: boolean;
|
|
71
71
|
oplogReplay: boolean;
|
|
72
72
|
noCursorTimeout: boolean;
|
|
73
73
|
awaitData: boolean;
|
|
@@ -112,7 +112,7 @@ export class Query {
|
|
|
112
112
|
|
|
113
113
|
// Flags
|
|
114
114
|
this.tailable = false;
|
|
115
|
-
this.
|
|
115
|
+
this.secondaryOk = typeof options.secondaryOk === 'boolean' ? options.secondaryOk : false;
|
|
116
116
|
this.oplogReplay = false;
|
|
117
117
|
this.noCursorTimeout = false;
|
|
118
118
|
this.awaitData = false;
|
|
@@ -146,8 +146,8 @@ export class Query {
|
|
|
146
146
|
flags |= OPTS_TAILABLE_CURSOR;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
if (this.
|
|
150
|
-
flags |=
|
|
149
|
+
if (this.secondaryOk) {
|
|
150
|
+
flags |= OPTS_SECONDARY;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
if (this.oplogReplay) {
|
|
@@ -837,22 +837,24 @@ export class BinMsg {
|
|
|
837
837
|
const promoteValues = options.promoteValues ?? this.opts.promoteValues;
|
|
838
838
|
const promoteBuffers = options.promoteBuffers ?? this.opts.promoteBuffers;
|
|
839
839
|
const bsonRegExp = options.bsonRegExp ?? this.opts.bsonRegExp;
|
|
840
|
+
const validation = this.parseBsonSerializationOptions(options);
|
|
840
841
|
|
|
841
842
|
// Set up the options
|
|
842
|
-
const
|
|
843
|
+
const bsonOptions: BSONSerializeOptions = {
|
|
843
844
|
promoteLongs,
|
|
844
845
|
promoteValues,
|
|
845
846
|
promoteBuffers,
|
|
846
|
-
bsonRegExp
|
|
847
|
-
|
|
847
|
+
bsonRegExp,
|
|
848
|
+
validation
|
|
849
|
+
// Due to the strictness of the BSON libraries validation option we need this cast
|
|
850
|
+
} as BSONSerializeOptions & { validation: { utf8: { writeErrors: boolean } } };
|
|
848
851
|
|
|
849
852
|
while (this.index < this.data.length) {
|
|
850
853
|
const payloadType = this.data.readUInt8(this.index++);
|
|
851
854
|
if (payloadType === 0) {
|
|
852
855
|
const bsonSize = this.data.readUInt32LE(this.index);
|
|
853
856
|
const bin = this.data.slice(this.index, this.index + bsonSize);
|
|
854
|
-
this.documents.push(raw ? bin : BSON.deserialize(bin,
|
|
855
|
-
|
|
857
|
+
this.documents.push(raw ? bin : BSON.deserialize(bin, bsonOptions));
|
|
856
858
|
this.index += bsonSize;
|
|
857
859
|
} else if (payloadType === 1) {
|
|
858
860
|
// It was decided that no driver makes use of payload type 1
|
|
@@ -865,12 +867,21 @@ export class BinMsg {
|
|
|
865
867
|
if (this.documents.length === 1 && documentsReturnedIn != null && raw) {
|
|
866
868
|
const fieldsAsRaw: Document = {};
|
|
867
869
|
fieldsAsRaw[documentsReturnedIn] = true;
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
const doc = BSON.deserialize(this.documents[0] as Buffer, _options);
|
|
870
|
+
bsonOptions.fieldsAsRaw = fieldsAsRaw;
|
|
871
|
+
const doc = BSON.deserialize(this.documents[0] as Buffer, bsonOptions);
|
|
871
872
|
this.documents = [doc];
|
|
872
873
|
}
|
|
873
874
|
|
|
874
875
|
this.parsed = true;
|
|
875
876
|
}
|
|
877
|
+
|
|
878
|
+
parseBsonSerializationOptions({ enableUtf8Validation }: BSONSerializeOptions): {
|
|
879
|
+
utf8: { writeErrors: false } | false;
|
|
880
|
+
} {
|
|
881
|
+
if (enableUtf8Validation === false) {
|
|
882
|
+
return { utf8: false };
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
return { utf8: { writeErrors: false } };
|
|
886
|
+
}
|
|
876
887
|
}
|
package/src/cmap/connect.ts
CHANGED
|
@@ -1,29 +1,53 @@
|
|
|
1
|
+
import type { Socket, SocketConnectOpts } from 'net';
|
|
1
2
|
import * as net from 'net';
|
|
3
|
+
import { SocksClient } from 'socks';
|
|
4
|
+
import type { ConnectionOptions as TLSConnectionOpts, TLSSocket } from 'tls';
|
|
2
5
|
import * as tls from 'tls';
|
|
3
|
-
|
|
6
|
+
|
|
7
|
+
import type { Document } from '../bson';
|
|
8
|
+
import { Int32 } from '../bson';
|
|
4
9
|
import {
|
|
5
|
-
MongoNetworkError,
|
|
6
|
-
MongoNetworkTimeoutError,
|
|
7
10
|
AnyError,
|
|
8
11
|
MongoCompatibilityError,
|
|
9
12
|
MongoInvalidArgumentError,
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
MongoNetworkError,
|
|
14
|
+
MongoNetworkTimeoutError,
|
|
15
|
+
MongoRuntimeError,
|
|
16
|
+
MongoServerError
|
|
12
17
|
} from '../error';
|
|
13
|
-
import { AUTH_PROVIDERS, AuthMechanism } from './auth/defaultAuthProviders';
|
|
14
|
-
import { AuthContext } from './auth/auth_provider';
|
|
15
|
-
import { makeClientMetadata, ClientMetadata, Callback, CallbackWithType, ns } from '../utils';
|
|
16
18
|
import {
|
|
17
|
-
|
|
19
|
+
Callback,
|
|
20
|
+
CallbackWithType,
|
|
21
|
+
ClientMetadata,
|
|
22
|
+
HostAddress,
|
|
23
|
+
makeClientMetadata,
|
|
24
|
+
ns
|
|
25
|
+
} from '../utils';
|
|
26
|
+
import { AuthContext, AuthProvider } from './auth/auth_provider';
|
|
27
|
+
import { GSSAPI } from './auth/gssapi';
|
|
28
|
+
import { MongoCR } from './auth/mongocr';
|
|
29
|
+
import { MongoDBAWS } from './auth/mongodb_aws';
|
|
30
|
+
import { Plain } from './auth/plain';
|
|
31
|
+
import { AuthMechanism } from './auth/providers';
|
|
32
|
+
import { ScramSHA1, ScramSHA256 } from './auth/scram';
|
|
33
|
+
import { X509 } from './auth/x509';
|
|
34
|
+
import { Connection, ConnectionOptions, CryptoConnection } from './connection';
|
|
35
|
+
import {
|
|
18
36
|
MAX_SUPPORTED_SERVER_VERSION,
|
|
19
|
-
|
|
20
|
-
MIN_SUPPORTED_SERVER_VERSION
|
|
37
|
+
MAX_SUPPORTED_WIRE_VERSION,
|
|
38
|
+
MIN_SUPPORTED_SERVER_VERSION,
|
|
39
|
+
MIN_SUPPORTED_WIRE_VERSION
|
|
21
40
|
} from './wire_protocol/constants';
|
|
22
|
-
import type { Document } from '../bson';
|
|
23
|
-
import { Int32 } from '../bson';
|
|
24
41
|
|
|
25
|
-
|
|
26
|
-
|
|
42
|
+
const AUTH_PROVIDERS = new Map<AuthMechanism | string, AuthProvider>([
|
|
43
|
+
[AuthMechanism.MONGODB_AWS, new MongoDBAWS()],
|
|
44
|
+
[AuthMechanism.MONGODB_CR, new MongoCR()],
|
|
45
|
+
[AuthMechanism.MONGODB_GSSAPI, new GSSAPI()],
|
|
46
|
+
[AuthMechanism.MONGODB_PLAIN, new Plain()],
|
|
47
|
+
[AuthMechanism.MONGODB_SCRAM_SHA1, new ScramSHA1()],
|
|
48
|
+
[AuthMechanism.MONGODB_SCRAM_SHA256, new ScramSHA256()],
|
|
49
|
+
[AuthMechanism.MONGODB_X509, new X509()]
|
|
50
|
+
]);
|
|
27
51
|
|
|
28
52
|
const FAKE_MONGODB_SERVICE_ID =
|
|
29
53
|
typeof process.env.FAKE_MONGODB_SERVICE_ID === 'string' &&
|
|
@@ -33,7 +57,7 @@ const FAKE_MONGODB_SERVICE_ID =
|
|
|
33
57
|
export type Stream = Socket | TLSSocket;
|
|
34
58
|
|
|
35
59
|
export function connect(options: ConnectionOptions, callback: Callback<Connection>): void {
|
|
36
|
-
makeConnection(options, (err, socket) => {
|
|
60
|
+
makeConnection({ ...options, existingSocket: undefined }, (err, socket) => {
|
|
37
61
|
if (err || !socket) {
|
|
38
62
|
return callback(err);
|
|
39
63
|
}
|
|
@@ -289,7 +313,9 @@ function parseConnectOptions(options: ConnectionOptions): SocketConnectOpts {
|
|
|
289
313
|
}
|
|
290
314
|
}
|
|
291
315
|
|
|
292
|
-
|
|
316
|
+
type MakeConnectionOptions = ConnectionOptions & { existingSocket?: Stream };
|
|
317
|
+
|
|
318
|
+
function parseSslOptions(options: MakeConnectionOptions): TLSConnectionOpts {
|
|
293
319
|
const result: TLSConnectionOpts = parseConnectOptions(options);
|
|
294
320
|
// Merge in valid SSL options
|
|
295
321
|
for (const name of LEGAL_TLS_SOCKET_OPTIONS) {
|
|
@@ -298,6 +324,10 @@ function parseSslOptions(options: ConnectionOptions): TLSConnectionOpts {
|
|
|
298
324
|
}
|
|
299
325
|
}
|
|
300
326
|
|
|
327
|
+
if (options.existingSocket) {
|
|
328
|
+
result.socket = options.existingSocket;
|
|
329
|
+
}
|
|
330
|
+
|
|
301
331
|
// Set default sni servername to be the same as host
|
|
302
332
|
if (result.servername == null && result.host && !net.isIP(result.host)) {
|
|
303
333
|
result.servername = result.host;
|
|
@@ -310,17 +340,21 @@ const SOCKET_ERROR_EVENT_LIST = ['error', 'close', 'timeout', 'parseError'] as c
|
|
|
310
340
|
type ErrorHandlerEventName = typeof SOCKET_ERROR_EVENT_LIST[number] | 'cancel';
|
|
311
341
|
const SOCKET_ERROR_EVENTS = new Set(SOCKET_ERROR_EVENT_LIST);
|
|
312
342
|
|
|
313
|
-
function makeConnection(
|
|
343
|
+
function makeConnection(
|
|
344
|
+
options: MakeConnectionOptions,
|
|
345
|
+
_callback: CallbackWithType<AnyError, Stream>
|
|
346
|
+
) {
|
|
314
347
|
const useTLS = options.tls ?? false;
|
|
315
348
|
const keepAlive = options.keepAlive ?? true;
|
|
316
349
|
const socketTimeoutMS = options.socketTimeoutMS ?? Reflect.get(options, 'socketTimeout') ?? 0;
|
|
317
350
|
const noDelay = options.noDelay ?? true;
|
|
318
|
-
const
|
|
351
|
+
const connectTimeoutMS = options.connectTimeoutMS ?? 30000;
|
|
319
352
|
const rejectUnauthorized = options.rejectUnauthorized ?? true;
|
|
320
353
|
const keepAliveInitialDelay =
|
|
321
354
|
((options.keepAliveInitialDelay ?? 120000) > socketTimeoutMS
|
|
322
355
|
? Math.round(socketTimeoutMS / 2)
|
|
323
356
|
: options.keepAliveInitialDelay) ?? 120000;
|
|
357
|
+
const existingSocket = options.existingSocket;
|
|
324
358
|
|
|
325
359
|
let socket: Stream;
|
|
326
360
|
const callback: Callback<Stream> = function (err, ret) {
|
|
@@ -331,18 +365,34 @@ function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<
|
|
|
331
365
|
_callback(err, ret);
|
|
332
366
|
};
|
|
333
367
|
|
|
368
|
+
if (options.proxyHost != null) {
|
|
369
|
+
// Currently, only Socks5 is supported.
|
|
370
|
+
return makeSocks5Connection(
|
|
371
|
+
{
|
|
372
|
+
...options,
|
|
373
|
+
connectTimeoutMS // Should always be present for Socks5
|
|
374
|
+
},
|
|
375
|
+
callback
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
334
379
|
if (useTLS) {
|
|
335
380
|
const tlsSocket = tls.connect(parseSslOptions(options));
|
|
336
381
|
if (typeof tlsSocket.disableRenegotiation === 'function') {
|
|
337
382
|
tlsSocket.disableRenegotiation();
|
|
338
383
|
}
|
|
339
384
|
socket = tlsSocket;
|
|
385
|
+
} else if (existingSocket) {
|
|
386
|
+
// In the TLS case, parseSslOptions() sets options.socket to existingSocket,
|
|
387
|
+
// so we only need to handle the non-TLS case here (where existingSocket
|
|
388
|
+
// gives us all we need out of the box).
|
|
389
|
+
socket = existingSocket;
|
|
340
390
|
} else {
|
|
341
391
|
socket = net.createConnection(parseConnectOptions(options));
|
|
342
392
|
}
|
|
343
393
|
|
|
344
394
|
socket.setKeepAlive(keepAlive, keepAliveInitialDelay);
|
|
345
|
-
socket.setTimeout(
|
|
395
|
+
socket.setTimeout(connectTimeoutMS);
|
|
346
396
|
socket.setNoDelay(noDelay);
|
|
347
397
|
|
|
348
398
|
const connectEvent = useTLS ? 'secureConnect' : 'connect';
|
|
@@ -381,10 +431,80 @@ function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<
|
|
|
381
431
|
options.cancellationToken.once('cancel', cancellationHandler);
|
|
382
432
|
}
|
|
383
433
|
|
|
384
|
-
|
|
434
|
+
if (existingSocket) {
|
|
435
|
+
process.nextTick(connectHandler);
|
|
436
|
+
} else {
|
|
437
|
+
socket.once(connectEvent, connectHandler);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function makeSocks5Connection(options: MakeConnectionOptions, callback: Callback<Stream>) {
|
|
442
|
+
const hostAddress = HostAddress.fromHostPort(
|
|
443
|
+
options.proxyHost ?? '', // proxyHost is guaranteed to set here
|
|
444
|
+
options.proxyPort ?? 1080
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
// First, connect to the proxy server itself:
|
|
448
|
+
makeConnection(
|
|
449
|
+
{
|
|
450
|
+
...options,
|
|
451
|
+
hostAddress,
|
|
452
|
+
tls: false,
|
|
453
|
+
proxyHost: undefined
|
|
454
|
+
},
|
|
455
|
+
(err, rawSocket) => {
|
|
456
|
+
if (err) {
|
|
457
|
+
return callback(err);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const destination = parseConnectOptions(options) as net.TcpNetConnectOpts;
|
|
461
|
+
if (typeof destination.host !== 'string' || typeof destination.port !== 'number') {
|
|
462
|
+
return callback(
|
|
463
|
+
new MongoInvalidArgumentError('Can only make Socks5 connections to TCP hosts')
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Then, establish the Socks5 proxy connection:
|
|
468
|
+
SocksClient.createConnection(
|
|
469
|
+
{
|
|
470
|
+
existing_socket: rawSocket,
|
|
471
|
+
timeout: options.connectTimeoutMS,
|
|
472
|
+
command: 'connect',
|
|
473
|
+
destination: {
|
|
474
|
+
host: destination.host,
|
|
475
|
+
port: destination.port
|
|
476
|
+
},
|
|
477
|
+
proxy: {
|
|
478
|
+
// host and port are ignored because we pass existing_socket
|
|
479
|
+
host: 'iLoveJavaScript',
|
|
480
|
+
port: 0,
|
|
481
|
+
type: 5,
|
|
482
|
+
userId: options.proxyUsername || undefined,
|
|
483
|
+
password: options.proxyPassword || undefined
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
(err: AnyError, info: { socket: Stream }) => {
|
|
487
|
+
if (err) {
|
|
488
|
+
return callback(connectionFailureError('error', err));
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Finally, now treat the resulting duplex stream as the
|
|
492
|
+
// socket over which we send and receive wire protocol messages:
|
|
493
|
+
makeConnection(
|
|
494
|
+
{
|
|
495
|
+
...options,
|
|
496
|
+
existingSocket: info.socket,
|
|
497
|
+
proxyHost: undefined
|
|
498
|
+
},
|
|
499
|
+
callback
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
);
|
|
385
505
|
}
|
|
386
506
|
|
|
387
|
-
function connectionFailureError(type:
|
|
507
|
+
function connectionFailureError(type: ErrorHandlerEventName, err: Error) {
|
|
388
508
|
switch (type) {
|
|
389
509
|
case 'error':
|
|
390
510
|
return new MongoNetworkError(err);
|
package/src/cmap/connection.ts
CHANGED
|
@@ -1,49 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { StreamDescription, StreamDescriptionOptions } from './stream_description';
|
|
3
|
-
import {
|
|
4
|
-
CommandStartedEvent,
|
|
5
|
-
CommandFailedEvent,
|
|
6
|
-
CommandSucceededEvent
|
|
7
|
-
} from './command_monitoring_events';
|
|
8
|
-
import { applySession, ClientSession, updateSessionFromResponse } from '../sessions';
|
|
1
|
+
import { BSONSerializeOptions, Document, Long, ObjectId, pluckBSONSerializeOptions } from '../bson';
|
|
9
2
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
} from '../
|
|
3
|
+
CLOSE,
|
|
4
|
+
CLUSTER_TIME_RECEIVED,
|
|
5
|
+
COMMAND_FAILED,
|
|
6
|
+
COMMAND_STARTED,
|
|
7
|
+
COMMAND_SUCCEEDED,
|
|
8
|
+
MESSAGE,
|
|
9
|
+
PINNED,
|
|
10
|
+
UNPINNED
|
|
11
|
+
} from '../constants';
|
|
12
|
+
import type { AutoEncrypter } from '../deps';
|
|
19
13
|
import {
|
|
20
|
-
MongoRuntimeError,
|
|
21
|
-
MongoMissingDependencyError,
|
|
22
14
|
MongoCompatibilityError,
|
|
15
|
+
MongoMissingDependencyError,
|
|
23
16
|
MongoNetworkError,
|
|
24
17
|
MongoNetworkTimeoutError,
|
|
18
|
+
MongoRuntimeError,
|
|
25
19
|
MongoServerError,
|
|
26
20
|
MongoWriteConcernError
|
|
27
21
|
} from '../error';
|
|
22
|
+
import type { ServerApi, SupportedNodeConnectionOptions } from '../mongo_client';
|
|
23
|
+
import { CancellationToken, TypedEventEmitter } from '../mongo_types';
|
|
24
|
+
import { ReadPreference, ReadPreferenceLike } from '../read_preference';
|
|
25
|
+
import { applySession, ClientSession, updateSessionFromResponse } from '../sessions';
|
|
26
|
+
import {
|
|
27
|
+
calculateDurationInMs,
|
|
28
|
+
Callback,
|
|
29
|
+
ClientMetadata,
|
|
30
|
+
HostAddress,
|
|
31
|
+
maxWireVersion,
|
|
32
|
+
MongoDBNamespace,
|
|
33
|
+
now,
|
|
34
|
+
uuidV4
|
|
35
|
+
} from '../utils';
|
|
36
|
+
import type { W, WriteConcern, WriteConcernOptions } from '../write_concern';
|
|
37
|
+
import type { MongoCredentials } from './auth/mongo_credentials';
|
|
38
|
+
import {
|
|
39
|
+
CommandFailedEvent,
|
|
40
|
+
CommandStartedEvent,
|
|
41
|
+
CommandSucceededEvent
|
|
42
|
+
} from './command_monitoring_events';
|
|
28
43
|
import {
|
|
29
44
|
BinMsg,
|
|
30
|
-
WriteProtocolMessageType,
|
|
31
|
-
Response,
|
|
32
|
-
KillCursor,
|
|
33
45
|
GetMore,
|
|
34
|
-
|
|
46
|
+
KillCursor,
|
|
47
|
+
Msg,
|
|
35
48
|
OpQueryOptions,
|
|
36
|
-
|
|
49
|
+
Query,
|
|
50
|
+
Response,
|
|
51
|
+
WriteProtocolMessageType
|
|
37
52
|
} from './commands';
|
|
38
|
-
import { BSONSerializeOptions, Document, Long, pluckBSONSerializeOptions, ObjectId } from '../bson';
|
|
39
|
-
import type { AutoEncrypter } from '../deps';
|
|
40
|
-
import type { MongoCredentials } from './auth/mongo_credentials';
|
|
41
53
|
import type { Stream } from './connect';
|
|
54
|
+
import { MessageStream, OperationDescription } from './message_stream';
|
|
55
|
+
import { StreamDescription, StreamDescriptionOptions } from './stream_description';
|
|
42
56
|
import { applyCommonQueryOptions, getReadPreference, isSharded } from './wire_protocol/shared';
|
|
43
|
-
import { ReadPreference, ReadPreferenceLike } from '../read_preference';
|
|
44
|
-
import type { W, WriteConcern, WriteConcernOptions } from '../write_concern';
|
|
45
|
-
import type { ServerApi, SupportedNodeConnectionOptions } from '../mongo_client';
|
|
46
|
-
import { CancellationToken, TypedEventEmitter } from '../mongo_types';
|
|
47
57
|
|
|
48
58
|
/** @internal */
|
|
49
59
|
const kStream = Symbol('stream');
|
|
@@ -86,7 +96,7 @@ export interface QueryOptions extends BSONSerializeOptions {
|
|
|
86
96
|
/** @internal */
|
|
87
97
|
export interface CommandOptions extends BSONSerializeOptions {
|
|
88
98
|
command?: boolean;
|
|
89
|
-
|
|
99
|
+
secondaryOk?: boolean;
|
|
90
100
|
/** Specify read preference if command supports it */
|
|
91
101
|
readPreference?: ReadPreferenceLike;
|
|
92
102
|
raw?: boolean;
|
|
@@ -97,6 +107,7 @@ export interface CommandOptions extends BSONSerializeOptions {
|
|
|
97
107
|
session?: ClientSession;
|
|
98
108
|
documentsReturnedIn?: string;
|
|
99
109
|
noResponse?: boolean;
|
|
110
|
+
omitReadPreference?: boolean;
|
|
100
111
|
|
|
101
112
|
// FIXME: NODE-2802
|
|
102
113
|
willRetryWrite?: boolean;
|
|
@@ -113,10 +124,19 @@ export interface GetMoreOptions extends CommandOptions {
|
|
|
113
124
|
comment?: Document | string;
|
|
114
125
|
}
|
|
115
126
|
|
|
127
|
+
/** @public */
|
|
128
|
+
export interface ProxyOptions {
|
|
129
|
+
proxyHost?: string;
|
|
130
|
+
proxyPort?: number;
|
|
131
|
+
proxyUsername?: string;
|
|
132
|
+
proxyPassword?: string;
|
|
133
|
+
}
|
|
134
|
+
|
|
116
135
|
/** @public */
|
|
117
136
|
export interface ConnectionOptions
|
|
118
137
|
extends SupportedNodeConnectionOptions,
|
|
119
|
-
StreamDescriptionOptions
|
|
138
|
+
StreamDescriptionOptions,
|
|
139
|
+
ProxyOptions {
|
|
120
140
|
// Internal creation info
|
|
121
141
|
id: number | '<monitor>';
|
|
122
142
|
generation: number;
|
|
@@ -186,26 +206,26 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
186
206
|
[kClusterTime]: Document;
|
|
187
207
|
|
|
188
208
|
/** @event */
|
|
189
|
-
static readonly COMMAND_STARTED =
|
|
209
|
+
static readonly COMMAND_STARTED = COMMAND_STARTED;
|
|
190
210
|
/** @event */
|
|
191
|
-
static readonly COMMAND_SUCCEEDED =
|
|
211
|
+
static readonly COMMAND_SUCCEEDED = COMMAND_SUCCEEDED;
|
|
192
212
|
/** @event */
|
|
193
|
-
static readonly COMMAND_FAILED =
|
|
213
|
+
static readonly COMMAND_FAILED = COMMAND_FAILED;
|
|
194
214
|
/** @event */
|
|
195
|
-
static readonly CLUSTER_TIME_RECEIVED =
|
|
215
|
+
static readonly CLUSTER_TIME_RECEIVED = CLUSTER_TIME_RECEIVED;
|
|
196
216
|
/** @event */
|
|
197
|
-
static readonly CLOSE =
|
|
217
|
+
static readonly CLOSE = CLOSE;
|
|
198
218
|
/** @event */
|
|
199
|
-
static readonly MESSAGE =
|
|
219
|
+
static readonly MESSAGE = MESSAGE;
|
|
200
220
|
/** @event */
|
|
201
|
-
static readonly PINNED =
|
|
221
|
+
static readonly PINNED = PINNED;
|
|
202
222
|
/** @event */
|
|
203
|
-
static readonly UNPINNED =
|
|
223
|
+
static readonly UNPINNED = UNPINNED;
|
|
204
224
|
|
|
205
225
|
constructor(stream: Stream, options: ConnectionOptions) {
|
|
206
226
|
super();
|
|
207
227
|
this.id = options.id;
|
|
208
|
-
this.address = streamIdentifier(stream);
|
|
228
|
+
this.address = streamIdentifier(stream, options);
|
|
209
229
|
this.socketTimeoutMS = options.socketTimeoutMS ?? 0;
|
|
210
230
|
this.monitorCommands = options.monitorCommands;
|
|
211
231
|
this.serverApi = options.serverApi;
|
|
@@ -416,7 +436,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
416
436
|
numberToReturn: -1,
|
|
417
437
|
checkKeys: false,
|
|
418
438
|
// This value is not overridable
|
|
419
|
-
|
|
439
|
+
secondaryOk: readPreference.secondaryOk()
|
|
420
440
|
},
|
|
421
441
|
options
|
|
422
442
|
);
|
|
@@ -461,7 +481,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
461
481
|
numberToReturn,
|
|
462
482
|
pre32Limit: typeof limit === 'number' ? limit : undefined,
|
|
463
483
|
checkKeys: false,
|
|
464
|
-
|
|
484
|
+
secondaryOk: readPreference.secondaryOk()
|
|
465
485
|
};
|
|
466
486
|
|
|
467
487
|
if (options.projection) {
|
|
@@ -615,13 +635,6 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
615
635
|
}
|
|
616
636
|
}
|
|
617
637
|
|
|
618
|
-
/** @public */
|
|
619
|
-
export const APM_EVENTS = [
|
|
620
|
-
Connection.COMMAND_STARTED,
|
|
621
|
-
Connection.COMMAND_SUCCEEDED,
|
|
622
|
-
Connection.COMMAND_FAILED
|
|
623
|
-
];
|
|
624
|
-
|
|
625
638
|
/** @internal */
|
|
626
639
|
export class CryptoConnection extends Connection {
|
|
627
640
|
/** @internal */
|
|
@@ -753,7 +766,13 @@ function messageHandler(conn: Connection) {
|
|
|
753
766
|
};
|
|
754
767
|
}
|
|
755
768
|
|
|
756
|
-
function streamIdentifier(stream: Stream) {
|
|
769
|
+
function streamIdentifier(stream: Stream, options: ConnectionOptions): string {
|
|
770
|
+
if (options.proxyHost) {
|
|
771
|
+
// If proxy options are specified, the properties of `stream` itself
|
|
772
|
+
// will not accurately reflect what endpoint this is connected to.
|
|
773
|
+
return options.hostAddress.toString();
|
|
774
|
+
}
|
|
775
|
+
|
|
757
776
|
if (typeof stream.address === 'function') {
|
|
758
777
|
return `${stream.remoteAddress}:${stream.remotePort}`;
|
|
759
778
|
}
|
|
@@ -786,6 +805,8 @@ function write(
|
|
|
786
805
|
promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true,
|
|
787
806
|
promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false,
|
|
788
807
|
bsonRegExp: typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false,
|
|
808
|
+
enableUtf8Validation:
|
|
809
|
+
typeof options.enableUtf8Validation === 'boolean' ? options.enableUtf8Validation : true,
|
|
789
810
|
raw: typeof options.raw === 'boolean' ? options.raw : false,
|
|
790
811
|
started: 0
|
|
791
812
|
};
|