mongo 2.9.2 → 2.10.0.rc0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +1 -0
- data/lib/mongo/auth/user/view.rb +4 -4
- data/lib/mongo/bulk_write.rb +14 -8
- data/lib/mongo/bulk_write/result.rb +1 -1
- data/lib/mongo/bulk_write/result_combiner.rb +2 -2
- data/lib/mongo/bulk_write/transformable.rb +17 -9
- data/lib/mongo/client.rb +107 -16
- data/lib/mongo/cluster.rb +47 -25
- data/lib/mongo/cluster/topology/replica_set_no_primary.rb +1 -1
- data/lib/mongo/cluster_time.rb +139 -0
- data/lib/mongo/collection.rb +84 -25
- data/lib/mongo/collection/view.rb +7 -3
- data/lib/mongo/collection/view/aggregation.rb +4 -4
- data/lib/mongo/collection/view/builder/aggregation.rb +31 -6
- data/lib/mongo/collection/view/builder/find_command.rb +4 -1
- data/lib/mongo/collection/view/builder/map_reduce.rb +4 -1
- data/lib/mongo/collection/view/change_stream.rb +54 -66
- data/lib/mongo/collection/view/iterable.rb +2 -2
- data/lib/mongo/collection/view/map_reduce.rb +6 -4
- data/lib/mongo/collection/view/readable.rb +36 -16
- data/lib/mongo/collection/view/writable.rb +68 -22
- data/lib/mongo/cursor.rb +87 -20
- data/lib/mongo/database.rb +47 -43
- data/lib/mongo/database/view.rb +54 -11
- data/lib/mongo/error.rb +13 -4
- data/lib/mongo/error/invalid_write_concern.rb +2 -2
- data/lib/mongo/error/operation_failure.rb +65 -11
- data/lib/mongo/error/parser.rb +41 -8
- data/lib/mongo/grid/fs_bucket.rb +26 -6
- data/lib/mongo/grid/stream/read.rb +9 -2
- data/lib/mongo/grid/stream/write.rb +21 -5
- data/lib/mongo/index/view.rb +3 -3
- data/lib/mongo/lint.rb +10 -3
- data/lib/mongo/operation.rb +2 -0
- data/lib/mongo/operation/aggregate/result.rb +19 -6
- data/lib/mongo/operation/collections_info.rb +1 -1
- data/lib/mongo/operation/get_more/result.rb +9 -0
- data/lib/mongo/operation/list_collections/command.rb +1 -3
- data/lib/mongo/operation/list_collections/op_msg.rb +1 -2
- data/lib/mongo/operation/parallel_scan/command.rb +4 -1
- data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -1
- data/lib/mongo/operation/result.rb +27 -4
- data/lib/mongo/operation/shared/executable.rb +19 -5
- data/lib/mongo/operation/shared/executable_no_validate.rb +1 -2
- data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -9
- data/lib/mongo/operation/shared/polymorphic_result.rb +9 -1
- data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
- data/lib/mongo/operation/shared/sessions_supported.rb +42 -32
- data/lib/mongo/operation/shared/specifiable.rb +40 -0
- data/lib/mongo/operation/shared/unpinnable.rb +39 -0
- data/lib/mongo/operation/shared/write.rb +1 -1
- data/lib/mongo/protocol/update.rb +6 -2
- data/lib/mongo/retryable.rb +79 -39
- data/lib/mongo/server/connection.rb +10 -3
- data/lib/mongo/server/description.rb +25 -1
- data/lib/mongo/server/monitor/connection.rb +1 -1
- data/lib/mongo/server_selector.rb +10 -0
- data/lib/mongo/server_selector/selectable.rb +172 -32
- data/lib/mongo/session.rb +654 -581
- data/lib/mongo/session/session_pool.rb +1 -1
- data/lib/mongo/socket.rb +7 -28
- data/lib/mongo/socket/ssl.rb +26 -1
- data/lib/mongo/socket/tcp.rb +3 -0
- data/lib/mongo/socket/unix.rb +3 -0
- data/lib/mongo/uri.rb +112 -265
- data/lib/mongo/uri/srv_protocol.rb +4 -1
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo/write_concern.rb +10 -29
- data/lib/mongo/write_concern/acknowledged.rb +12 -0
- data/lib/mongo/write_concern/base.rb +17 -13
- data/lib/mongo/write_concern/unacknowledged.rb +12 -0
- data/spec/atlas/atlas_connectivity_spec.rb +7 -37
- data/spec/atlas/operations_spec.rb +25 -0
- data/spec/integration/change_stream_examples_spec.rb +45 -31
- data/spec/integration/change_stream_spec.rb +305 -5
- data/spec/integration/client_spec.rb +44 -0
- data/spec/integration/command_monitoring_spec.rb +1 -0
- data/spec/integration/command_spec.rb +7 -1
- data/spec/integration/mmapv1_spec.rb +28 -0
- data/spec/integration/mongos_pinning_spec.rb +34 -0
- data/spec/integration/operation_failure_code_spec.rb +2 -2
- data/spec/integration/{read_concern.rb → read_concern_spec.rb} +7 -1
- data/spec/integration/read_preference_spec.rb +485 -0
- data/spec/integration/retryable_writes_spec.rb +8 -19
- data/spec/integration/sdam_error_handling_spec.rb +1 -1
- data/spec/integration/sdam_events_spec.rb +2 -2
- data/spec/integration/server_description_spec.rb +14 -17
- data/spec/integration/server_selector_spec.rb +7 -3
- data/spec/integration/server_spec.rb +48 -0
- data/spec/integration/ssl_uri_options_spec.rb +1 -1
- data/spec/integration/step_down_spec.rb +10 -4
- data/spec/integration/transactions_examples_spec.rb +11 -10
- data/spec/lite_spec_helper.rb +19 -16
- data/spec/mongo/auth/scram/negotiation_spec.rb +11 -8
- data/spec/mongo/bulk_write/ordered_combiner_spec.rb +6 -6
- data/spec/mongo/bulk_write/unordered_combiner_spec.rb +4 -4
- data/spec/mongo/bulk_write_spec.rb +12 -2
- data/spec/mongo/client_construction_spec.rb +160 -8
- data/spec/mongo/client_spec.rb +5 -4
- data/spec/mongo/cluster_spec.rb +6 -6
- data/spec/mongo/cluster_time_spec.rb +148 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +34 -15
- data/spec/mongo/collection/view/change_stream_spec.rb +62 -3
- data/spec/mongo/collection/view/map_reduce_spec.rb +7 -5
- data/spec/mongo/collection/view/readable_spec.rb +4 -4
- data/spec/mongo/collection_spec.rb +331 -14
- data/spec/mongo/cursor_spec.rb +117 -5
- data/spec/mongo/database_spec.rb +240 -8
- data/spec/mongo/error/operation_failure_spec.rb +47 -1
- data/spec/mongo/error/parser_spec.rb +160 -23
- data/spec/mongo/operation/insert/bulk_spec.rb +2 -1
- data/spec/mongo/operation/result_spec.rb +27 -0
- data/spec/mongo/operation/update/bulk_spec.rb +1 -0
- data/spec/mongo/retryable_spec.rb +2 -0
- data/spec/mongo/server/app_metadata_spec.rb +2 -2
- data/spec/mongo/server/connection_spec.rb +13 -17
- data/spec/mongo/server/monitor/connection_spec.rb +13 -10
- data/spec/mongo/server_selector_spec.rb +34 -2
- data/spec/mongo/session/session_pool_spec.rb +14 -3
- data/spec/mongo/session_spec.rb +3 -3
- data/spec/mongo/session_transaction_spec.rb +4 -3
- data/spec/mongo/socket/ssl_spec.rb +19 -5
- data/spec/mongo/socket_spec.rb +1 -62
- data/spec/mongo/uri/srv_protocol_spec.rb +14 -20
- data/spec/mongo/uri_option_parsing_spec.rb +94 -8
- data/spec/mongo/uri_spec.rb +23 -10
- data/spec/mongo/write_concern_spec.rb +56 -3
- data/spec/spec_tests/change_streams_spec.rb +2 -1
- data/spec/spec_tests/cmap_spec.rb +1 -1
- data/spec/spec_tests/crud_spec.rb +12 -2
- data/spec/spec_tests/data/change_streams/change-streams-errors.yml +24 -1
- data/spec/spec_tests/data/change_streams/change-streams.yml +172 -3
- data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +1 -1
- data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -2
- data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -5
- data/spec/spec_tests/data/crud/read/aggregate-out.yml +0 -6
- data/spec/spec_tests/data/crud/read/count-empty.yml +29 -0
- data/spec/spec_tests/data/crud/write/bulkWrite-arrayFilters.yml +1 -0
- data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +101 -0
- data/spec/spec_tests/data/crud/write/bulkWrite.yml +401 -0
- data/spec/spec_tests/data/crud/write/insertMany.yml +58 -2
- data/spec/spec_tests/data/crud/write/updateMany-arrayFilters.yml +3 -0
- data/spec/spec_tests/data/crud/write/updateOne-arrayFilters.yml +6 -1
- data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +103 -0
- data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +110 -0
- data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +81 -0
- data/spec/spec_tests/data/crud_v2/db-aggregate.yml +38 -0
- data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +92 -0
- data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +2 -2
- data/spec/spec_tests/data/transactions/abort.yml +3 -0
- data/spec/spec_tests/data/transactions/bulk.yml +3 -8
- data/spec/spec_tests/data/transactions/causal-consistency.yml +3 -8
- data/spec/spec_tests/data/transactions/commit.yml +3 -1
- data/spec/spec_tests/data/transactions/count.yml +3 -0
- data/spec/spec_tests/data/transactions/delete.yml +3 -0
- data/spec/spec_tests/data/transactions/error-labels.yml +4 -1
- data/spec/spec_tests/data/transactions/errors-client.yml +56 -0
- data/spec/spec_tests/data/transactions/errors.yml +3 -0
- data/spec/spec_tests/data/transactions/findOneAndDelete.yml +3 -0
- data/spec/spec_tests/data/transactions/findOneAndReplace.yml +3 -0
- data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +3 -0
- data/spec/spec_tests/data/transactions/insert.yml +3 -0
- data/spec/spec_tests/data/transactions/isolation.yml +3 -0
- data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +1671 -0
- data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +347 -0
- data/spec/spec_tests/data/transactions/pin-mongos.yml +557 -0
- data/spec/spec_tests/data/transactions/read-concern.yml +3 -0
- data/spec/spec_tests/data/transactions/read-pref.yml +3 -0
- data/spec/spec_tests/data/transactions/reads.yml +3 -0
- data/spec/spec_tests/data/transactions/retryable-abort.yml +5 -2
- data/spec/spec_tests/data/transactions/retryable-commit.yml +4 -1
- data/spec/spec_tests/data/transactions/retryable-writes.yml +3 -0
- data/spec/spec_tests/data/transactions/run-command.yml +3 -0
- data/spec/spec_tests/data/transactions/transaction-options.yml +6 -0
- data/spec/spec_tests/data/transactions/update.yml +3 -8
- data/spec/spec_tests/data/transactions/write-concern.yml +348 -38
- data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -0
- data/spec/spec_tests/data/transactions_api/callback-commits.yml +5 -0
- data/spec/spec_tests/data/transactions_api/callback-retry.yml +7 -2
- data/spec/spec_tests/data/transactions_api/commit-retry.yml +70 -15
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +3 -0
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +3 -0
- data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +59 -109
- data/spec/spec_tests/data/transactions_api/commit.yml +5 -0
- data/spec/spec_tests/data/transactions_api/transaction-options.yml +10 -0
- data/spec/spec_tests/retryable_reads_spec.rb +5 -2
- data/spec/spec_tests/retryable_writes_spec.rb +5 -2
- data/spec/spec_tests/sdam_monitoring_spec.rb +3 -3
- data/spec/spec_tests/sdam_spec.rb +2 -2
- data/spec/spec_tests/transactions_api_spec.rb +1 -67
- data/spec/spec_tests/transactions_spec.rb +2 -66
- data/spec/support/authorization.rb +4 -0
- data/spec/support/change_streams.rb +30 -10
- data/spec/support/change_streams/operation.rb +27 -0
- data/spec/support/client_registry.rb +44 -25
- data/spec/support/cluster_config.rb +25 -14
- data/spec/support/cluster_tools.rb +32 -10
- data/spec/support/command_monitoring.rb +1 -1
- data/spec/support/common_shortcuts.rb +30 -0
- data/spec/support/connection_string.rb +8 -3
- data/spec/support/constraints.rb +34 -0
- data/spec/support/crud.rb +31 -16
- data/spec/support/crud/context.rb +23 -0
- data/spec/support/crud/operation.rb +311 -14
- data/spec/support/crud/spec.rb +2 -1
- data/spec/support/crud/test.rb +24 -27
- data/spec/support/crud/test_base.rb +22 -0
- data/spec/support/crud/verifier.rb +15 -1
- data/spec/support/event_subscriber.rb +12 -0
- data/spec/support/sdam_formatter_integration.rb +12 -6
- data/spec/support/shared/server_selector.rb +10 -0
- data/spec/support/shared/session.rb +13 -12
- data/spec/support/spec_config.rb +32 -22
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/transactions.rb +87 -0
- data/spec/support/transactions/context.rb +33 -0
- data/spec/support/transactions/operation.rb +99 -349
- data/spec/support/transactions/spec.rb +1 -3
- data/spec/support/transactions/test.rb +110 -49
- data/spec/support/utils.rb +74 -1
- metadata +52 -10
- metadata.gz.sig +0 -0
- data/spec/support/crud/read.rb +0 -265
- data/spec/support/crud/write.rb +0 -284
data/lib/mongo/socket.rb
CHANGED
@@ -49,9 +49,6 @@ module Mongo
|
|
49
49
|
# @return [ Hash ] The options.
|
50
50
|
attr_reader :options
|
51
51
|
|
52
|
-
# @return [ Float ] timeout The socket timeout.
|
53
|
-
attr_reader :timeout
|
54
|
-
|
55
52
|
# Is the socket connection alive?
|
56
53
|
#
|
57
54
|
# @example Is the socket alive?
|
@@ -126,14 +123,10 @@ module Mongo
|
|
126
123
|
def read(length)
|
127
124
|
handle_errors do
|
128
125
|
data = read_from_socket(length)
|
129
|
-
unless (data.length > 0 || length == 0)
|
130
|
-
raise IOError, "Expected to read > 0 bytes but read 0 bytes"
|
131
|
-
end
|
126
|
+
raise IOError unless (data.length > 0 || length == 0)
|
132
127
|
while data.length < length
|
133
128
|
chunk = read_from_socket(length - data.length)
|
134
|
-
unless (chunk.length > 0 || length == 0)
|
135
|
-
raise IOError, "Expected to read > 0 bytes but read 0 bytes"
|
136
|
-
end
|
129
|
+
raise IOError unless (chunk.length > 0 || length == 0)
|
137
130
|
data << chunk
|
138
131
|
end
|
139
132
|
data
|
@@ -192,9 +185,7 @@ module Mongo
|
|
192
185
|
return ''.force_encoding('BINARY')
|
193
186
|
end
|
194
187
|
|
195
|
-
|
196
|
-
deadline = Time.now + _timeout
|
197
|
-
end
|
188
|
+
deadline = (Time.now + timeout) if timeout
|
198
189
|
|
199
190
|
# We want to have a fixed and reasonably small size buffer for reads
|
200
191
|
# because, for example, OpenSSL reads in 16 kb chunks max.
|
@@ -241,22 +232,10 @@ module Mongo
|
|
241
232
|
data[retrieved, chunk.length] = chunk
|
242
233
|
retrieved += chunk.length
|
243
234
|
end
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
select_timeout = deadline - Time.now
|
249
|
-
if select_timeout <= 0
|
250
|
-
raise Errno::ETIMEDOUT, "Took more than #{_timeout} seconds to receive data"
|
251
|
-
end
|
252
|
-
end
|
253
|
-
if exc.is_a?(IO::WaitReadable)
|
254
|
-
select_args = [[@socket], nil, [@socket], select_timeout]
|
255
|
-
else
|
256
|
-
select_args = [nil, [@socket], [@socket], select_timeout]
|
257
|
-
end
|
258
|
-
unless Kernel::select(*select_args)
|
259
|
-
raise Errno::ETIMEDOUT, "Took more than #{_timeout} seconds to receive data"
|
235
|
+
rescue IO::WaitReadable
|
236
|
+
select_timeout = (deadline - Time.now) if deadline
|
237
|
+
if (select_timeout && select_timeout <= 0) || !Kernel::select([@socket], nil, [@socket], select_timeout)
|
238
|
+
raise Timeout::Error.new("Took more than #{timeout} seconds to receive data.")
|
260
239
|
end
|
261
240
|
retry
|
262
241
|
end
|
data/lib/mongo/socket/ssl.rb
CHANGED
@@ -33,6 +33,9 @@ module Mongo
|
|
33
33
|
# @return [ Integer ] port The port to connect to.
|
34
34
|
attr_reader :port
|
35
35
|
|
36
|
+
# @return [ Float ] timeout The socket timeout.
|
37
|
+
attr_reader :timeout
|
38
|
+
|
36
39
|
# Establishes a socket connection.
|
37
40
|
#
|
38
41
|
# @example Connect the socket.
|
@@ -125,10 +128,32 @@ module Mongo
|
|
125
128
|
|
126
129
|
def create_context(options)
|
127
130
|
OpenSSL::SSL::SSLContext.new.tap do |context|
|
131
|
+
if OpenSSL::SSL.const_defined?(:OP_NO_RENEGOTIATION)
|
132
|
+
context.options = context.options | OpenSSL::SSL::OP_NO_RENEGOTIATION
|
133
|
+
end
|
134
|
+
|
135
|
+
if context.respond_to?(:renegotiation_cb=)
|
136
|
+
# Disable renegotiation for older Ruby versions per the sample code at
|
137
|
+
# https://rubydocs.org/d/ruby-2-6-0/classes/OpenSSL/SSL/SSLContext.html
|
138
|
+
# In JRuby we must allow one call as this callback is invoked for
|
139
|
+
# the initial connection also, not just for renegotiations -
|
140
|
+
# https://github.com/jruby/jruby-openssl/issues/180
|
141
|
+
if BSON::Environment.jruby?
|
142
|
+
allowed_calls = 1
|
143
|
+
else
|
144
|
+
allowed_calls = 0
|
145
|
+
end
|
146
|
+
context.renegotiation_cb = lambda do |ssl|
|
147
|
+
if allowed_calls <= 0
|
148
|
+
raise RuntimeError, 'Client renegotiation disabled'
|
149
|
+
end
|
150
|
+
allowed_calls -= 1
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
128
154
|
set_cert(context, options)
|
129
155
|
set_key(context, options)
|
130
156
|
|
131
|
-
|
132
157
|
if verify_certificate?
|
133
158
|
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
134
159
|
set_cert_verification(context, options)
|
data/lib/mongo/socket/tcp.rb
CHANGED
data/lib/mongo/socket/unix.rb
CHANGED
data/lib/mongo/uri.rb
CHANGED
@@ -115,6 +115,7 @@ module Mongo
|
|
115
115
|
# The character delimiting multiple options.
|
116
116
|
#
|
117
117
|
# @since 2.1.0
|
118
|
+
# @deprecated
|
118
119
|
INDIV_URI_OPTS_DELIM = '&'.freeze
|
119
120
|
|
120
121
|
# The character delimiting an option and its value.
|
@@ -188,21 +189,21 @@ module Mongo
|
|
188
189
|
#
|
189
190
|
# @since 2.0.0
|
190
191
|
AUTH_MECH_MAP = {
|
191
|
-
'
|
192
|
+
'GSSAPI' => :gssapi,
|
192
193
|
# MONGODB-CR is deprecated and will be removed in driver version 3.0
|
193
194
|
'MONGODB-CR' => :mongodb_cr,
|
194
|
-
'GSSAPI' => :gssapi,
|
195
195
|
'MONGODB-X509' => :mongodb_x509,
|
196
|
+
'PLAIN' => :plain,
|
196
197
|
'SCRAM-SHA-1' => :scram,
|
197
198
|
'SCRAM-SHA-256' => :scram256
|
198
199
|
}.freeze
|
199
200
|
|
200
201
|
# Options that are allowed to appear more than once in the uri.
|
201
202
|
#
|
202
|
-
# In order to follow the URI options spec requirement that all instances
|
203
|
-
# the same value, we need to keep track of all
|
204
|
-
#
|
205
|
-
# parsing the URI.
|
203
|
+
# In order to follow the URI options spec requirement that all instances
|
204
|
+
# of 'tls' and 'ssl' have the same value, we need to keep track of all
|
205
|
+
# of the values passed in for those options. Assuming they don't conflict,
|
206
|
+
# they will be condensed to a single value immediately after parsing the URI.
|
206
207
|
#
|
207
208
|
# @since 2.1.0
|
208
209
|
REPEATABLE_OPTIONS = [ :tag_sets, :ssl ]
|
@@ -349,7 +350,19 @@ module Mongo
|
|
349
350
|
end
|
350
351
|
end
|
351
352
|
|
352
|
-
|
353
|
+
unless hosts.length > 0
|
354
|
+
raise_invalid_error!("Missing host; at least one must be provided")
|
355
|
+
end
|
356
|
+
|
357
|
+
@servers = hosts.split(',').map do |host|
|
358
|
+
if host.empty?
|
359
|
+
raise_invalid_error!('Empty host given in the host list')
|
360
|
+
end
|
361
|
+
decode(host).tap do |host|
|
362
|
+
validate_host!(host)
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
353
366
|
@user = parse_user!(creds)
|
354
367
|
@password = parse_password!(creds)
|
355
368
|
@uri_options = Options::Redacted.new(parse_uri_options!(options))
|
@@ -368,20 +381,26 @@ module Mongo
|
|
368
381
|
end
|
369
382
|
|
370
383
|
def parse_uri_options!(string)
|
371
|
-
|
372
|
-
string
|
373
|
-
|
384
|
+
uri_options = {}
|
385
|
+
unless string
|
386
|
+
return uri_options
|
387
|
+
end
|
388
|
+
string.split('&').each do |option_str|
|
389
|
+
if option_str.empty?
|
390
|
+
next
|
391
|
+
end
|
392
|
+
key, value = option_str.split('=', 2)
|
374
393
|
if value.nil?
|
375
394
|
raise_invalid_error!("Option #{key} has no value")
|
376
395
|
end
|
377
396
|
if value.index('=')
|
378
397
|
raise_invalid_error!("Value for option #{key} contains the key/value delimiter (=): #{value}")
|
379
398
|
end
|
380
|
-
key =
|
381
|
-
value =
|
399
|
+
key = decode(key)
|
400
|
+
value = decode(value)
|
382
401
|
add_uri_option(key, value, uri_options)
|
383
|
-
uri_options
|
384
402
|
end
|
403
|
+
uri_options
|
385
404
|
end
|
386
405
|
|
387
406
|
def parse_user!(string)
|
@@ -421,23 +440,44 @@ module Mongo
|
|
421
440
|
end
|
422
441
|
end
|
423
442
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
elsif host.index(HOST_PORT_DELIM)
|
433
|
-
h, _, p = host.partition(HOST_PORT_DELIM)
|
434
|
-
raise_invalid_error!(INVALID_HOST) unless h.size > 0
|
435
|
-
validate_port_string!(p)
|
436
|
-
elsif host =~ UNIX_SOCKET
|
437
|
-
raise_invalid_error!(UNESCAPED_UNIX_SOCKET) if host =~ UNSAFE
|
438
|
-
host = decode(host)
|
443
|
+
# Takes a host in ipv4/ipv6/hostname/socket path format and validates
|
444
|
+
# its format.
|
445
|
+
def validate_host!(host)
|
446
|
+
case host
|
447
|
+
when /\A\[[\d:]+\](?::(\d+))?\z/
|
448
|
+
# ipv6 with optional port
|
449
|
+
if port_str = $1
|
450
|
+
validate_port_string!(port_str)
|
439
451
|
end
|
440
|
-
|
452
|
+
when /\A\//, /\.sock\z/
|
453
|
+
# Unix socket path.
|
454
|
+
# Spec requires us to validate that the path has no unescaped
|
455
|
+
# slashes, but if this were to be the case, parsing would have
|
456
|
+
# already failed elsewhere because the URI would've been split in
|
457
|
+
# a weird place.
|
458
|
+
# The spec also allows relative socket paths and requires that
|
459
|
+
# socket paths end in ".sock". We accept all paths but special case
|
460
|
+
# the .sock extension to avoid relative paths falling into the
|
461
|
+
# host:port case below.
|
462
|
+
when /[\/\[\]]/
|
463
|
+
# Not a host:port nor an ipv4 address with optional port.
|
464
|
+
# Possibly botched ipv6 address with e.g. port delimiter present and
|
465
|
+
# port missing, or extra junk before or after.
|
466
|
+
raise_invalid_error!("Invalid hostname: #{host}")
|
467
|
+
when /:.*:/m
|
468
|
+
raise_invalid_error!("Multiple port delimiters are not allowed: #{host}")
|
469
|
+
else
|
470
|
+
# host:port or ipv4 address with optional port number
|
471
|
+
host, port = host.split(':')
|
472
|
+
if host.empty?
|
473
|
+
raise_invalid_error!("Host is empty: #{host}")
|
474
|
+
end
|
475
|
+
|
476
|
+
if port && port.empty?
|
477
|
+
raise_invalid_error!("Port is empty: #{port}")
|
478
|
+
end
|
479
|
+
|
480
|
+
validate_port_string!(port)
|
441
481
|
end
|
442
482
|
end
|
443
483
|
|
@@ -472,21 +512,21 @@ module Mongo
|
|
472
512
|
end
|
473
513
|
|
474
514
|
# Replica Set Options
|
475
|
-
uri_option 'replicaset', :replica_set
|
515
|
+
uri_option 'replicaset', :replica_set
|
476
516
|
|
477
517
|
# Timeout Options
|
478
|
-
uri_option 'connecttimeoutms', :connect_timeout, :type => :
|
479
|
-
uri_option 'sockettimeoutms', :socket_timeout, :type => :
|
480
|
-
uri_option 'serverselectiontimeoutms', :server_selection_timeout, :type => :
|
481
|
-
uri_option 'localthresholdms', :local_threshold, :type => :
|
482
|
-
uri_option 'heartbeatfrequencyms', :heartbeat_frequency, :type => :
|
483
|
-
uri_option 'maxidletimems', :max_idle_time, :type => :
|
518
|
+
uri_option 'connecttimeoutms', :connect_timeout, :type => :ms
|
519
|
+
uri_option 'sockettimeoutms', :socket_timeout, :type => :ms
|
520
|
+
uri_option 'serverselectiontimeoutms', :server_selection_timeout, :type => :ms
|
521
|
+
uri_option 'localthresholdms', :local_threshold, :type => :ms
|
522
|
+
uri_option 'heartbeatfrequencyms', :heartbeat_frequency, :type => :ms
|
523
|
+
uri_option 'maxidletimems', :max_idle_time, :type => :ms
|
484
524
|
|
485
525
|
# Write Options
|
486
|
-
uri_option 'w', :w, :group => :
|
487
|
-
uri_option 'journal', :j, :group => :
|
488
|
-
uri_option 'fsync', :fsync, :group => :
|
489
|
-
uri_option 'wtimeoutms', :wtimeout, :group => :
|
526
|
+
uri_option 'w', :w, :group => :write_concern, type: :w
|
527
|
+
uri_option 'journal', :j, :group => :write_concern, :type => :bool
|
528
|
+
uri_option 'fsync', :fsync, :group => :write_concern, type: :bool
|
529
|
+
uri_option 'wtimeoutms', :wtimeout, :group => :write_concern, :type => :integer
|
490
530
|
|
491
531
|
# Read Options
|
492
532
|
uri_option 'readpreference', :mode, :group => :read, :type => :read_mode
|
@@ -494,21 +534,21 @@ module Mongo
|
|
494
534
|
uri_option 'maxstalenessseconds', :max_staleness, :group => :read, :type => :max_staleness
|
495
535
|
|
496
536
|
# Pool options
|
497
|
-
uri_option 'minpoolsize', :min_pool_size, :type => :
|
498
|
-
uri_option 'maxpoolsize', :max_pool_size, :type => :
|
499
|
-
uri_option 'waitqueuetimeoutms', :wait_queue_timeout, :type => :
|
537
|
+
uri_option 'minpoolsize', :min_pool_size, :type => :integer
|
538
|
+
uri_option 'maxpoolsize', :max_pool_size, :type => :integer
|
539
|
+
uri_option 'waitqueuetimeoutms', :wait_queue_timeout, :type => :ms
|
500
540
|
|
501
541
|
# Security Options
|
502
|
-
uri_option 'ssl', :ssl, :type => :
|
503
|
-
uri_option 'tls', :ssl, :type => :
|
542
|
+
uri_option 'ssl', :ssl, :type => :repeated_bool
|
543
|
+
uri_option 'tls', :ssl, :type => :repeated_bool
|
504
544
|
uri_option 'tlsallowinvalidcertificates', :ssl_verify_certificate,
|
505
|
-
:type => :
|
545
|
+
:type => :inverse_bool
|
506
546
|
uri_option 'tlsallowinvalidhostnames', :ssl_verify_hostname,
|
507
|
-
:type => :
|
547
|
+
:type => :inverse_bool
|
508
548
|
uri_option 'tlscafile', :ssl_ca_cert
|
509
549
|
uri_option 'tlscertificatekeyfile', :ssl_cert
|
510
550
|
uri_option 'tlscertificatekeyfilepassword', :ssl_key_pass_phrase
|
511
|
-
uri_option 'tlsinsecure', :ssl_verify, :type => :
|
551
|
+
uri_option 'tlsinsecure', :ssl_verify, :type => :inverse_bool
|
512
552
|
|
513
553
|
# Topology options
|
514
554
|
uri_option 'connect', :connect, type: :symbol
|
@@ -521,9 +561,9 @@ module Mongo
|
|
521
561
|
# Client Options
|
522
562
|
uri_option 'appname', :app_name
|
523
563
|
uri_option 'compressors', :compressors, :type => :array
|
524
|
-
uri_option 'readconcernlevel', :level, group: :read_concern
|
525
|
-
uri_option 'retryreads', :retry_reads, :type => :
|
526
|
-
uri_option 'retrywrites', :retry_writes, :type => :
|
564
|
+
uri_option 'readconcernlevel', :level, group: :read_concern, type: :symbol
|
565
|
+
uri_option 'retryreads', :retry_reads, :type => :bool
|
566
|
+
uri_option 'retrywrites', :retry_writes, :type => :bool
|
527
567
|
uri_option 'zlibcompressionlevel', :zlib_compression_level, :type => :zlib_compression_level
|
528
568
|
|
529
569
|
# Applies URI value transformation by either using the default cast
|
@@ -602,15 +642,6 @@ module Mongo
|
|
602
642
|
merge_uri_option(target, value, strategy[:name])
|
603
643
|
end
|
604
644
|
|
605
|
-
# Replica set transformation, avoid converting to Symbol.
|
606
|
-
#
|
607
|
-
# @param value [String] Replica set name.
|
608
|
-
#
|
609
|
-
# @return [String] Same value to avoid cast to Symbol.
|
610
|
-
def replica_set(value)
|
611
|
-
decode(value)
|
612
|
-
end
|
613
|
-
|
614
645
|
# Auth source transformation, either db string or :external.
|
615
646
|
#
|
616
647
|
# @param value [String] Authentication source.
|
@@ -618,7 +649,7 @@ module Mongo
|
|
618
649
|
# @return [String] If auth source is database name.
|
619
650
|
# @return [:external] If auth source is external authentication.
|
620
651
|
def auth_source(value)
|
621
|
-
value == '$external' ? :external :
|
652
|
+
value == '$external' ? :external : value
|
622
653
|
end
|
623
654
|
|
624
655
|
# Authentication mechanism transformation.
|
@@ -627,7 +658,7 @@ module Mongo
|
|
627
658
|
#
|
628
659
|
# @return [Symbol] The transformed authentication mechanism.
|
629
660
|
def auth_mech(value)
|
630
|
-
AUTH_MECH_MAP[value.upcase].tap do |mech|
|
661
|
+
(AUTH_MECH_MAP[value.upcase] || value).tap do |mech|
|
631
662
|
log_warn("#{value} is not a valid auth mechanism") unless mech
|
632
663
|
end
|
633
664
|
end
|
@@ -638,7 +669,7 @@ module Mongo
|
|
638
669
|
#
|
639
670
|
# @return [Symbol] The read mode symbol.
|
640
671
|
def read_mode(value)
|
641
|
-
READ_MODE_MAP[value.downcase]
|
672
|
+
READ_MODE_MAP[value.downcase] || value
|
642
673
|
end
|
643
674
|
|
644
675
|
# Read preference tags transformation.
|
@@ -668,7 +699,7 @@ module Mongo
|
|
668
699
|
properties = hash_extractor('authMechanismProperties', value)
|
669
700
|
if properties[:canonicalize_host_name]
|
670
701
|
properties.merge!(canonicalize_host_name:
|
671
|
-
|
702
|
+
properties[:canonicalize_host_name].downcase == 'true')
|
672
703
|
end
|
673
704
|
properties
|
674
705
|
end
|
@@ -692,118 +723,15 @@ module Mongo
|
|
692
723
|
nil
|
693
724
|
end
|
694
725
|
|
695
|
-
#
|
696
|
-
#
|
697
|
-
# @param value [ String ] The max pool size string.
|
698
|
-
#
|
699
|
-
# @return [ Integer | nil ] The min pool size if it is valid, otherwise nil (and a warning will)
|
700
|
-
# be logged.
|
701
|
-
def max_pool_size(value)
|
702
|
-
if /\A\d+\z/ =~ value
|
703
|
-
return value.to_i
|
704
|
-
end
|
705
|
-
|
706
|
-
log_warn("#{value} is not a valid maxPoolSize")
|
707
|
-
nil
|
708
|
-
end
|
709
|
-
|
710
|
-
|
711
|
-
# Parses the min pool size.
|
712
|
-
#
|
713
|
-
# @param value [ String ] The min pool size string.
|
714
|
-
#
|
715
|
-
# @return [ Integer | nil ] The min pool size if it is valid, otherwise nil (and a warning will
|
716
|
-
# be logged).
|
717
|
-
def min_pool_size(value)
|
718
|
-
if /\A\d+\z/ =~ value
|
719
|
-
return value.to_i
|
720
|
-
end
|
721
|
-
|
722
|
-
log_warn("#{value} is not a valid minPoolSize")
|
723
|
-
nil
|
724
|
-
end
|
725
|
-
|
726
|
-
# Parses the journal value.
|
727
|
-
#
|
728
|
-
# @param value [ String ] The journal value.
|
729
|
-
#
|
730
|
-
# @return [ true | false | nil ] The journal value parsed out, otherwise nil (and a warning
|
731
|
-
# will be logged).
|
732
|
-
def journal(value)
|
733
|
-
convert_bool('journal', value)
|
734
|
-
end
|
735
|
-
|
736
|
-
# Parses the ssl value from the URI.
|
737
|
-
#
|
738
|
-
# @param value [ String ] The ssl value.
|
739
|
-
#
|
740
|
-
# @return [ Array<true | false> ] The ssl value parsed out (stored in an array to facilitate
|
741
|
-
# keeping track of all values).
|
742
|
-
def ssl(value)
|
743
|
-
[convert_bool('ssl', value)]
|
744
|
-
end
|
745
|
-
|
746
|
-
# Parses the tls value from the URI.
|
747
|
-
#
|
748
|
-
# @param value [ String ] The tls value.
|
749
|
-
#
|
750
|
-
# @return [ Array<true | false> ] The tls value parsed out (stored in an array to facilitate
|
751
|
-
# keeping track of all values).
|
752
|
-
def tls(value)
|
753
|
-
[convert_bool('tls', value)]
|
754
|
-
end
|
755
|
-
|
756
|
-
# Parses the ssl_verify value from the tlsInsecure URI value. Note that this will be the inverse
|
757
|
-
# of the value of tlsInsecure (if present).
|
758
|
-
#
|
759
|
-
# @param value [ String ] The tlsInsecure value.
|
760
|
-
#
|
761
|
-
# @return [ true | false | nil ] The ssl_verify value parsed out, otherwise nil (and a warning
|
762
|
-
# will be logged).
|
763
|
-
def ssl_verify(value)
|
764
|
-
inverse_bool('tlsAllowInvalidCertificates', value)
|
765
|
-
end
|
766
|
-
|
767
|
-
# Parses the ssl_verify_certificate value from the tlsAllowInvalidCertificates URI value. Note
|
768
|
-
# that this will be the inverse of the value of tlsInsecure (if present).
|
769
|
-
#
|
770
|
-
# @param value [ String ] The tlsAllowInvalidCertificates value.
|
771
|
-
#
|
772
|
-
# @return [ true | false | nil ] The ssl_verify_certificate value parsed out, otherwise nil
|
773
|
-
# (and a warning will be logged).
|
774
|
-
def ssl_verify_certificate(value)
|
775
|
-
inverse_bool('tlsAllowInvalidCertificates', value)
|
776
|
-
end
|
777
|
-
|
778
|
-
# Parses the ssl_verify_hostname value from the tlsAllowInvalidHostnames URI value. Note that
|
779
|
-
# this will be the inverse of the value of tlsAllowInvalidHostnames (if present).
|
780
|
-
#
|
781
|
-
# @param value [ String ] The tlsAllowInvalidHostnames value.
|
782
|
-
#
|
783
|
-
# @return [ true | false | nil ] The ssl_verify_hostname value parsed out, otherwise nil
|
784
|
-
# (and a warning will be logged).
|
785
|
-
def ssl_verify_hostname(value)
|
786
|
-
inverse_bool('tlsAllowInvalidHostnames', value)
|
787
|
-
end
|
788
|
-
|
789
|
-
# Parses the retryReads value.
|
726
|
+
# Converts the value into a boolean and returns it wrapped in an array.
|
790
727
|
#
|
791
|
-
# @param
|
792
|
-
#
|
793
|
-
# @return [ true | false | nil ] The boolean value parsed out, otherwise nil (and a warning
|
794
|
-
# will be logged).
|
795
|
-
def retry_reads(value)
|
796
|
-
convert_bool('retryReads', value)
|
797
|
-
end
|
798
|
-
|
799
|
-
# Parses the retryWrites value.
|
800
|
-
#
|
801
|
-
# @param value [ String ] The retryWrites value.
|
728
|
+
# @param name [ String ] Name of the URI option being processed.
|
729
|
+
# @param value [ String ] URI option value.
|
802
730
|
#
|
803
|
-
# @return [ true | false
|
804
|
-
#
|
805
|
-
def
|
806
|
-
convert_bool(
|
731
|
+
# @return [ Array<true | false> ] The boolean value parsed and wraped
|
732
|
+
# in an array.
|
733
|
+
def convert_repeated_bool(name, value)
|
734
|
+
[convert_bool(name, value)]
|
807
735
|
end
|
808
736
|
|
809
737
|
# Converts +value+ into an integer.
|
@@ -880,7 +808,7 @@ module Mongo
|
|
880
808
|
#
|
881
809
|
# @return [ true | false | nil ] The inverse of the boolean value parsed out, otherwise nil
|
882
810
|
# (and a warning will be logged).
|
883
|
-
|
811
|
+
def convert_inverse_bool(name, value)
|
884
812
|
b = convert_bool(name, value)
|
885
813
|
|
886
814
|
if b.nil?
|
@@ -897,11 +825,15 @@ module Mongo
|
|
897
825
|
# @return [ Integer | nil ] The max staleness integer parsed out if it is valid, otherwise nil
|
898
826
|
# (and a warning will be logged).
|
899
827
|
def max_staleness(value)
|
900
|
-
if /\A
|
828
|
+
if /\A-?\d+\z/ =~ value
|
901
829
|
int = value.to_i
|
902
830
|
|
903
|
-
if int
|
904
|
-
|
831
|
+
if int == -1
|
832
|
+
int = nil
|
833
|
+
end
|
834
|
+
|
835
|
+
if int && (int >= 0 && int < 90 || int < 0)
|
836
|
+
log_warn("max staleness should be either 0 or greater than 90: #{value}")
|
905
837
|
end
|
906
838
|
|
907
839
|
return int
|
@@ -911,91 +843,6 @@ module Mongo
|
|
911
843
|
nil
|
912
844
|
end
|
913
845
|
|
914
|
-
# Parses the connectTimeoutMS value.
|
915
|
-
#
|
916
|
-
# @param value [ String ] The connectTimeoutMS value.
|
917
|
-
#
|
918
|
-
# @return [ Integer | nil ] The integer parsed out, otherwise nil (and a warning will be
|
919
|
-
# logged).
|
920
|
-
def connect_timeout(value)
|
921
|
-
ms_convert('connectTimeoutMS', value)
|
922
|
-
end
|
923
|
-
|
924
|
-
# Parses the localThresholdMS value.
|
925
|
-
#
|
926
|
-
# @param value [ String ] The localThresholdMS value.
|
927
|
-
#
|
928
|
-
# @return [ Integer | nil ] The integer parsed out, otherwise nil (and a warning will be
|
929
|
-
# logged).
|
930
|
-
def local_threshold(value)
|
931
|
-
ms_convert('localThresholdMS', value)
|
932
|
-
end
|
933
|
-
|
934
|
-
# Parses the heartbeatFrequencyMS value.
|
935
|
-
#
|
936
|
-
# @param value [ String ] The heartbeatFrequencyMS value.
|
937
|
-
#
|
938
|
-
# @return [ Integer | nil ] The integer parsed out, otherwise nil (and a warning will be
|
939
|
-
# logged).
|
940
|
-
def heartbeat_frequency(value)
|
941
|
-
ms_convert('heartbeatFrequencyMS', value)
|
942
|
-
end
|
943
|
-
|
944
|
-
# Parses the maxIdleTimeMS value.
|
945
|
-
#
|
946
|
-
# @param value [ String ] The maxIdleTimeMS value.
|
947
|
-
#
|
948
|
-
# @return [ Integer | nil ] The integer parsed out, otherwise nil (and a warning will be
|
949
|
-
# logged).
|
950
|
-
def max_idle_time(value)
|
951
|
-
ms_convert('maxIdleTimeMS', value)
|
952
|
-
end
|
953
|
-
|
954
|
-
# Parses the serverSelectionMS value.
|
955
|
-
#
|
956
|
-
# @param value [ String ] The serverSelectionMS value.
|
957
|
-
#
|
958
|
-
# @return [ Integer | nil ] The integer parsed out, otherwise nil (and a warning will be
|
959
|
-
# logged).
|
960
|
-
def server_selection_timeout(value)
|
961
|
-
ms_convert('serverSelectionTimeoutMS', value)
|
962
|
-
end
|
963
|
-
|
964
|
-
# Parses the socketTimeoutMS value.
|
965
|
-
#
|
966
|
-
# @param value [ String ] The socketTimeoutMS value.
|
967
|
-
#
|
968
|
-
# @return [ Integer | nil ] The integer parsed out, otherwise nil (and a warning will be
|
969
|
-
# logged).
|
970
|
-
def socket_timeout(value)
|
971
|
-
ms_convert('socketTimeoutMS', value)
|
972
|
-
end
|
973
|
-
|
974
|
-
# Parses the waitQueueTimeoutMS value.
|
975
|
-
#
|
976
|
-
# @param value [ String ] The waitQueueTimeoutMS value.
|
977
|
-
#
|
978
|
-
# @return [ Integer | nil ] The integer parsed out, otherwise nil (and a warning will be
|
979
|
-
# logged).
|
980
|
-
def wait_queue_timeout(value)
|
981
|
-
ms_convert('MS', value)
|
982
|
-
end
|
983
|
-
|
984
|
-
# Parses the wtimeoutMS value.
|
985
|
-
#
|
986
|
-
# @param value [ String ] The wtimeoutMS value.
|
987
|
-
#
|
988
|
-
# @return [ Integer | nil ] The integer parsed out, otherwise nil (and a warning will be
|
989
|
-
# logged).
|
990
|
-
def wtimeout(value)
|
991
|
-
unless /\A\d+\z/ =~ value
|
992
|
-
log_warn("Invalid wtimeoutMS value: #{value}")
|
993
|
-
return nil
|
994
|
-
end
|
995
|
-
|
996
|
-
value.to_i
|
997
|
-
end
|
998
|
-
|
999
846
|
# Ruby's convention is to provide timeouts in seconds, not milliseconds and
|
1000
847
|
# to use fractions where more precision is necessary. The connection string
|
1001
848
|
# options are always in MS so we provide an easy conversion type.
|
@@ -1005,7 +852,7 @@ module Mongo
|
|
1005
852
|
# @return [ Float ] The seconds value.
|
1006
853
|
#
|
1007
854
|
# @since 2.0.0
|
1008
|
-
def
|
855
|
+
def convert_ms(name, value)
|
1009
856
|
unless /\A-?\d+(\.\d+)?\z/ =~ value
|
1010
857
|
log_warn("Invalid ms value for #{name}: #{value}")
|
1011
858
|
return nil
|
@@ -1032,7 +879,7 @@ module Mongo
|
|
1032
879
|
return nil
|
1033
880
|
end
|
1034
881
|
|
1035
|
-
set.merge(
|
882
|
+
set.merge(k.downcase.to_sym => v)
|
1036
883
|
end
|
1037
884
|
end
|
1038
885
|
|