@@ -30,8 +30,9 @@ class MongoClient
3030 DEFAULT_HOST = 'localhost'
3131 DEFAULT_PORT = 27017
3232 DEFAULT_DB_NAME = 'test'
33- GENERIC_OPTS = [ :ssl , : auths, :logger , :connect ]
33+ GENERIC_OPTS = [ :auths , :logger , :connect ]
3434 TIMEOUT_OPTS = [ :timeout , :op_timeout , :connect_timeout ]
35+ SSL_OPTS = [ :ssl , :ssl_key , :ssl_cert , :ssl_verify , :ssl_ca_cert ]
3536 POOL_OPTS = [ :pool_size , :pool_timeout ]
3637 READ_PREFERENCE_OPTS = [ :read , :tag_sets , :secondary_acceptable_latency_ms ]
3738 WRITE_CONCERN_OPTS = [ :w , :j , :fsync , :wtimeout ]
@@ -50,6 +51,7 @@ class MongoClient
5051 :pool_timeout ,
5152 :primary_pool ,
5253 :socket_class ,
54+ :socket_opts ,
5355 :op_timeout ,
5456 :tag_sets ,
5557 :acceptable_latency ,
@@ -69,33 +71,43 @@ class MongoClient
6971 # MongoClient#arbiters. This is useful if your application needs to connect manually to nodes other
7072 # than the primary.
7173 #
72- # @param [String] host
73- # @param [Integer] port specify a port number here if only one host is being specified.
74- #
75- # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
76- # should be acknowledged
77- # @option opts [Boolean] :j (false) Set journal acknowledgement
78- # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
79- # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
80- #
81- # Notes about write concern options:
82- # Write concern options are propagated to objects instantiated from this MongoClient.
83- # These defaults can be overridden upon instantiation of any object by explicitly setting an options hash
84- # on initialization.
85- # @option opts [Boolean] :slave_ok (false) Must be set to +true+ when connecting
86- # to a single, slave node.
87- # @option opts [Logger, #debug] :logger (nil) A Logger instance for debugging driver ops. Note that
88- # logging negatively impacts performance; therefore, it should not be used for high-performance apps.
89- # @option opts [Integer] :pool_size (1) The maximum number of socket self.connections allowed per
90- # connection pool. Note: this setting is relevant only for multi-threaded applications.
91- # @option opts [Float] :timeout (5.0) When all of the self.connections a pool are checked out,
92- # this is the number of seconds to wait for a new connection to be released before throwing an exception.
93- # Note: this setting is relevant only for multi-threaded applications (which in Ruby are rare).
94- # @option opts [Float] :op_timeout (nil) The number of seconds to wait for a read operation to time out.
95- # Disabled by default.
96- # @option opts [Float] :connect_timeout (nil) The number of seconds to wait before timing out a
97- # connection attempt.
98- # @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
74+ # @overload initialize(host, port, opts={})
75+ # @param [String] host hostname for the target MongoDB server.
76+ # @param [Integer] port specify a port number here if only one host is being specified.
77+ # @param [Hash] opts hash of optional settings and configuration values.
78+ #
79+ # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
80+ # should be acknowledged
81+ # @option opts [Boolean] :j (false) Set journal acknowledgement
82+ # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
83+ # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
84+ #
85+ # Notes about Write-Concern Options:
86+ # Write concern options are propagated to objects instantiated from this MongoClient.
87+ # These defaults can be overridden upon instantiation of any object by explicitly setting an options hash
88+ # on initialization.
89+ #
90+ # @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
91+ # @option opts [String] :ssl_cert (nil) The certificate file used to identify the local connection against MongoDB.
92+ # @option opts [String] :ssl_key (nil) The private keyfile used to identify the local connection against MongoDB.
93+ # If included with the :ssl_cert then only :ssl_cert is needed.
94+ # @option opts [Boolean] :ssl_verify (nil) Specifies whether or not peer certification validation should occur.
95+ # @option opts [String] :ssl_ca_cert (nil) The ca_certs file contains a set of concatenated "certification authority"
96+ # certificates, which are used to validate certificates passed from the other end of the connection.
97+ # Required for :ssl_verify.
98+ # @option opts [Boolean] :slave_ok (false) Must be set to +true+ when connecting
99+ # to a single, slave node.
100+ # @option opts [Logger, #debug] :logger (nil) A Logger instance for debugging driver ops. Note that
101+ # logging negatively impacts performance; therefore, it should not be used for high-performance apps.
102+ # @option opts [Integer] :pool_size (1) The maximum number of socket self.connections allowed per
103+ # connection pool. Note: this setting is relevant only for multi-threaded applications.
104+ # @option opts [Float] :timeout (5.0) When all of the self.connections a pool are checked out,
105+ # this is the number of seconds to wait for a new connection to be released before throwing an exception.
106+ # Note: this setting is relevant only for multi-threaded applications.
107+ # @option opts [Float] :op_timeout (nil) The number of seconds to wait for a read operation to time out.
108+ # Disabled by default.
109+ # @option opts [Float] :connect_timeout (nil) The number of seconds to wait before timing out a
110+ # connection attempt.
99111 #
100112 # @example localhost, 27017 (or <code>ENV["MONGODB_URI"]</code> if available)
101113 # MongoClient.new
@@ -459,9 +471,7 @@ def mongos?
459471 # @raise [ConnectionFailure] if unable to connect to any host or port.
460472 def connect
461473 close
462-
463474 config = check_is_master ( host_port )
464-
465475 if config
466476 if config [ 'ismaster' ] == 1 || config [ 'ismaster' ] == true
467477 @read_primary = true
@@ -481,6 +491,7 @@ def connect
481491 if !connected?
482492 raise ConnectionFailure , "Failed to connect to a master node at #{ host_port . join ( ":" ) } "
483493 end
494+ true
484495 end
485496 alias :reconnect :connect
486497
@@ -574,7 +585,7 @@ def check_is_master(node)
574585 begin
575586 host , port = *node
576587 config = nil
577- socket = @socket_class . new ( host , port , @op_timeout , @connect_timeout )
588+ socket = @socket_class . new ( host , port , @op_timeout , @connect_timeout , @socket_opts )
578589 if @connect_timeout
579590 Timeout ::timeout ( @connect_timeout , OperationTimeout ) do
580591 config = self [ 'admin' ] . command ( { :ismaster => 1 } , :socket => socket )
@@ -598,7 +609,8 @@ def valid_opts
598609 POOL_OPTS +
599610 READ_PREFERENCE_OPTS +
600611 WRITE_CONCERN_OPTS +
601- TIMEOUT_OPTS
612+ TIMEOUT_OPTS +
613+ SSL_OPTS
602614 end
603615
604616 def check_opts ( opts )
@@ -612,11 +624,32 @@ def check_opts(opts)
612624 # Parse option hash
613625 def setup ( opts )
614626 @slave_ok = opts . delete ( :slave_ok )
627+ @ssl = opts . delete ( :ssl )
628+ @unix = @host ? @host . end_with? ( '.sock' ) : false
629+
630+ # if ssl options are present, but ssl is nil/false raise for misconfig
631+ ssl_opts = opts . keys . select { |k | k . to_s . start_with? ( 'ssl' ) }
632+ if ssl_opts . size > 0 && !@ssl
633+ raise MongoArgumentError , "SSL has not been enabled (:ssl=false) " +
634+ "but the following SSL related options were " +
635+ "specified: #{ ssl_opts . join ( ', ' ) } "
636+ end
615637
616- @ssl = opts . delete ( :ssl )
617- @unix = @host ? @host . end_with? ( '.sock' ) : false
618-
638+ @socket_opts = { }
619639 if @ssl
640+ # construct ssl socket opts
641+ @socket_opts [ :key ] = opts . delete ( :ssl_key )
642+ @socket_opts [ :cert ] = opts . delete ( :ssl_cert )
643+ @socket_opts [ :verify ] = opts . delete ( :ssl_verify )
644+ @socket_opts [ :ca_cert ] = opts . delete ( :ssl_ca_cert )
645+
646+ # verify peer requires ca_cert, raise if only one is present
647+ if @socket_opts [ :verify ] && !@socket_opts [ :ca_cert ]
648+ raise MongoArgumentError ,
649+ "If :ssl_verify_mode has been specified, then you must include " +
650+ ":ssl_ca_cert in order to perform server validation."
651+ end
652+
620653 @socket_class = Mongo ::SSLSocket
621654 elsif @unix
622655 @socket_class = Mongo ::UNIXSocket
@@ -631,7 +664,8 @@ def setup(opts)
631664 @pool_size = opts . delete ( :pool_size ) || 1
632665 if opts [ :timeout ]
633666 warn "The :timeout option has been deprecated " +
634- "and will be removed in the 2.0 release. Use :pool_timeout instead."
667+ "and will be removed in the 2.0 release. " +
668+ "Use :pool_timeout instead."
635669 end
636670 @pool_timeout = opts . delete ( :pool_timeout ) || opts . delete ( :timeout ) || 5.0
637671
0 commit comments