mongo 2.8.0 → 2.9.0.rc0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +12 -0
- data/lib/mongo.rb +15 -1
- data/lib/mongo/address/ipv6.rb +0 -2
- data/lib/mongo/auth/scram/conversation.rb +0 -3
- data/lib/mongo/bulk_write/result_combiner.rb +12 -2
- data/lib/mongo/client.rb +59 -6
- data/lib/mongo/cluster.rb +19 -8
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +0 -2
- data/lib/mongo/cluster/reapers/socket_reaper.rb +12 -9
- data/lib/mongo/collection.rb +1 -1
- data/lib/mongo/collection/view/aggregation.rb +5 -1
- data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +30 -10
- data/lib/mongo/collection/view/iterable.rb +13 -6
- data/lib/mongo/collection/view/map_reduce.rb +12 -10
- data/lib/mongo/collection/view/readable.rb +19 -14
- data/lib/mongo/cursor.rb +12 -8
- data/lib/mongo/database.rb +10 -7
- data/lib/mongo/database/view.rb +18 -11
- data/lib/mongo/error.rb +2 -2
- data/lib/mongo/error/connection_check_out_timeout.rb +49 -0
- data/lib/mongo/error/operation_failure.rb +9 -9
- data/lib/mongo/error/parser.rb +25 -3
- data/lib/mongo/error/pool_closed_error.rb +43 -0
- data/lib/mongo/error/sdam_error_detection.rb +18 -0
- data/lib/mongo/grid/file/chunk.rb +0 -2
- data/lib/mongo/grid/fs_bucket.rb +26 -12
- data/lib/mongo/grid/stream/read.rb +36 -21
- data/lib/mongo/index/view.rb +11 -7
- data/lib/mongo/logger.rb +0 -2
- data/lib/mongo/monitoring.rb +31 -0
- data/lib/mongo/monitoring/cmap_log_subscriber.rb +53 -0
- data/lib/mongo/monitoring/event.rb +1 -0
- data/lib/mongo/monitoring/event/cmap.rb +25 -0
- data/lib/mongo/monitoring/event/cmap/base.rb +28 -0
- data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +78 -0
- data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +56 -0
- data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +63 -0
- data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +64 -0
- data/lib/mongo/monitoring/event/cmap/connection_closed.rb +103 -0
- data/lib/mongo/monitoring/event/cmap/connection_created.rb +64 -0
- data/lib/mongo/monitoring/event/cmap/connection_ready.rb +64 -0
- data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +57 -0
- data/lib/mongo/monitoring/event/cmap/pool_closed.rb +57 -0
- data/lib/mongo/monitoring/event/cmap/pool_created.rb +63 -0
- data/lib/mongo/monitoring/event/command_started.rb +12 -3
- data/lib/mongo/monitoring/publishable.rb +10 -2
- data/lib/mongo/operation.rb +0 -1
- data/lib/mongo/operation/find/legacy/result.rb +1 -0
- data/lib/mongo/operation/list_collections/result.rb +7 -1
- data/lib/mongo/operation/result.rb +10 -1
- data/lib/mongo/operation/shared/executable.rb +15 -0
- data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +29 -0
- data/lib/mongo/operation/shared/specifiable.rb +0 -16
- data/lib/mongo/operation/update/legacy/result.rb +1 -0
- data/lib/mongo/protocol/compressed.rb +0 -2
- data/lib/mongo/protocol/msg.rb +25 -2
- data/lib/mongo/retryable.rb +171 -33
- data/lib/mongo/server.rb +26 -7
- data/lib/mongo/server/app_metadata.rb +0 -2
- data/lib/mongo/server/connectable.rb +8 -2
- data/lib/mongo/server/connection.rb +83 -13
- data/lib/mongo/server/connection_base.rb +1 -1
- data/lib/mongo/server/connection_pool.rb +439 -43
- data/lib/mongo/server/monitor/connection.rb +4 -1
- data/lib/mongo/session.rb +37 -5
- data/lib/mongo/session/session_pool.rb +2 -2
- data/lib/mongo/socket.rb +0 -2
- data/lib/mongo/socket/ssl.rb +0 -2
- data/lib/mongo/uri.rb +127 -66
- data/lib/mongo/uri/srv_protocol.rb +35 -13
- data/lib/mongo/version.rb +1 -1
- data/spec/README.md +190 -63
- data/spec/integration/change_stream_spec.rb +64 -0
- data/spec/integration/command_spec.rb +0 -7
- data/spec/integration/error_detection_spec.rb +39 -0
- data/spec/integration/read_concern.rb +83 -0
- data/spec/integration/retryable_writes_spec.rb +6 -50
- data/spec/integration/sdam_error_handling_spec.rb +60 -7
- data/spec/integration/ssl_uri_options_spec.rb +24 -0
- data/spec/integration/step_down_spec.rb +197 -0
- data/spec/lite_spec_helper.rb +4 -0
- data/spec/mongo/client_construction_spec.rb +42 -17
- data/spec/mongo/client_spec.rb +32 -1
- data/spec/mongo/cluster/socket_reaper_spec.rb +2 -2
- data/spec/mongo/cluster_spec.rb +36 -2
- data/spec/mongo/collection/view/aggregation_spec.rb +2 -0
- data/spec/mongo/collection/view/change_stream_spec.rb +28 -28
- data/spec/mongo/collection/view/readable_spec.rb +1 -1
- data/spec/mongo/collection/view_spec.rb +3 -1
- data/spec/mongo/cursor_spec.rb +5 -5
- data/spec/mongo/error/parser_spec.rb +61 -1
- data/spec/mongo/grid/stream/read_spec.rb +2 -2
- data/spec/mongo/monitoring/event/cmap/connection_check_out_failed_spec.rb +23 -0
- data/spec/mongo/monitoring/event/cmap/connection_check_out_started_spec.rb +19 -0
- data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +23 -0
- data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +23 -0
- data/spec/mongo/monitoring/event/cmap/connection_closed_spec.rb +27 -0
- data/spec/mongo/monitoring/event/cmap/connection_created_spec.rb +24 -0
- data/spec/mongo/monitoring/event/cmap/connection_ready_spec.rb +24 -0
- data/spec/mongo/monitoring/event/cmap/pool_cleared_spec.rb +19 -0
- data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +19 -0
- data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +26 -0
- data/spec/mongo/operation/delete/bulk_spec.rb +1 -6
- data/spec/mongo/operation/delete/command_spec.rb +1 -1
- data/spec/mongo/operation/delete/op_msg_spec.rb +1 -1
- data/spec/mongo/operation/delete_spec.rb +4 -4
- data/spec/mongo/operation/insert/bulk_spec.rb +1 -1
- data/spec/mongo/operation/insert/command_spec.rb +1 -1
- data/spec/mongo/operation/insert/op_msg_spec.rb +1 -1
- data/spec/mongo/operation/update/bulk_spec.rb +1 -1
- data/spec/mongo/operation/update/command_spec.rb +2 -2
- data/spec/mongo/operation/update/op_msg_spec.rb +2 -2
- data/spec/mongo/protocol/msg_spec.rb +11 -0
- data/spec/mongo/retryable_spec.rb +78 -25
- data/spec/mongo/server/connection_pool_spec.rb +661 -126
- data/spec/mongo/server/connection_spec.rb +55 -7
- data/spec/mongo/server_spec.rb +5 -0
- data/spec/mongo/uri/srv_protocol_spec.rb +135 -2
- data/spec/mongo/uri_option_parsing_spec.rb +511 -0
- data/spec/mongo/uri_spec.rb +42 -6
- data/spec/spec_helper.rb +1 -84
- data/spec/spec_tests/cmap_spec.rb +50 -0
- data/spec/spec_tests/command_monitoring_spec.rb +7 -18
- data/spec/spec_tests/crud_spec.rb +3 -49
- data/spec/spec_tests/data/cmap/connection-must-have-id.yml +21 -0
- data/spec/spec_tests/data/cmap/connection-must-order-ids.yml +21 -0
- data/spec/spec_tests/data/cmap/pool-checkin-destroy-closed.yml +24 -0
- data/spec/spec_tests/data/cmap/pool-checkin-destroy-stale.yml +24 -0
- data/spec/spec_tests/data/cmap/pool-checkin-make-available.yml +21 -0
- data/spec/spec_tests/data/cmap/pool-checkin.yml +18 -0
- data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +13 -0
- data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +28 -0
- data/spec/spec_tests/data/cmap/pool-checkout-multiple.yml +34 -0
- data/spec/spec_tests/data/cmap/pool-checkout-no-idle.yml +31 -0
- data/spec/spec_tests/data/cmap/pool-checkout-no-stale.yml +29 -0
- data/spec/spec_tests/data/cmap/pool-close-destroy-conns.yml +26 -0
- data/spec/spec_tests/data/cmap/pool-close.yml +11 -0
- data/spec/spec_tests/data/cmap/pool-create-max-size.yml +56 -0
- data/spec/spec_tests/data/cmap/pool-create-min-size.yml +27 -0
- data/spec/spec_tests/data/cmap/pool-create-with-options.yml +20 -0
- data/spec/spec_tests/data/cmap/pool-create.yml +12 -0
- data/spec/spec_tests/data/cmap/wait-queue-fairness.yml +94 -0
- data/spec/spec_tests/data/cmap/wait-queue-timeout.yml +41 -0
- data/spec/spec_tests/data/retryable_reads/aggregate-serverErrors.yml +157 -0
- data/spec/spec_tests/data/retryable_reads/aggregate.yml +87 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +149 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +61 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +149 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +65 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +153 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +61 -0
- data/spec/spec_tests/data/retryable_reads/count-serverErrors.yml +150 -0
- data/spec/spec_tests/data/retryable_reads/count.yml +64 -0
- data/spec/spec_tests/data/retryable_reads/countDocuments-serverErrors.yml +150 -0
- data/spec/spec_tests/data/retryable_reads/countDocuments.yml +64 -0
- data/spec/spec_tests/data/retryable_reads/distinct-serverErrors.yml +156 -0
- data/spec/spec_tests/data/retryable_reads/distinct.yml +71 -0
- data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors.yml +148 -0
- data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount.yml +62 -0
- data/spec/spec_tests/data/retryable_reads/find-serverErrors.yml +160 -0
- data/spec/spec_tests/data/retryable_reads/find.yml +86 -0
- data/spec/spec_tests/data/retryable_reads/findOne-serverErrors.yml +154 -0
- data/spec/spec_tests/data/retryable_reads/findOne.yml +68 -0
- data/spec/spec_tests/data/retryable_reads/gridfs-download-serverErrors.yml +173 -0
- data/spec/spec_tests/data/retryable_reads/gridfs-download.yml +79 -0
- data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName-serverErrors.yml +174 -0
- data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName.yml +79 -0
- data/spec/spec_tests/data/retryable_reads/listCollectionNames-serverErrors.yml +143 -0
- data/spec/spec_tests/data/retryable_reads/listCollectionNames.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listCollectionObjects-serverErrors.yml +144 -0
- data/spec/spec_tests/data/retryable_reads/listCollectionObjects.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listCollections-serverErrors.yml +143 -0
- data/spec/spec_tests/data/retryable_reads/listCollections.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listDatabaseNames-serverErrors.yml +143 -0
- data/spec/spec_tests/data/retryable_reads/listDatabaseNames.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listDatabaseObjects-serverErrors.yml +144 -0
- data/spec/spec_tests/data/retryable_reads/listDatabaseObjects.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listDatabases-serverErrors.yml +144 -0
- data/spec/spec_tests/data/retryable_reads/listDatabases.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listIndexNames-serverErrors.yml +144 -0
- data/spec/spec_tests/data/retryable_reads/listIndexNames.yml +60 -0
- data/spec/spec_tests/data/retryable_reads/listIndexes-serverErrors.yml +145 -0
- data/spec/spec_tests/data/retryable_reads/listIndexes.yml +60 -0
- data/spec/spec_tests/data/retryable_reads/mapReduce.yml +60 -0
- data/spec/spec_tests/data/retryable_writes/bulkWrite-serverErrors.yml +10 -7
- data/spec/spec_tests/data/retryable_writes/bulkWrite.yml +15 -22
- data/spec/spec_tests/data/retryable_writes/deleteMany.yml +22 -0
- data/spec/spec_tests/data/retryable_writes/deleteOne-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/deleteOne.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/findOneAndDelete-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/findOneAndDelete.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/findOneAndReplace-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/findOneAndReplace.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/findOneAndUpdate.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/insertMany-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/insertMany.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +10 -45
- data/spec/spec_tests/data/retryable_writes/insertOne.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/replaceOne-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/replaceOne.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/updateMany.yml +27 -0
- data/spec/spec_tests/data/retryable_writes/updateOne-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/updateOne.yml +5 -14
- data/spec/spec_tests/data/transactions/abort.yml +7 -2
- data/spec/spec_tests/data/transactions/bulk.yml +7 -2
- data/spec/spec_tests/data/transactions/causal-consistency.yml +11 -4
- data/spec/spec_tests/data/transactions/commit.yml +11 -4
- data/spec/spec_tests/data/transactions/count.yml +64 -0
- data/spec/spec_tests/data/transactions/delete.yml +7 -2
- data/spec/spec_tests/data/transactions/error-labels.yml +8 -2
- data/spec/spec_tests/data/transactions/errors.yml +7 -2
- data/spec/spec_tests/data/transactions/findOneAndDelete.yml +7 -2
- data/spec/spec_tests/data/transactions/findOneAndReplace.yml +7 -2
- data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +7 -2
- data/spec/spec_tests/data/transactions/insert.yml +9 -2
- data/spec/spec_tests/data/transactions/isolation.yml +7 -2
- data/spec/spec_tests/data/transactions/read-concern.yml +15 -6
- data/spec/spec_tests/data/transactions/read-pref.yml +7 -2
- data/spec/spec_tests/data/transactions/reads.yml +8 -48
- data/spec/spec_tests/data/transactions/retryable-abort.yml +7 -2
- data/spec/spec_tests/data/transactions/retryable-commit.yml +7 -2
- data/spec/spec_tests/data/transactions/retryable-writes.yml +7 -2
- data/spec/spec_tests/data/transactions/run-command.yml +7 -2
- data/spec/spec_tests/data/transactions/transaction-options.yml +7 -2
- data/spec/spec_tests/data/transactions/update.yml +7 -2
- data/spec/spec_tests/data/transactions/write-concern.yml +7 -2
- data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -1
- data/spec/spec_tests/data/transactions_api/callback-commits.yml +6 -1
- data/spec/spec_tests/data/transactions_api/callback-retry.yml +6 -1
- data/spec/spec_tests/data/transactions_api/commit-retry.yml +6 -1
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +6 -3
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +6 -1
- data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +6 -1
- data/spec/spec_tests/data/transactions_api/commit.yml +6 -1
- data/spec/spec_tests/data/transactions_api/transaction-options.yml +6 -1
- data/spec/spec_tests/retryable_reads_spec.rb +11 -0
- data/spec/spec_tests/retryable_writes_spec.rb +4 -69
- data/spec/spec_tests/transactions_api_spec.rb +42 -37
- data/spec/spec_tests/transactions_spec.rb +42 -33
- data/spec/support/authorization.rb +12 -0
- data/spec/support/change_streams/operation.rb +1 -1
- data/spec/support/client_registry.rb +20 -0
- data/spec/support/cluster_config.rb +16 -15
- data/spec/support/cluster_tools.rb +346 -0
- data/spec/support/cmap.rb +367 -0
- data/spec/support/cmap/verifier.rb +46 -0
- data/spec/support/command_monitoring.rb +4 -6
- data/spec/support/common_shortcuts.rb +6 -0
- data/spec/support/connection_string.rb +2 -2
- data/spec/support/crud.rb +171 -184
- data/spec/support/crud/operation.rb +43 -0
- data/spec/support/crud/outcome.rb +53 -0
- data/spec/support/crud/read.rb +102 -12
- data/spec/support/crud/requirement.rb +69 -0
- data/spec/support/crud/spec.rb +68 -0
- data/spec/support/crud/test.rb +141 -0
- data/spec/support/crud/verifier.rb +96 -18
- data/spec/support/crud/write.rb +18 -3
- data/spec/support/event_subscriber.rb +15 -0
- data/spec/support/primary_socket.rb +2 -2
- data/spec/support/spec_config.rb +89 -20
- data/spec/support/transactions.rb +2 -306
- data/spec/support/transactions/operation.rb +7 -7
- data/spec/support/transactions/spec.rb +28 -0
- data/spec/support/transactions/test.rb +191 -0
- data/spec/support/utils.rb +123 -0
- metadata +202 -9
- metadata.gz.sig +0 -0
- data/lib/mongo/server/connection_pool/queue.rb +0 -359
- data/spec/mongo/server/connection_pool/queue_spec.rb +0 -353
- data/spec/support/transactions/verifier.rb +0 -97
@@ -179,10 +179,13 @@ module Mongo
|
|
179
179
|
# @note This method mutates the connection by setting the socket to nil
|
180
180
|
# if the closing succeeded.
|
181
181
|
#
|
182
|
+
# @note This method accepts an options argument for compatibility with
|
183
|
+
# Server::Connections. However, all options are ignored.
|
184
|
+
#
|
182
185
|
# @return [ true ] If the disconnect succeeded.
|
183
186
|
#
|
184
187
|
# @since 2.0.0
|
185
|
-
def disconnect!
|
188
|
+
def disconnect!(options = nil)
|
186
189
|
if socket
|
187
190
|
socket.close
|
188
191
|
@socket = nil
|
data/lib/mongo/session.rb
CHANGED
@@ -443,6 +443,26 @@ module Mongo
|
|
443
443
|
end
|
444
444
|
end
|
445
445
|
|
446
|
+
# Whether reads executed with this session can be retried according to
|
447
|
+
# the modern retryable reads specification.
|
448
|
+
#
|
449
|
+
# If this method returns true, the modern retryable reads have been
|
450
|
+
# requested by the application. If the server selected for a read operation
|
451
|
+
# supports modern retryable reads, they will be used for that particular
|
452
|
+
# operation. If the server selected for a read operation does not support
|
453
|
+
# modern retryable reads, the read will not be retried.
|
454
|
+
#
|
455
|
+
# If this method returns false, legacy retryable reads have been requested
|
456
|
+
# by the application. Legacy retryable read logic will be used regardless
|
457
|
+
# of server version of the server(s) that the client is connected to.
|
458
|
+
# The number of read retries is given by :max_read_retries client option,
|
459
|
+
# which is 1 by default and can be set to 0 to disable legacy read retries.
|
460
|
+
#
|
461
|
+
# @api private
|
462
|
+
def retry_reads?
|
463
|
+
client.options[:retry_reads] != false
|
464
|
+
end
|
465
|
+
|
446
466
|
# Will writes executed with this session be retried.
|
447
467
|
#
|
448
468
|
# @example Will writes be retried.
|
@@ -874,6 +894,23 @@ module Mongo
|
|
874
894
|
@client.cluster
|
875
895
|
end
|
876
896
|
|
897
|
+
protected
|
898
|
+
|
899
|
+
# Get the read concern the session will use when starting a transaction.
|
900
|
+
#
|
901
|
+
# This is a driver style hash with underscore keys.
|
902
|
+
#
|
903
|
+
# @example Get the session's transaction read concern.
|
904
|
+
# session.txn_read_concern
|
905
|
+
#
|
906
|
+
# @return [ Hash ] The read concern used for starting transactions.
|
907
|
+
#
|
908
|
+
# @since 2.9.0
|
909
|
+
def txn_read_concern
|
910
|
+
# Read concern is inherited from client but not db or collection.
|
911
|
+
txn_options && txn_options[:read_concern] || @client.read_concern
|
912
|
+
end
|
913
|
+
|
877
914
|
private
|
878
915
|
|
879
916
|
def within_states?(*states)
|
@@ -891,11 +928,6 @@ module Mongo
|
|
891
928
|
Mongo::Error::InvalidTransactionOperation::NO_TRANSACTION_STARTED)
|
892
929
|
end
|
893
930
|
|
894
|
-
def txn_read_concern
|
895
|
-
# Read concern is inherited from client but not db or collection.
|
896
|
-
txn_options && txn_options[:read_concern] || @client.read_concern
|
897
|
-
end
|
898
|
-
|
899
931
|
def txn_write_concern
|
900
932
|
(txn_options && txn_options[:write_concern]) ||
|
901
933
|
(@client.write_concern && @client.write_concern.options)
|
@@ -64,9 +64,9 @@ module Mongo
|
|
64
64
|
"#<Mongo::Session::SessionPool:0x#{object_id} current_size=#{@queue.size}>"
|
65
65
|
end
|
66
66
|
|
67
|
-
#
|
67
|
+
# Check out a server session from the pool.
|
68
68
|
#
|
69
|
-
# @example
|
69
|
+
# @example Check out a session.
|
70
70
|
# pool.checkout
|
71
71
|
#
|
72
72
|
# @return [ ServerSession ] The server session.
|
data/lib/mongo/socket.rb
CHANGED
data/lib/mongo/socket/ssl.rb
CHANGED
data/lib/mongo/uri.rb
CHANGED
@@ -12,8 +12,6 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
require 'uri'
|
16
|
-
|
17
15
|
module Mongo
|
18
16
|
|
19
17
|
# The URI class provides a way for users to parse the MongoDB uri as
|
@@ -260,6 +258,9 @@ module Mongo
|
|
260
258
|
@options = options
|
261
259
|
parsed_scheme, _, remaining = string.partition(SCHEME_DELIM)
|
262
260
|
raise_invalid_error!(INVALID_SCHEME) unless parsed_scheme == scheme
|
261
|
+
if remaining.empty?
|
262
|
+
raise_invalid_error!('No hosts in the URI')
|
263
|
+
end
|
263
264
|
parse!(remaining)
|
264
265
|
|
265
266
|
# The URI options spec requires that we raise an error if there are conflicting values of
|
@@ -283,6 +284,12 @@ module Mongo
|
|
283
284
|
raise_invalid_error_no_fmt!("tlsInsecure' and 'tlsAllowInvalidHostnames' cannot both be specified")
|
284
285
|
end
|
285
286
|
end
|
287
|
+
|
288
|
+
# Since we know that the only URI option that sets :ssl_cert is "tlsCertificateKeyFile", any
|
289
|
+
# value set for :ssl_cert must also be set for :ssl_key.
|
290
|
+
if @uri_options[:ssl_cert]
|
291
|
+
@uri_options[:ssl_key] = @uri_options[:ssl_cert]
|
292
|
+
end
|
286
293
|
end
|
287
294
|
|
288
295
|
# Get the credentials provided in the URI.
|
@@ -317,17 +324,38 @@ module Mongo
|
|
317
324
|
MONGODB_SCHEME
|
318
325
|
end
|
319
326
|
|
320
|
-
def
|
321
|
-
|
327
|
+
def parse!(remaining)
|
328
|
+
hosts_and_db, options = remaining.split('?', 2)
|
329
|
+
if options && options.index('?')
|
330
|
+
raise_invalid_error!("Options contain an unescaped question mark (?), or the database name contains a question mark and was not escaped")
|
331
|
+
end
|
332
|
+
|
333
|
+
if options && !hosts_and_db.index('/')
|
334
|
+
raise_invalid_error!("MongoDB URI must have a slash (/) after the hosts if options are given")
|
335
|
+
end
|
336
|
+
|
337
|
+
hosts, db = hosts_and_db.split('/', 2)
|
338
|
+
if db && db.index('/')
|
339
|
+
raise_invalid_error!("Database name contains an unescaped slash (/): #{db}")
|
340
|
+
end
|
341
|
+
|
342
|
+
if hosts.index('@')
|
343
|
+
creds, hosts = hosts.split('@', 2)
|
344
|
+
if hosts.empty?
|
345
|
+
raise_invalid_error!("Empty hosts list")
|
346
|
+
end
|
347
|
+
if hosts.index('@')
|
348
|
+
raise_invalid_error!("Unescaped @ in auth info")
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
322
352
|
@servers = parse_servers!(hosts)
|
323
353
|
@user = parse_user!(creds)
|
324
354
|
@password = parse_password!(creds)
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
parse_creds_hosts!(creds_hosts)
|
330
|
-
parse_db_opts!(db_opts)
|
355
|
+
@uri_options = Options::Redacted.new(parse_uri_options!(options))
|
356
|
+
if db
|
357
|
+
@database = parse_database!(db)
|
358
|
+
end
|
331
359
|
end
|
332
360
|
|
333
361
|
def extract_db_opts!(string)
|
@@ -339,28 +367,23 @@ module Mongo
|
|
339
367
|
[ creds_hosts, db_opts ].map { |s| s.reverse }
|
340
368
|
end
|
341
369
|
|
342
|
-
def split_creds_hosts(string)
|
343
|
-
hosts, _, creds = string.reverse.partition(AUTH_DELIM)
|
344
|
-
hosts, creds = creds, hosts if hosts.empty?
|
345
|
-
[ hosts, creds ].map { |s| s.reverse }
|
346
|
-
end
|
347
|
-
|
348
|
-
def parse_db_opts!(string)
|
349
|
-
auth_db, _, uri_opts = string.partition(URI_OPTS_DELIM)
|
350
|
-
@uri_options = Options::Redacted.new(parse_uri_options!(uri_opts))
|
351
|
-
@database = parse_database!(auth_db)
|
352
|
-
end
|
353
|
-
|
354
370
|
def parse_uri_options!(string)
|
355
371
|
return {} unless string
|
356
372
|
string.split(INDIV_URI_OPTS_DELIM).reduce({}) do |uri_options, opt|
|
357
|
-
|
358
|
-
|
373
|
+
key, value = opt.split('=', 2)
|
374
|
+
if value.nil?
|
375
|
+
raise_invalid_error!("Option #{key} has no value")
|
376
|
+
end
|
377
|
+
if value.index('=')
|
378
|
+
raise_invalid_error!("Value for option #{key} contains the key/value delimiter (=): #{value}")
|
379
|
+
end
|
380
|
+
key = ::URI.decode(key)
|
359
381
|
strategy = URI_OPTION_MAP[key.downcase]
|
360
382
|
if strategy.nil?
|
361
383
|
log_warn("Unsupported URI option '#{key}' on URI '#{@string}'. It will be ignored.")
|
362
384
|
else
|
363
|
-
|
385
|
+
value = ::URI.decode(value)
|
386
|
+
add_uri_option(key, strategy, value, uri_options)
|
364
387
|
end
|
365
388
|
uri_options
|
366
389
|
end
|
@@ -465,10 +488,10 @@ module Mongo
|
|
465
488
|
uri_option 'maxidletimems', :max_idle_time, :type => :max_idle_time
|
466
489
|
|
467
490
|
# Write Options
|
468
|
-
uri_option 'w', :w, :group => :write
|
491
|
+
uri_option 'w', :w, :group => :write, type: :w
|
469
492
|
uri_option 'journal', :j, :group => :write, :type => :journal
|
470
|
-
uri_option 'fsync', :fsync, :group => :write
|
471
|
-
uri_option 'wtimeoutms', :
|
493
|
+
uri_option 'fsync', :fsync, :group => :write, type: :bool
|
494
|
+
uri_option 'wtimeoutms', :wtimeout, :group => :write, :type => :wtimeout
|
472
495
|
|
473
496
|
# Read Options
|
474
497
|
uri_option 'readpreference', :mode, :group => :read, :type => :read_mode
|
@@ -493,7 +516,7 @@ module Mongo
|
|
493
516
|
uri_option 'tlsinsecure', :ssl_verify, :type => :ssl_verify
|
494
517
|
|
495
518
|
# Topology options
|
496
|
-
uri_option 'connect', :connect
|
519
|
+
uri_option 'connect', :connect, type: :symbol
|
497
520
|
|
498
521
|
# Auth Options
|
499
522
|
uri_option 'authsource', :auth_source, :type => :auth_source
|
@@ -503,38 +526,25 @@ module Mongo
|
|
503
526
|
# Client Options
|
504
527
|
uri_option 'appname', :app_name
|
505
528
|
uri_option 'compressors', :compressors, :type => :array
|
506
|
-
uri_option 'readconcernlevel', :read_concern
|
529
|
+
uri_option 'readconcernlevel', :level, group: :read_concern
|
507
530
|
uri_option 'retrywrites', :retry_writes, :type => :retry_writes
|
508
531
|
uri_option 'zlibcompressionlevel', :zlib_compression_level, :type => :zlib_compression_level
|
509
532
|
|
510
|
-
# Casts option values that do not have a specifically provided
|
511
|
-
# transformation to the appropriate type.
|
512
|
-
#
|
513
|
-
# @param value [String] The value to be cast.
|
514
|
-
#
|
515
|
-
# @return [true, false, Fixnum, Symbol] The cast value.
|
516
|
-
def cast(value)
|
517
|
-
if value == 'true'
|
518
|
-
true
|
519
|
-
elsif value == 'false'
|
520
|
-
false
|
521
|
-
elsif value =~ /\A[\d]\z/
|
522
|
-
value.to_i
|
523
|
-
else
|
524
|
-
decode(value).to_sym
|
525
|
-
end
|
526
|
-
end
|
527
|
-
|
528
533
|
# Applies URI value transformation by either using the default cast
|
529
534
|
# or a transformation appropriate for the given type.
|
530
535
|
#
|
536
|
+
# @param key [String] URI option name.
|
531
537
|
# @param value [String] The value to be transformed.
|
532
538
|
# @param type [Symbol] The transform method.
|
533
|
-
def apply_transform(value, type
|
539
|
+
def apply_transform(key, value, type)
|
534
540
|
if type
|
535
|
-
|
541
|
+
if respond_to?("convert_#{type}", true)
|
542
|
+
send("convert_#{type}", key, value)
|
543
|
+
else
|
544
|
+
send(type, value)
|
545
|
+
end
|
536
546
|
else
|
537
|
-
|
547
|
+
value
|
538
548
|
end
|
539
549
|
end
|
540
550
|
|
@@ -581,12 +591,13 @@ module Mongo
|
|
581
591
|
# Transforms the value.
|
582
592
|
# Merges the option into the target.
|
583
593
|
#
|
594
|
+
# @param key [String] URI option name.
|
584
595
|
# @param strategy [Symbol] The strategy for this option.
|
585
596
|
# @param value [String] The value of the option.
|
586
597
|
# @param uri_options [Hash] The base option target.
|
587
|
-
def add_uri_option(strategy, value, uri_options)
|
598
|
+
def add_uri_option(key, strategy, value, uri_options)
|
588
599
|
target = select_target(uri_options, strategy[:group])
|
589
|
-
value = apply_transform(value, strategy[:type])
|
600
|
+
value = apply_transform(key, value, strategy[:type])
|
590
601
|
merge_uri_option(target, value, strategy[:name])
|
591
602
|
end
|
592
603
|
|
@@ -656,7 +667,7 @@ module Mongo
|
|
656
667
|
properties = hash_extractor('authMechanismProperties', value)
|
657
668
|
if properties[:canonicalize_host_name]
|
658
669
|
properties.merge!(canonicalize_host_name:
|
659
|
-
|
670
|
+
%w(true TRUE).include?(properties[:canonicalize_host_name]))
|
660
671
|
end
|
661
672
|
properties
|
662
673
|
end
|
@@ -718,7 +729,7 @@ module Mongo
|
|
718
729
|
# @return [ true | false | nil ] The journal value parsed out, otherwise nil (and a warning
|
719
730
|
# will be logged).
|
720
731
|
def journal(value)
|
721
|
-
|
732
|
+
convert_bool('journal', value)
|
722
733
|
end
|
723
734
|
|
724
735
|
# Parses the ssl value from the URI.
|
@@ -728,7 +739,7 @@ module Mongo
|
|
728
739
|
# @return [ Array<true | false> ] The ssl value parsed out (stored in an array to facilitate
|
729
740
|
# keeping track of all values).
|
730
741
|
def ssl(value)
|
731
|
-
[
|
742
|
+
[convert_bool('ssl', value)]
|
732
743
|
end
|
733
744
|
|
734
745
|
# Parses the tls value from the URI.
|
@@ -738,7 +749,7 @@ module Mongo
|
|
738
749
|
# @return [ Array<true | false> ] The tls value parsed out (stored in an array to facilitate
|
739
750
|
# keeping track of all values).
|
740
751
|
def tls(value)
|
741
|
-
[
|
752
|
+
[convert_bool('tls', value)]
|
742
753
|
end
|
743
754
|
|
744
755
|
# Parses the ssl_verify value from the tlsInsecure URI value. Note that this will be the inverse
|
@@ -781,20 +792,70 @@ module Mongo
|
|
781
792
|
# @return [ true | false | nil ] The boolean value parsed out, otherwise nil (and a warning
|
782
793
|
# will be logged).
|
783
794
|
def retry_writes(value)
|
784
|
-
|
795
|
+
convert_bool('retryWrites', value)
|
785
796
|
end
|
786
797
|
|
787
|
-
#
|
798
|
+
# Converts +value+ into an integer.
|
788
799
|
#
|
789
|
-
#
|
800
|
+
# If the value is not a valid integer, warns and returns nil.
|
790
801
|
#
|
791
|
-
# @
|
792
|
-
#
|
793
|
-
|
802
|
+
# @param name [ String ] Name of the URI option being processed.
|
803
|
+
# @param value [ String ] URI option value.
|
804
|
+
#
|
805
|
+
# @return [ nil | Integer ] Converted value.
|
806
|
+
def convert_integer(name, value)
|
807
|
+
unless /\A\d+\z/ =~ value
|
808
|
+
log_warn("#{value} is not a valid integer for #{name}")
|
809
|
+
return nil
|
810
|
+
end
|
811
|
+
|
812
|
+
value.to_i
|
813
|
+
end
|
814
|
+
|
815
|
+
# Converts +value+ into a symbol.
|
816
|
+
#
|
817
|
+
# @param name [ String ] Name of the URI option being processed.
|
818
|
+
# @param value [ String ] URI option value.
|
819
|
+
#
|
820
|
+
# @return [ Symbol ] Converted value.
|
821
|
+
def convert_symbol(name, value)
|
822
|
+
value.to_sym
|
823
|
+
end
|
824
|
+
|
825
|
+
# Converts +value+ as a write concern.
|
826
|
+
#
|
827
|
+
# If +value+ is the word "majority", returns the symbol :majority.
|
828
|
+
# If +value+ is a number, returns the number as an integer.
|
829
|
+
# Otherwise returns the string +value+ unchanged.
|
830
|
+
#
|
831
|
+
# @param name [ String ] Name of the URI option being processed.
|
832
|
+
# @param value [ String ] URI option value.
|
833
|
+
#
|
834
|
+
# @return [ Integer | Symbol | String ] Converted value.
|
835
|
+
def convert_w(name, value)
|
836
|
+
case value
|
837
|
+
when 'majority'
|
838
|
+
:majority
|
839
|
+
when /\A[0-9]+\z/
|
840
|
+
value.to_i
|
841
|
+
else
|
842
|
+
value
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
# Converts +value+ to a boolean.
|
847
|
+
#
|
848
|
+
# Returns true for 'true', false for 'false', otherwise nil.
|
849
|
+
#
|
850
|
+
# @param name [ String ] Name of the URI option being processed.
|
851
|
+
# @param value [ String ] URI option value.
|
852
|
+
#
|
853
|
+
# @return [ true | false | nil ] Converted value.
|
854
|
+
def convert_bool(name, value)
|
794
855
|
case value
|
795
|
-
when "true"
|
856
|
+
when "true", 'TRUE'
|
796
857
|
true
|
797
|
-
when "false"
|
858
|
+
when "false", 'FALSE'
|
798
859
|
false
|
799
860
|
else
|
800
861
|
log_warn("invalid boolean option for #{name}: #{value}")
|
@@ -809,7 +870,7 @@ module Mongo
|
|
809
870
|
# @return [ true | false | nil ] The inverse of the boolean value parsed out, otherwise nil
|
810
871
|
# (and a warning will be logged).
|
811
872
|
def inverse_bool(name, value)
|
812
|
-
b =
|
873
|
+
b = convert_bool(name, value)
|
813
874
|
|
814
875
|
if b.nil?
|
815
876
|
nil
|
@@ -12,8 +12,6 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
require 'resolv'
|
16
|
-
|
17
15
|
module Mongo
|
18
16
|
|
19
17
|
class URI
|
@@ -65,6 +63,7 @@ module Mongo
|
|
65
63
|
INVALID_PORT = "It is not allowed to specify a port in a connection string with the " +
|
66
64
|
"'#{MONGODB_SRV_SCHEME}' protocol.".freeze
|
67
65
|
|
66
|
+
# @deprecated
|
68
67
|
INVALID_DOMAIN = "The domain name must consist of at least two parts: the domain name, " +
|
69
68
|
"and a TLD.".freeze
|
70
69
|
|
@@ -93,22 +92,45 @@ module Mongo
|
|
93
92
|
@resolver ||= Resolv::DNS.new
|
94
93
|
end
|
95
94
|
|
96
|
-
def
|
97
|
-
|
98
|
-
|
95
|
+
def parse!(remaining)
|
96
|
+
super
|
97
|
+
|
98
|
+
if @servers.length != 1
|
99
|
+
raise_invalid_error!(INVALID_HOST)
|
100
|
+
end
|
101
|
+
hostname = @servers.first
|
102
|
+
validate_hostname(hostname)
|
103
|
+
|
99
104
|
records = get_records(hostname)
|
100
105
|
@txt_options = get_txt_opts(hostname) || {}
|
101
106
|
@servers = parse_servers!(records.join(','))
|
102
|
-
@user = parse_user!(creds)
|
103
|
-
@password = parse_password!(creds)
|
104
107
|
end
|
105
108
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
+
# Validates the hostname used in an SRV URI.
|
110
|
+
#
|
111
|
+
# The hostname cannot include a port.
|
112
|
+
#
|
113
|
+
# The hostname must not begin with a dot, end with a dot, or have
|
114
|
+
# consecutive dots. The hostname must have a minimum of 3 total
|
115
|
+
# components (foo.bar.tld).
|
116
|
+
#
|
117
|
+
# Raises Error::InvalidURI if validation fails.
|
118
|
+
def validate_hostname(hostname)
|
109
119
|
raise_invalid_error!(INVALID_PORT) if hostname.include?(HOST_PORT_DELIM)
|
110
|
-
|
111
|
-
|
120
|
+
|
121
|
+
if hostname.start_with?('.')
|
122
|
+
raise_invalid_error!("Hostname cannot start with a dot: #{hostname}")
|
123
|
+
end
|
124
|
+
if hostname.end_with?('.')
|
125
|
+
raise_invalid_error!("Hostname cannot end with a dot: #{hostname}")
|
126
|
+
end
|
127
|
+
parts = hostname.split('.')
|
128
|
+
if parts.any?(&:empty?)
|
129
|
+
raise_invalid_error!("Hostname cannot have consecutive dots: #{hostname}")
|
130
|
+
end
|
131
|
+
if parts.length < 3
|
132
|
+
raise_invalid_error!("Hostname must have a minimum of 3 components (foo.bar.tld): #{hostname}")
|
133
|
+
end
|
112
134
|
end
|
113
135
|
|
114
136
|
def get_records(hostname)
|
@@ -149,7 +171,7 @@ module Mongo
|
|
149
171
|
key, value = opt.split(URI_OPTS_VALUE_DELIM)
|
150
172
|
raise Error::InvalidTXTRecord.new(INVALID_TXT_RECORD_OPTION) unless VALID_TXT_OPTIONS.include?(key.downcase)
|
151
173
|
strategy = URI_OPTION_MAP[key.downcase]
|
152
|
-
add_uri_option(strategy, value, txt_options)
|
174
|
+
add_uri_option(key, strategy, value, txt_options)
|
153
175
|
txt_options
|
154
176
|
end
|
155
177
|
end
|