mongo 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo/address.rb +70 -11
  5. data/lib/mongo/address/ipv4.rb +23 -22
  6. data/lib/mongo/address/ipv6.rb +23 -22
  7. data/lib/mongo/address/unix.rb +18 -18
  8. data/lib/mongo/auth.rb +0 -1
  9. data/lib/mongo/auth/cr.rb +21 -2
  10. data/lib/mongo/auth/cr/conversation.rb +7 -4
  11. data/lib/mongo/auth/ldap.rb +14 -1
  12. data/lib/mongo/auth/scram.rb +15 -1
  13. data/lib/mongo/auth/scram/conversation.rb +3 -3
  14. data/lib/mongo/auth/user.rb +1 -1
  15. data/lib/mongo/auth/x509.rb +15 -1
  16. data/lib/mongo/cluster.rb +22 -8
  17. data/lib/mongo/cluster/topology.rb +7 -6
  18. data/lib/mongo/cluster/topology/replica_set.rb +5 -5
  19. data/lib/mongo/cluster/topology/sharded.rb +5 -5
  20. data/lib/mongo/cluster/topology/{standalone.rb → single.rb} +26 -22
  21. data/lib/mongo/cluster/topology/unknown.rb +6 -5
  22. data/lib/mongo/collection.rb +6 -1
  23. data/lib/mongo/collection/view.rb +1 -0
  24. data/lib/mongo/collection/view/readable.rb +5 -0
  25. data/lib/mongo/error.rb +4 -0
  26. data/lib/mongo/error/invalid_document.rb +1 -1
  27. data/lib/mongo/error/invalid_server_preference.rb +36 -0
  28. data/lib/mongo/error/invalid_uri.rb +37 -0
  29. data/lib/mongo/error/invalid_uri_option.rb +38 -0
  30. data/lib/mongo/error/no_server_available.rb +37 -0
  31. data/lib/mongo/operation/read_preferrable.rb +20 -4
  32. data/lib/mongo/protocol/query.rb +14 -1
  33. data/lib/mongo/server.rb +12 -0
  34. data/lib/mongo/server/connectable.rb +5 -1
  35. data/lib/mongo/server/connection.rb +1 -1
  36. data/lib/mongo/server/context.rb +2 -1
  37. data/lib/mongo/server_selector.rb +0 -19
  38. data/lib/mongo/server_selector/selectable.rb +4 -22
  39. data/lib/mongo/uri.rb +9 -55
  40. data/lib/mongo/version.rb +1 -1
  41. data/spec/mongo/address/ipv4_spec.rb +27 -6
  42. data/spec/mongo/address/ipv6_spec.rb +27 -6
  43. data/spec/mongo/address/unix_spec.rb +15 -4
  44. data/spec/mongo/auth/cr_spec.rb +2 -2
  45. data/spec/mongo/auth/ldap_spec.rb +2 -2
  46. data/spec/mongo/auth/scram_spec.rb +2 -2
  47. data/spec/mongo/auth/x509_spec.rb +2 -2
  48. data/spec/mongo/client_spec.rb +8 -0
  49. data/spec/mongo/cluster/topology/replica_set_spec.rb +6 -6
  50. data/spec/mongo/cluster/topology/sharded_spec.rb +5 -5
  51. data/spec/mongo/cluster/topology/{standalone_spec.rb → single_spec.rb} +7 -7
  52. data/spec/mongo/cluster/topology_spec.rb +31 -5
  53. data/spec/mongo/cluster_spec.rb +103 -21
  54. data/spec/mongo/collection/view/readable_spec.rb +18 -7
  55. data/spec/mongo/collection/view_spec.rb +13 -0
  56. data/spec/mongo/collection_spec.rb +7 -0
  57. data/spec/mongo/database_spec.rb +2 -2
  58. data/spec/mongo/protocol/query_spec.rb +29 -0
  59. data/spec/mongo/server/connection_pool_spec.rb +4 -4
  60. data/spec/mongo/server/connection_spec.rb +46 -10
  61. data/spec/mongo/server/monitor_spec.rb +2 -2
  62. data/spec/mongo/server_discovery_and_monitoring_spec.rb +23 -0
  63. data/spec/mongo/server_selection_rtt_spec.rb +2 -1
  64. data/spec/mongo/server_selection_spec.rb +6 -15
  65. data/spec/mongo/server_selector/nearest_spec.rb +1 -1
  66. data/spec/mongo/server_selector_spec.rb +53 -2
  67. data/spec/mongo/server_spec.rb +9 -9
  68. data/spec/mongo/socket/ssl_spec.rb +1 -1
  69. data/spec/mongo/uri_spec.rb +2 -2
  70. data/spec/spec_helper.rb +34 -5
  71. data/spec/support/authorization.rb +32 -46
  72. data/spec/support/server_discovery_and_monitoring.rb +1 -1
  73. data/spec/support/server_selection.rb +1 -25
  74. data/spec/support/shared/operation.rb +3 -0
  75. data/spec/support/shared/server_selector.rb +1 -1
  76. metadata +10 -7
  77. metadata.gz.sig +0 -0
  78. data/lib/mongo/auth/executable.rb +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: efe6bb7e6b47adaa8d2552af028e6c77510659ec
4
- data.tar.gz: fcf01b4299f65ab1b0604f7c6ad5be3f470774cf
3
+ metadata.gz: 7b0437cd0c5d8bb2f5500c239a8814d634c80499
4
+ data.tar.gz: bed04278506ef47a820421a872f5850ab8f01a7d
5
5
  SHA512:
6
- metadata.gz: 84f370d047ea3d27dd06940145be29bc2d6655b1b9676be732010a1d13d17f1fb5f86be35ba47e6a7b2c122dd2fadf02f0d4e37334f0f2446fa66da09d91e68e
7
- data.tar.gz: 84902c053cf3394d8b821e4b6e4ada9906010f4221015e86a14ae1897d9c1be7c772c0848a19aabcc7446b1032e6e23f54475f96418dda607bead0143dc1e9fd
6
+ metadata.gz: 9d790a1e9b2f1e97c2b354e22daf0ec5d6552c438f5d59c3d84e98ab57c42fec8f4cc4d81699569efde84840d3b41e5f9417c0aa536f0d51af1f39ce3c8368fa
7
+ data.tar.gz: d9417be0c394836c30d60a0bf4a1199003b56866a39f3630aea96e9647a3ef27040c9d1df9a7acc6c068718da4bee16bdb982c6feb3fae13ef7218280059e9e3
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/lib/mongo/address.rb CHANGED
@@ -25,13 +25,22 @@ module Mongo
25
25
  class Address
26
26
  extend Forwardable
27
27
 
28
- # Delegate the ip, host, and port methods to the resolver.
28
+ # Mapping from socket family to resolver class.
29
29
  #
30
30
  # @since 2.0.0
31
- def_delegators :@resolver, :host, :port, :socket, :seed, :to_s
31
+ FAMILY_MAP = { ::Socket::PF_UNIX => Unix,
32
+ ::Socket::AF_INET6 => IPv6,
33
+ ::Socket::AF_INET => IPv4
34
+ }
32
35
 
33
- # @return [ Integer ] port The port to the connect to.
34
- attr_reader :resolver
36
+ # @return [ String ] seed The seed address.
37
+ attr_reader :seed
38
+
39
+ # @return [ String ] host The original host name.
40
+ attr_reader :host
41
+
42
+ # @return [ Integer ] port The port.
43
+ attr_reader :port
35
44
 
36
45
  # Check equality of the address to another.
37
46
  #
@@ -88,12 +97,8 @@ module Mongo
88
97
  #
89
98
  # @since 2.0.0
90
99
  def initialize(seed, options = {})
91
- address = seed.downcase
92
- case address
93
- when Unix::MATCH then @resolver = Unix.new(address)
94
- when IPv6::MATCH then @resolver = IPv6.new(address)
95
- else @resolver = IPv4.new(address)
96
- end
100
+ @seed = seed
101
+ @host, @port = parse_host_port
97
102
  end
98
103
 
99
104
  # Get a pretty printed address inspection.
@@ -105,7 +110,61 @@ module Mongo
105
110
  #
106
111
  # @since 2.0.0
107
112
  def inspect
108
- "#<Mongo::Address:0x#{object_id} address=#{resolver.to_s}>"
113
+ "#<Mongo::Address:0x#{object_id} address=#{to_s}>"
114
+ end
115
+
116
+ # Get a socket for the provided address, given the options.
117
+ #
118
+ # @example Get a socket.
119
+ # address.socket(5, :ssl => true)
120
+ #
121
+ # @param [ Float ] timeout The socket timeout.
122
+ # @param [ Hash ] ssl_options SSL options.
123
+ #
124
+ # @return [ Pool::Socket::SSL, Pool::Socket::TCP, Pool::Socket::Unix ] The socket.
125
+ #
126
+ # @since 2.0.0
127
+ def socket(timeout, ssl_options = {})
128
+ @resolver ||= initialize_resolver!(timeout, ssl_options)
129
+ @resolver.socket(timeout, ssl_options)
130
+ end
131
+
132
+ # Get the address as a string.
133
+ #
134
+ # @example Get the address as a string.
135
+ # address.to_s
136
+ #
137
+ # @return [ String ] The nice string.
138
+ #
139
+ # @since 2.0.0
140
+ def to_s
141
+ port ? "#{host}:#{port}" : host
142
+ end
143
+
144
+ private
145
+
146
+ def initialize_resolver!(timeout, ssl_options)
147
+ family = (host == 'localhost') ? ::Socket::AF_INET : ::Socket::AF_UNSPEC
148
+ error = nil
149
+ ::Socket.getaddrinfo(host, nil, family, ::Socket::SOCK_STREAM).detect do |info|
150
+ begin
151
+ return FAMILY_MAP[info[4]].new(host, port).tap do |res|
152
+ res.socket(timeout, ssl_options).connect!
153
+ end
154
+ rescue IOError, SystemCallError => e
155
+ error = e
156
+ end
157
+ end
158
+ raise error
159
+ end
160
+
161
+ def parse_host_port
162
+ address = seed.downcase
163
+ case address
164
+ when Unix::MATCH then Unix.parse(address)
165
+ when IPv6::MATCH then IPv6.parse(address)
166
+ else IPv4.parse(address)
167
+ end
109
168
  end
110
169
  end
111
170
  end
@@ -27,27 +27,40 @@ module Mongo
27
27
  # @return [ Integer ] port The port.
28
28
  attr_reader :port
29
29
 
30
- # @return [ String ] seed The seed address.
31
- attr_reader :seed
32
-
33
30
  # The regular expression to use to match an IPv4 ip address.
34
31
  #
35
32
  # @since 2.0.0
36
33
  MATCH = Regexp.new('/\./').freeze
37
34
 
35
+ # Parse an IPv4 address into its host and port.
36
+ #
37
+ # @example Parse the address.
38
+ # IPv4.parse("127.0.0.1:28011")
39
+ #
40
+ # @param [ String ] address The address to parse.
41
+ #
42
+ # @return [ Array<String, Integer> ] The host and port pair.
43
+ #
44
+ # @since 2.0.0
45
+ def self.parse(address)
46
+ parts = address.split(':')
47
+ host = parts[0]
48
+ port = (parts[1] || 27017).to_i
49
+ [ host, port ]
50
+ end
51
+
38
52
  # Initialize the IPv4 resolver.
39
53
  #
40
54
  # @example Initialize the resolver.
41
- # IPv4.new("127.0.0.1:28011")
55
+ # IPv4.new("127.0.0.1", 27017, "127.0.0.1:28011")
42
56
  #
43
- # @param [ String ] address The address to resolve.
57
+ # @param [ String ] host The host.
58
+ # @param [ Integer ] port The port.
44
59
  #
45
60
  # @since 2.0.0
46
- def initialize(address)
47
- parts = address.split(':')
48
- @host = parts[0]
49
- @port = (parts[1] || 27017).to_i
50
- @seed = address
61
+ def initialize(host, port)
62
+ @host = host
63
+ @port = port
51
64
  end
52
65
 
53
66
  # Get a socket for the provided address type, given the options.
@@ -68,18 +81,6 @@ module Mongo
68
81
  Socket::TCP.new(host, port, timeout, Socket::PF_INET)
69
82
  end
70
83
  end
71
-
72
- # Get the address as a string.
73
- #
74
- # @example Get the address as a string.
75
- # ipv4.to_s
76
- #
77
- # @return [ String ] The nice string.
78
- #
79
- # @since 2.0.0
80
- def to_s
81
- "#{host}:#{port}"
82
- end
83
84
  end
84
85
  end
85
86
  end
@@ -27,27 +27,40 @@ module Mongo
27
27
  # @return [ Integer ] port The port.
28
28
  attr_reader :port
29
29
 
30
- # @return [ String ] seed The seed address.
31
- attr_reader :seed
32
-
33
30
  # The regular expression to use to match an IPv6 ip address.
34
31
  #
35
32
  # @since 2.0.0
36
33
  MATCH = Regexp.new('::').freeze
37
34
 
35
+ # Parse an IPv6 address into its host and port.
36
+ #
37
+ # @example Parse the address.
38
+ # IPv4.parse("[::1]:28011")
39
+ #
40
+ # @param [ String ] address The address to parse.
41
+ #
42
+ # @return [ Array<String, Integer> ] The host and port pair.
43
+ #
44
+ # @since 2.0.0
45
+ def self.parse(address)
46
+ parts = address.match(/\[(.+)\]:?(.+)?/)
47
+ host = parts[1]
48
+ port = (parts[2] || 27017).to_i
49
+ [ host, port ]
50
+ end
51
+
38
52
  # Initialize the IPv6 resolver.
39
53
  #
40
54
  # @example Initialize the resolver.
41
- # IPv6.new("[::1]:28011")
55
+ # IPv6.new("::1", 28011, "[::1]:28011")
42
56
  #
43
- # @param [ String ] address The address to resolve.
57
+ # @param [ String ] host The host.
58
+ # @param [ Integer ] port The port.
44
59
  #
45
60
  # @since 2.0.0
46
- def initialize(address)
47
- parts = address.match(/\[(.+)\]:?(.+)?/)
48
- @host = parts[1]
49
- @port = (parts[2] || 27017).to_i
50
- @seed = address
61
+ def initialize(host, port)
62
+ @host = host
63
+ @port = port
51
64
  end
52
65
 
53
66
  # Get a socket for the provided address type, given the options.
@@ -68,18 +81,6 @@ module Mongo
68
81
  Socket::TCP.new(host, port, timeout, Socket::PF_INET6)
69
82
  end
70
83
  end
71
-
72
- # Get the address as a string.
73
- #
74
- # @example Get the address as a string.
75
- # ipv4.to_s
76
- #
77
- # @return [ String ] The nice string.
78
- #
79
- # @since 2.0.0
80
- def to_s
81
- "#{host}:#{port}"
82
- end
83
84
  end
84
85
  end
85
86
  end
@@ -26,25 +26,35 @@ module Mongo
26
26
  # @return [ nil ] port Will always be nil.
27
27
  attr_reader :port
28
28
 
29
- # @return [ String ] seed The seed address.
30
- attr_reader :seed
31
-
32
29
  # The regular expression to use to match a socket path.
33
30
  #
34
31
  # @since 2.0.0
35
32
  MATCH = Regexp.new('\.sock').freeze
36
33
 
34
+ # Parse a socket path.
35
+ #
36
+ # @example Parse the address.
37
+ # Unix.parse("/path/to/socket.sock")
38
+ #
39
+ # @param [ String ] address The address to parse.
40
+ #
41
+ # @return [ Array<String> ] A list with the host (socket path).
42
+ #
43
+ # @since 2.0.0
44
+ def self.parse(address)
45
+ [ address ]
46
+ end
47
+
37
48
  # Initialize the socket resolver.
38
49
  #
39
50
  # @example Initialize the resolver.
40
- # Sock.new("/path/to/socket.sock")
51
+ # Unix.new("/path/to/socket.sock", "/path/to/socket.sock")
41
52
  #
42
- # @param [ String ] address The socket path.
53
+ # @param [ String ] host The host.
43
54
  #
44
55
  # @since 2.0.0
45
- def initialize(address)
46
- @host = address
47
- @seed = address
56
+ def initialize(host)
57
+ @host = host
48
58
  end
49
59
 
50
60
  # Get a socket for the provided address type, given the options.
@@ -61,16 +71,6 @@ module Mongo
61
71
  def socket(timeout, ssl_options = {})
62
72
  Socket::Unix.new(host, timeout, Socket::AF_UNIX)
63
73
  end
64
-
65
- # Get the address as a string.
66
- #
67
- # @example Get the address as a string.
68
- # ipv4.to_s
69
- #
70
- # @return [ String ] The nice string.
71
- #
72
- # @since 2.0.0
73
- alias :to_s :host
74
74
  end
75
75
  end
76
76
  end
data/lib/mongo/auth.rb CHANGED
@@ -12,7 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'mongo/auth/executable'
16
15
  require 'mongo/auth/cr'
17
16
  require 'mongo/auth/ldap'
18
17
  require 'mongo/auth/scram'
data/lib/mongo/auth/cr.rb CHANGED
@@ -21,7 +21,26 @@ module Mongo
21
21
  #
22
22
  # @since 2.0.0
23
23
  class CR
24
- include Executable
24
+
25
+ # The authentication mechinism string.
26
+ #
27
+ # @since 2.0.0
28
+ MECHANISM = 'MONGODB-CR'.freeze
29
+
30
+ # @return [ Mongo::Auth::User ] The user to authenticate.
31
+ attr_reader :user
32
+
33
+ # Instantiate a new authenticator.
34
+ #
35
+ # @example Create the authenticator.
36
+ # Mongo::Auth::CR.new(user)
37
+ #
38
+ # @param [ Mongo::Auth::User ] user The user to authenticate.
39
+ #
40
+ # @since 2.0.0
41
+ def initialize(user)
42
+ @user = user
43
+ end
25
44
 
26
45
  # Log the user in on the given connection.
27
46
  #
@@ -34,7 +53,7 @@ module Mongo
34
53
  #
35
54
  # @since 2.0.0
36
55
  def login(connection)
37
- conversation = Conversation.new(user, auth_database(connection))
56
+ conversation = Conversation.new(user)
38
57
  reply = connection.dispatch([ conversation.start ])
39
58
  reply = connection.dispatch([ conversation.continue(reply) ])
40
59
  conversation.finalize(reply)
@@ -56,7 +56,7 @@ module Mongo
56
56
  def continue(reply)
57
57
  validate!(reply)
58
58
  Protocol::Query.new(
59
- database,
59
+ user.auth_source,
60
60
  Database::COMMAND,
61
61
  LOGIN.merge(user: user.name, nonce: nonce, key: user.auth_key(nonce)),
62
62
  limit: -1
@@ -89,7 +89,11 @@ module Mongo
89
89
  #
90
90
  # @since 2.0.0
91
91
  def start
92
- Protocol::Query.new(database, Database::COMMAND, Auth::GET_NONCE, limit: -1)
92
+ Protocol::Query.new(
93
+ user.auth_source,
94
+ Database::COMMAND,
95
+ Auth::GET_NONCE,
96
+ limit: -1)
93
97
  end
94
98
 
95
99
  # Create the new conversation.
@@ -101,9 +105,8 @@ module Mongo
101
105
  # @param [ String ] database The database to authenticate against.
102
106
  #
103
107
  # @since 2.0.0
104
- def initialize(user, database)
108
+ def initialize(user)
105
109
  @user = user
106
- @database = database
107
110
  end
108
111
 
109
112
  private
@@ -21,13 +21,26 @@ module Mongo
21
21
  #
22
22
  # @since 2.0.0
23
23
  class LDAP
24
- include Executable
25
24
 
26
25
  # The authentication mechinism string.
27
26
  #
28
27
  # @since 2.0.0
29
28
  MECHANISM = 'PLAIN'.freeze
30
29
 
30
+ # @return [ Mongo::Auth::User ] The user to authenticate.
31
+ attr_reader :user
32
+
33
+ # Instantiate a new authenticator.
34
+ #
35
+ # @example Create the authenticator.
36
+ # Mongo::Auth::LDAP.new(user)
37
+ #
38
+ # @param [ Mongo::Auth::User ] user The user to authenticate.
39
+ #
40
+ # @since 2.0.0
41
+ def initialize(user)
42
+ @user = user
43
+ end
31
44
  # Log the user in on the given connection.
32
45
  #
33
46
  # @example Log the user in.
@@ -21,13 +21,27 @@ module Mongo
21
21
  #
22
22
  # @since 2.0.0
23
23
  class SCRAM
24
- include Executable
25
24
 
26
25
  # The authentication mechinism string.
27
26
  #
28
27
  # @since 2.0.0
29
28
  MECHANISM = 'SCRAM-SHA-1'.freeze
30
29
 
30
+ # @return [ Mongo::Auth::User ] The user to authenticate.
31
+ attr_reader :user
32
+
33
+ # Instantiate a new authenticator.
34
+ #
35
+ # @example Create the authenticator.
36
+ # Mongo::Auth::SCRAM.new(user)
37
+ #
38
+ # @param [ Mongo::Auth::User ] user The user to authenticate.
39
+ #
40
+ # @since 2.0.0
41
+ def initialize(user)
42
+ @user = user
43
+ end
44
+
31
45
  # Log the user in on the given connection.
32
46
  #
33
47
  # @example Log the user in.