mongo 2.13.0.rc1 → 2.13.0
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/auth/aws/request.rb +27 -3
- data/lib/mongo/client.rb +35 -0
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/error/invalid_server_auth_host.rb +22 -0
- data/lib/mongo/index/view.rb +3 -0
- data/lib/mongo/protocol/msg.rb +19 -0
- data/lib/mongo/server/app_metadata.rb +27 -3
- data/lib/mongo/server/connection_base.rb +34 -8
- data/lib/mongo/version.rb +1 -1
- data/spec/integration/bulk_write_spec.rb +19 -0
- data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +3 -3
- data/spec/integration/size_limit_spec.rb +23 -10
- data/spec/mongo/auth/aws/request_region_spec.rb +42 -0
- data/spec/mongo/auth/aws/request_spec.rb +32 -32
- data/spec/mongo/client_construction_spec.rb +112 -0
- data/spec/mongo/index/view_spec.rb +146 -0
- data/spec/mongo/server/app_metadata_shared.rb +80 -0
- metadata +985 -984
- metadata.gz.sig +0 -0
- data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +0 -98
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df3eb3a5733323f2f4440c67bc0173661ada194ecb35374e8e78345e2d072525
|
4
|
+
data.tar.gz: 63227bff6f14e3100f86a747b3e5d577812dd74d6da8061a069d8a313ecce09c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '02253019a9aab19c94dbb2a4e459a84c1fa6f1383eca9d5b1daa26bf1c2aa1a96c32f52a23267b0b7b5c58fc469144d0c1722b4f79593ae7563ac0c9deb55d95'
|
7
|
+
data.tar.gz: e02d93a95630d770f20a37cbe91a4dc18c98cb18e684da4b2a538a70afaaf61731e808832b2fe9aadca484dacfc8dce43cedf356ef00db019a03d77e9283cc45
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
@@ -61,9 +61,13 @@ module Mongo
|
|
61
61
|
%i(access_key_id secret_access_key host server_nonce).each do |arg|
|
62
62
|
value = instance_variable_get("@#{arg}")
|
63
63
|
if value.nil? || value.empty?
|
64
|
-
raise
|
64
|
+
raise Error::InvalidServerAuthResponse, "Value for '#{arg}' is required"
|
65
65
|
end
|
66
66
|
end
|
67
|
+
|
68
|
+
if host && host.length > 255
|
69
|
+
raise Error::InvalidServerAuthHost, "Value for 'host' is too long: #{@host}"
|
70
|
+
end
|
67
71
|
end
|
68
72
|
|
69
73
|
# @return [ String ] access_key_id The access key id.
|
@@ -98,8 +102,28 @@ module Mongo
|
|
98
102
|
|
99
103
|
# @return [ String ] region The region of the host, derived from the host.
|
100
104
|
def region
|
101
|
-
#
|
102
|
-
'
|
105
|
+
# Common case
|
106
|
+
if host == 'sts.amazonaws.com'
|
107
|
+
return 'us-east-1'
|
108
|
+
end
|
109
|
+
|
110
|
+
if host.start_with?('.')
|
111
|
+
raise Error::InvalidServerAuthHost, "Host begins with a period: #{host}"
|
112
|
+
end
|
113
|
+
if host.end_with?('.')
|
114
|
+
raise Error::InvalidServerAuthHost, "Host ends with a period: #{host}"
|
115
|
+
end
|
116
|
+
|
117
|
+
parts = host.split('.')
|
118
|
+
if parts.any? { |part| part.empty? }
|
119
|
+
raise Error::InvalidServerAuthHost, "Host has an empty component: #{host}"
|
120
|
+
end
|
121
|
+
|
122
|
+
if parts.length == 1
|
123
|
+
'us-east-1'
|
124
|
+
else
|
125
|
+
parts[1]
|
126
|
+
end
|
103
127
|
end
|
104
128
|
|
105
129
|
# Returns the scope of the request, per the AWS signature V4 specification.
|
data/lib/mongo/client.rb
CHANGED
@@ -104,6 +104,7 @@ module Mongo
|
|
104
104
|
:truncate_logs,
|
105
105
|
:user,
|
106
106
|
:wait_queue_timeout,
|
107
|
+
:wrapping_libraries,
|
107
108
|
:write,
|
108
109
|
:write_concern,
|
109
110
|
:zlib_compression_level,
|
@@ -375,6 +376,10 @@ module Mongo
|
|
375
376
|
# @option options [ String ] :user The user name.
|
376
377
|
# @option options [ Float ] :wait_queue_timeout The time to wait, in
|
377
378
|
# seconds, in the connection pool for a connection to be checked in.
|
379
|
+
# @option options [ Array<Hash> ] :wrapping_libraries Information about
|
380
|
+
# libraries such as ODMs that are wrapping the driver, to be added to
|
381
|
+
# metadata sent to the server. Specify the lower level libraries first.
|
382
|
+
# Allowed hash keys: :name, :version, :platform.
|
378
383
|
# @option options [ Hash ] :write Deprecated. Equivalent to :write_concern
|
379
384
|
# option.
|
380
385
|
# @option options [ Hash ] :write_concern The write concern options.
|
@@ -1160,6 +1165,36 @@ module Mongo
|
|
1160
1165
|
raise ArgumentError, ":bg_error_backtrace option value must be true, false, nil or a positive integer: #{value}"
|
1161
1166
|
end
|
1162
1167
|
end
|
1168
|
+
|
1169
|
+
if libraries = options[:wrapping_libraries]
|
1170
|
+
unless Array === libraries
|
1171
|
+
raise ArgumentError, ":wrapping_libraries must be an array of hashes: #{libraries}"
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
libraries = libraries.map do |library|
|
1175
|
+
Utils.shallow_symbolize_keys(library)
|
1176
|
+
end
|
1177
|
+
|
1178
|
+
libraries.each do |library|
|
1179
|
+
unless Hash === library
|
1180
|
+
raise ArgumentError, ":wrapping_libraries element is not a hash: #{library}"
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
if library.empty?
|
1184
|
+
raise ArgumentError, ":wrapping_libraries element is empty"
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
unless (library.keys - %i(name platform version)).empty?
|
1188
|
+
raise ArgumentError, ":wrapping_libraries element has invalid keys (allowed keys: :name, :platform, :version): #{library}"
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
library.each do |key, value|
|
1192
|
+
if value.include?('|')
|
1193
|
+
raise ArgumentError, ":wrapping_libraries element value cannot include '|': #{value}"
|
1194
|
+
end
|
1195
|
+
end
|
1196
|
+
end
|
1197
|
+
end
|
1163
1198
|
end
|
1164
1199
|
|
1165
1200
|
# Validates all authentication-related options after they are set on the client
|
data/lib/mongo/error.rb
CHANGED
@@ -190,6 +190,8 @@ require 'mongo/error/invalid_application_name'
|
|
190
190
|
require 'mongo/error/invalid_nonce'
|
191
191
|
require 'mongo/error/invalid_replacement_document'
|
192
192
|
require 'mongo/error/invalid_server_auth_response'
|
193
|
+
# Subclass of InvalidServerAuthResponse
|
194
|
+
require 'mongo/error/invalid_server_auth_host'
|
193
195
|
require 'mongo/error/invalid_server_preference'
|
194
196
|
require 'mongo/error/invalid_session'
|
195
197
|
require 'mongo/error/invalid_signature'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Copyright (C) 2020 MongoDB Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Mongo
|
16
|
+
class Error
|
17
|
+
|
18
|
+
# Raised when the server returned an invalid Host value in AWS auth.
|
19
|
+
class InvalidServerAuthHost < InvalidServerAuthResponse
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/mongo/index/view.rb
CHANGED
@@ -120,6 +120,9 @@ module Mongo
|
|
120
120
|
# a geo index.
|
121
121
|
# @option options [ Hash ] :partial_filter_expression Specify a filter for a partial
|
122
122
|
# index.
|
123
|
+
# @option options [ Boolean ] :hidden When :hidden is true, this index will
|
124
|
+
# exist on the collection but not be used by the query planner when
|
125
|
+
# executing operations.
|
123
126
|
# @option options [ String | Integer ] :commit_quorum Specify how many
|
124
127
|
# data-bearing members of a replica set, including the primary, must
|
125
128
|
# complete the index builds successfully before the primary marks
|
data/lib/mongo/protocol/msg.rb
CHANGED
@@ -147,6 +147,8 @@ module Mongo
|
|
147
147
|
#
|
148
148
|
# @since 2.5.0
|
149
149
|
def serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil)
|
150
|
+
validate_document_size!(max_bson_size)
|
151
|
+
|
150
152
|
super
|
151
153
|
add_check_sum(buffer)
|
152
154
|
buffer
|
@@ -275,6 +277,23 @@ module Mongo
|
|
275
277
|
|
276
278
|
private
|
277
279
|
|
280
|
+
# Validate that the documents in this message are all smaller than the
|
281
|
+
# maxBsonObjectSize. If not, raise an exception.
|
282
|
+
def validate_document_size!(max_bson_size)
|
283
|
+
max_bson_size ||= Mongo::Server::ConnectionBase::DEFAULT_MAX_BSON_OBJECT_SIZE
|
284
|
+
|
285
|
+
contains_too_large_document = @sections.any? do |section|
|
286
|
+
section[:type] == 1 &&
|
287
|
+
section[:payload][:sequence].any? do |document|
|
288
|
+
document.to_bson.length > max_bson_size
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
if contains_too_large_document
|
293
|
+
raise Error::MaxBSONSize.new('The document exceeds maximum allowed BSON object size after serialization')
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
278
297
|
def command
|
279
298
|
@command ||= if @main_document
|
280
299
|
@main_document.dup.tap do |cmd|
|
@@ -65,12 +65,17 @@ module Mongo
|
|
65
65
|
# the metadata printed to the mongod logs upon establishing a connection
|
66
66
|
# in server versions >= 3.4.
|
67
67
|
# @option options [ String ] :user The user name.
|
68
|
+
# @option options [ Array<Hash> ] :wrapping_libraries Information about
|
69
|
+
# libraries such as ODMs that are wrapping the driver. Specify the
|
70
|
+
# lower level libraries first. Allowed hash keys: :name, :version,
|
71
|
+
# :platform.
|
68
72
|
#
|
69
73
|
# @since 2.4.0
|
70
74
|
def initialize(options)
|
71
75
|
@app_name = options[:app_name].to_s if options[:app_name]
|
72
76
|
@platform = options[:platform]
|
73
77
|
@compressors = options[:compressors] || []
|
78
|
+
@wrapping_libraries = options[:wrapping_libraries]
|
74
79
|
|
75
80
|
if options[:user] && !options[:auth_mech]
|
76
81
|
auth_db = options[:auth_source] || 'admin'
|
@@ -78,6 +83,10 @@ module Mongo
|
|
78
83
|
end
|
79
84
|
end
|
80
85
|
|
86
|
+
# @return [ Array<Hash> | nil ] Information about libraries wrapping
|
87
|
+
# the driver.
|
88
|
+
attr_reader :wrapping_libraries
|
89
|
+
|
81
90
|
# Get the bytes of the ismaster message including this metadata.
|
82
91
|
#
|
83
92
|
# @api private
|
@@ -140,9 +149,17 @@ module Mongo
|
|
140
149
|
end
|
141
150
|
|
142
151
|
def driver_doc
|
152
|
+
names = [DRIVER_NAME]
|
153
|
+
versions = [Mongo::VERSION]
|
154
|
+
if wrapping_libraries
|
155
|
+
wrapping_libraries.each do |library|
|
156
|
+
names << library[:name] || ''
|
157
|
+
versions << library[:version] || ''
|
158
|
+
end
|
159
|
+
end
|
143
160
|
{
|
144
|
-
name:
|
145
|
-
version:
|
161
|
+
name: names.join('|'),
|
162
|
+
version: versions.join('|'),
|
146
163
|
}
|
147
164
|
end
|
148
165
|
|
@@ -175,12 +192,19 @@ module Mongo
|
|
175
192
|
ruby_versions = ["Ruby #{RUBY_VERSION}"]
|
176
193
|
platforms = [RUBY_PLATFORM]
|
177
194
|
end
|
178
|
-
[
|
195
|
+
platform = [
|
179
196
|
@platform,
|
180
197
|
*ruby_versions,
|
181
198
|
*platforms,
|
182
199
|
RbConfig::CONFIG['build'],
|
183
200
|
].compact.join(', ')
|
201
|
+
platforms = [platform]
|
202
|
+
if wrapping_libraries
|
203
|
+
wrapping_libraries.each do |library|
|
204
|
+
platforms << library[:platform] || ''
|
205
|
+
end
|
206
|
+
end
|
207
|
+
platforms.join('|')
|
184
208
|
end
|
185
209
|
end
|
186
210
|
end
|
@@ -186,9 +186,6 @@ module Mongo
|
|
186
186
|
end
|
187
187
|
|
188
188
|
def serialize(message, client, buffer = BSON::ByteBuffer.new)
|
189
|
-
start_size = 0
|
190
|
-
final_message = message.maybe_compress(compressor, options[:zlib_compression_level])
|
191
|
-
|
192
189
|
# Driver specifications only mandate the fixed 16MiB limit for
|
193
190
|
# serialized BSON documents. However, the server returns its
|
194
191
|
# active serialized BSON document size limit in the ismaster response,
|
@@ -213,12 +210,41 @@ module Mongo
|
|
213
210
|
max_bson_size += MAX_BSON_COMMAND_OVERHEAD
|
214
211
|
end
|
215
212
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
213
|
+
# RUBY-2234: It is necessary to check that the message size does not
|
214
|
+
# exceed the maximum bson object size before compressing and serializing
|
215
|
+
# the final message.
|
216
|
+
#
|
217
|
+
# This is to avoid the case where the user performs a bulk write
|
218
|
+
# larger than 16MiB which, when compressed, becomes smaller than 16MiB.
|
219
|
+
# If the driver does not split the bulk writes prior to compression,
|
220
|
+
# the entire operation will be sent to the server, which will raise an
|
221
|
+
# error because the uncompressed operation exceeds the maximum bson size.
|
222
|
+
#
|
223
|
+
# To address this problem, we serialize the message prior to compression
|
224
|
+
# and raise an exception if the serialized message exceeds the maximum
|
225
|
+
# bson size.
|
226
|
+
if max_message_size
|
227
|
+
# Create a separate buffer that contains the un-compressed message
|
228
|
+
# for the purpose of checking its size. Write any pre-existing contents
|
229
|
+
# from the original buffer into the temporary one.
|
230
|
+
temp_buffer = BSON::ByteBuffer.new
|
231
|
+
|
232
|
+
# TODO: address the fact that this line mutates the buffer.
|
233
|
+
temp_buffer.put_bytes(buffer.get_bytes(buffer.length))
|
234
|
+
|
235
|
+
message.serialize(temp_buffer, max_bson_size)
|
236
|
+
if temp_buffer.length > max_message_size
|
237
|
+
raise Error::MaxMessageSize.new(max_message_size)
|
238
|
+
end
|
221
239
|
end
|
240
|
+
|
241
|
+
# RUBY-2335: When the un-compressed message is smaller than the maximum
|
242
|
+
# bson size limit, the message will be serialized twice. The operations
|
243
|
+
# layer should be refactored to allow compression on an already-
|
244
|
+
# serialized message.
|
245
|
+
final_message = message.maybe_compress(compressor, options[:zlib_compression_level])
|
246
|
+
final_message.serialize(buffer, max_bson_size)
|
247
|
+
|
222
248
|
buffer
|
223
249
|
end
|
224
250
|
end
|
data/lib/mongo/version.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Bulk writes' do
|
4
|
+
before do
|
5
|
+
authorized_collection.drop
|
6
|
+
end
|
7
|
+
|
8
|
+
context 'when bulk write is larger than 48MB' do
|
9
|
+
let(:operations) do
|
10
|
+
[ { insert_one: { text: 'a' * 1000 * 1000 } } ] * 48
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'succeeds' do
|
14
|
+
expect do
|
15
|
+
authorized_collection.bulk_write(operations)
|
16
|
+
end.not_to raise_error
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -113,7 +113,7 @@ describe 'Bulk writes with auto-encryption enabled' do
|
|
113
113
|
it 'raises an exception' do
|
114
114
|
expect do
|
115
115
|
bulk_write.execute
|
116
|
-
end.to raise_error(Mongo::Error::MaxBSONSize, /maximum allowed size
|
116
|
+
end.to raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
117
117
|
end
|
118
118
|
end
|
119
119
|
end
|
@@ -255,7 +255,7 @@ describe 'Bulk writes with auto-encryption enabled' do
|
|
255
255
|
it 'raises an exception' do
|
256
256
|
expect do
|
257
257
|
bulk_write.execute
|
258
|
-
end.to raise_error(Mongo::Error::MaxBSONSize, /maximum allowed size
|
258
|
+
end.to raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
259
259
|
end
|
260
260
|
end
|
261
261
|
end
|
@@ -346,7 +346,7 @@ describe 'Bulk writes with auto-encryption enabled' do
|
|
346
346
|
it 'raises an exception' do
|
347
347
|
expect do
|
348
348
|
perform_bulk_write
|
349
|
-
end.to raise_error(Mongo::Error::MaxBSONSize, /maximum allowed size
|
349
|
+
end.to raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
350
350
|
end
|
351
351
|
end
|
352
352
|
end
|
@@ -62,13 +62,30 @@ describe 'BSON & command size limits' do
|
|
62
62
|
authorized_collection.insert_one(document)
|
63
63
|
end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
expect(document.to_bson.length).to eq(max_document_size+1)
|
65
|
+
context 'on server versions >= 3.6' do
|
66
|
+
min_server_fcv '3.6'
|
68
67
|
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
it 'fails on the driver when a document larger than 16MiB is inserted' do
|
69
|
+
document = { key: 'a' * (max_document_size - 27), _id: 'foo' }
|
70
|
+
expect(document.to_bson.length).to eq(max_document_size+1)
|
71
|
+
|
72
|
+
lambda do
|
73
|
+
authorized_collection.insert_one(document)
|
74
|
+
end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'on server versions <= 3.4' do
|
79
|
+
max_server_fcv '3.4'
|
80
|
+
|
81
|
+
it 'fails on the server when a document larger than 16MiB is inserted' do
|
82
|
+
document = { key: 'a' * (max_document_size - 27), _id: 'foo' }
|
83
|
+
expect(document.to_bson.length).to eq(max_document_size+1)
|
84
|
+
|
85
|
+
lambda do
|
86
|
+
authorized_collection.insert_one(document)
|
87
|
+
end.should raise_error(Mongo::Error::OperationFailure, /object to insert too large/)
|
88
|
+
end
|
72
89
|
end
|
73
90
|
|
74
91
|
it 'fails in the driver when a document larger than 16MiB+16KiB is inserted' do
|
@@ -81,10 +98,6 @@ describe 'BSON & command size limits' do
|
|
81
98
|
end
|
82
99
|
|
83
100
|
it 'allows bulk writes of multiple documents of exactly 16 MiB each' do
|
84
|
-
if SpecConfig.instance.compressors
|
85
|
-
pending "RUBY-2234"
|
86
|
-
end
|
87
|
-
|
88
101
|
documents = []
|
89
102
|
1.upto(3) do |index|
|
90
103
|
document = { key: 'a' * (max_document_size - 28), _id: "in#{index}" }
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'lite_spec_helper'
|
2
|
+
|
3
|
+
AWS_REGION_TEST_CASES = {
|
4
|
+
'sts.amazonaws.com' => 'us-east-1',
|
5
|
+
'sts.us-west-2.amazonaws.com' => 'us-west-2',
|
6
|
+
'sts.us-west-2.amazonaws.com.ch' => 'us-west-2',
|
7
|
+
'example.com' => 'com',
|
8
|
+
'localhost' => 'us-east-1',
|
9
|
+
'sts..com' => Mongo::Error::InvalidServerAuthHost,
|
10
|
+
'.amazonaws.com' => Mongo::Error::InvalidServerAuthHost,
|
11
|
+
'sts.amazonaws.' => Mongo::Error::InvalidServerAuthHost,
|
12
|
+
'' => Mongo::Error::InvalidServerAuthResponse,
|
13
|
+
'x' * 256 => Mongo::Error::InvalidServerAuthHost,
|
14
|
+
}
|
15
|
+
|
16
|
+
describe 'AWS auth region tests' do
|
17
|
+
|
18
|
+
AWS_REGION_TEST_CASES.each do |host, expected_region|
|
19
|
+
context "host '#{host}'" do
|
20
|
+
let(:request) do
|
21
|
+
Mongo::Auth::Aws::Request.new(access_key_id: 'access_key_id',
|
22
|
+
secret_access_key: 'secret_access_key',
|
23
|
+
session_token: 'session_token',
|
24
|
+
host: host,
|
25
|
+
server_nonce: 'server_nonce',
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
if expected_region.is_a?(String)
|
30
|
+
it 'derives expected region' do
|
31
|
+
request.region.should == expected_region
|
32
|
+
end
|
33
|
+
else
|
34
|
+
it 'fails with an error' do
|
35
|
+
lambda do
|
36
|
+
request.region
|
37
|
+
end.should raise_error(expected_region)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|