From 9da68bb3db09136e75f6147dde61aca4769d183a Mon Sep 17 00:00:00 2001 From: Kyle Banker Date: Wed, 29 Dec 2010 18:06:31 -0500 Subject: [PATCH] RUBY-189 use result of ismaster's maxBsonObjectSize --- ext/cbson/cbson.c | 19 +++++++++-- ext/java/jar/jbson.jar | Bin 13618 -> 13831 bytes ext/java/src/org/jbson/RubyBSONEncoder.java | 23 ++++++++++--- lib/bson/bson_c.rb | 7 ++++ lib/bson/bson_java.rb | 7 ++++ lib/bson/bson_ruby.rb | 20 ++++++++--- lib/mongo.rb | 2 ++ lib/mongo/connection.rb | 13 +++++++- lib/mongo/repl_set_connection.rb | 4 ++- test/bson/bson_test.rb | 8 +++-- test/connection_test.rb | 35 ++++++++++++++++++++ 11 files changed, 122 insertions(+), 16 deletions(-) diff --git a/ext/cbson/cbson.c b/ext/cbson/cbson.c index c769379..065f23c 100644 --- a/ext/cbson/cbson.c +++ b/ext/cbson/cbson.c @@ -88,6 +88,8 @@ static VALUE InvalidDocument; static VALUE DigestMD5; static VALUE RB_HASH; +static int max_bson_size; + #if HAVE_RUBY_ENCODING_H #include "ruby/encoding.h" #define STR_NEW(p,n) \ @@ -582,9 +584,9 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_ length = buffer_get_position(buffer) - start_position; // make sure that length doesn't exceed 4MB - if (length > 4 * 1024 * 1024) { + if (length > max_bson_size) { buffer_free(buffer); - rb_raise(InvalidDocument, "Document too large: BSON documents are limited to 4MB."); + rb_raise(InvalidDocument, "Document too large: BSON documents are limited to %d bytes.", max_bson_size); return; } SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&length, 4); @@ -902,11 +904,18 @@ static VALUE objectid_generate(VALUE self) return oid; } +static void method_update_max_bson_size(VALUE self, VALUE connection) { + max_bson_size = FIX2INT(rb_funcall(connection, rb_intern("max_bson_size"), 0)); +} + +static VALUE method_max_bson_size(VALUE self) { + return INT2FIX(max_bson_size); +} void Init_cbson() { VALUE bson, CBson, Digest, ext_version, digest; static char hostname[MAX_HOSTNAME_LENGTH]; - + element_assignment_method = rb_intern("[]="); unpack_method = rb_intern("unpack"); utc_method = rb_intern("utc"); @@ -939,6 +948,8 @@ void Init_cbson() { rb_define_const(CBson, "VERSION", ext_version); rb_define_module_function(CBson, "serialize", method_serialize, 3); rb_define_module_function(CBson, "deserialize", method_deserialize, 1); + rb_define_module_function(CBson, "max_bson_size", method_max_bson_size, 0); + rb_define_module_function(CBson, "update_max_bson_size", method_update_max_bson_size, 1); rb_require("digest/md5"); Digest = rb_const_get(rb_cObject, rb_intern("Digest")); @@ -953,4 +964,6 @@ void Init_cbson() { rb_str_new2(hostname)); memcpy(hostname_digest, RSTRING_PTR(digest), 16); hostname_digest[16] = '\0'; + + max_bson_size = 4 * 1024 * 1024; } diff --git a/ext/java/jar/jbson.jar b/ext/java/jar/jbson.jar index 2c90cf34d61d2543365046698d0f5dbade47e9d2..672589aefceae2fd08e861ded1bb53444323e459 100644 GIT binary patch delta 9131 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 Ry!p>#Y;H1?NUnb?{{>Xupql^y delta 8964 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 R{|eR 4 * 1024 * 1024 ) { + if ( _buf.size() > _max_bson_size ) { _rbRaise( (RubyClass)_rbclsInvalidDocument, - "Document is too large (" + _buf.size() + "). BSON documents are limited to 4MB (" + - 4 * 1024 * 1024 + ")."); + "Document is too large (" + _buf.size() + "). BSON documents are limited to " + + _max_bson_size + " bytes." ); } _buf.write( EOO ); diff --git a/lib/bson/bson_c.rb b/lib/bson/bson_c.rb index b3b5e4d..d0b6ea5 100644 --- a/lib/bson/bson_c.rb +++ b/lib/bson/bson_c.rb @@ -28,5 +28,12 @@ module BSON CBson.deserialize(ByteBuffer.new(buf).to_s) end + def self.max_bson_size + CBson.max_bson_size + end + + def self.update_max_bson_size(connection) + CBson.update_max_bson_size(connection) + end end end diff --git a/lib/bson/bson_java.rb b/lib/bson/bson_java.rb index cd45e29..14257c5 100644 --- a/lib/bson/bson_java.rb +++ b/lib/bson/bson_java.rb @@ -17,5 +17,12 @@ module BSON callback.get end + def self.max_bson_size + Java::OrgJbson::RubyBSONEncoder.max_bson_size(self) + end + + def self.update_max_bson_size(connection) + Java::OrgJbson::RubyBSONEncoder.update_max_bson_size(self, connection) + end end end diff --git a/lib/bson/bson_ruby.rb b/lib/bson/bson_ruby.rb index eb033d9..f380559 100644 --- a/lib/bson/bson_ruby.rb +++ b/lib/bson/bson_ruby.rb @@ -20,6 +20,10 @@ module BSON # A BSON seralizer/deserializer in pure Ruby. class BSON_RUBY + DEFAULT_MAX_BSON_SIZE = 4 * 1024 * 1024 + + @@max_bson_size = DEFAULT_MAX_BSON_SIZE + MINKEY = -1 EOO = 0 NUMBER = 1 @@ -51,13 +55,13 @@ module BSON NULL_BYTE = "\0".force_encoding('binary').freeze UTF8_ENCODING = Encoding.find('utf-8') BINARY_ENCODING = Encoding.find('binary') - + def self.to_utf8_binary(str) str.encode(UTF8_ENCODING).force_encoding(BINARY_ENCODING) end else NULL_BYTE = "\0" - + def self.to_utf8_binary(str) begin str.unpack("U*") @@ -68,6 +72,14 @@ module BSON end end + def self.update_max_bson_size(connection) + @@max_bson_size = connection.max_bson_size + end + + def self.max_bson_size + @@max_bson_size + end + def self.serialize_cstr(buf, val) buf.put_binary(to_utf8_binary(val.to_s)) buf.put_binary(NULL_BYTE) @@ -120,8 +132,8 @@ module BSON end serialize_eoo_element(@buf) - if @buf.size > 4 * 1024 * 1024 - raise InvalidDocument, "Document is too large (#{@buf.size}). BSON documents are limited to 4MB (#{4 * 1024 * 1024})." + if @buf.size > @@max_bson_size + raise InvalidDocument, "Document is too large (#{@buf.size}). BSON documents are limited to #{@@max_bson_size} bytes." end @buf.put_int(@buf.size, 0) @buf diff --git a/lib/mongo.rb b/lib/mongo.rb index 09f676c..f036ca7 100644 --- a/lib/mongo.rb +++ b/lib/mongo.rb @@ -11,6 +11,8 @@ module Mongo DESCENDING = -1 GEO2D = '2d' + DEFAULT_MAX_BSON_SIZE = 4 * 1024 * 1024 + module Constants OP_REPLY = 1 OP_MSG = 1000 diff --git a/lib/mongo/connection.rb b/lib/mongo/connection.rb index a7aa60e..c09fbbc 100644 --- a/lib/mongo/connection.rb +++ b/lib/mongo/connection.rb @@ -440,7 +440,9 @@ module Mongo set_primary(@host_to_try) end - if !connected? + if connected? + BSON::BSON_CODER.update_max_bson_size(self) + else raise ConnectionFailure, "Failed to connect to a master node at #{@host_to_try[0]}:#{@host_to_try[1]}" end end @@ -470,6 +472,15 @@ module Mongo @primary_pool = nil end + # Returns the maximum BSON object size as returned by the core server. + # Use the 4MB default when the server doesn't report this. + # + # @return [Integer] + def max_bson_size + config = self['admin'].command({:ismaster => 1}) + config['maxBsonObjectSize'] || Mongo::DEFAULT_MAX_BSON_SIZE + end + # Checkout a socket for reading (i.e., a secondary node). # Note: this is overridden in ReplSetConnection. def checkout_reader diff --git a/lib/mongo/repl_set_connection.rb b/lib/mongo/repl_set_connection.rb index ecc5292..7c8438d 100644 --- a/lib/mongo/repl_set_connection.rb +++ b/lib/mongo/repl_set_connection.rb @@ -111,7 +111,9 @@ module Mongo pick_secondary_for_read if @read_secondary - if !connected? + if connected? + BSON::BSON_CODER.update_max_bson_size(self) + else if @secondary_pools.empty? raise ConnectionFailure, "Failed to connect any given host:port" else diff --git a/test/bson/bson_test.rb b/test/bson/bson_test.rb index 2209deb..c88c762 100644 --- a/test/bson/bson_test.rb +++ b/test/bson/bson_test.rb @@ -67,13 +67,17 @@ class BSONTest < Test::Unit::TestCase assert_doc_pass(doc) end - def test_document_length - doc = {'name' => 'a' * 5 * 1024 * 1024} + def test_limit_max_bson_size + doc = {'name' => 'a' * BSON_CODER.max_bson_size} assert_raise InvalidDocument do assert @encoder.serialize(doc) end end + def test_max_bson_size + assert BSON_CODER.max_bson_size >= BSON::DEFAULT_MAX_BSON_SIZE + end + def test_round_trip doc = {'doc' => 123} @encoder.deserialize(@encoder.serialize(doc)) diff --git a/test/connection_test.rb b/test/connection_test.rb index e1b26ea..8e46d50 100644 --- a/test/connection_test.rb +++ b/test/connection_test.rb @@ -165,6 +165,41 @@ class TestConnection < Test::Unit::TestCase assert unlocked, "mongod failed to unlock" end + def test_max_bson_size_value + conn = standard_connection + if conn.server_version > "1.6" + assert_equal conn['admin'].command({:ismaster => 1})['maxBsonObjectSize'], conn.max_bson_size + end + + conn.connect + assert_equal BSON::BSON_CODER.max_bson_size, conn.max_bson_size + doc = {'n' => 'a' * (BSON_CODER.max_bson_size - 11)} + assert_raise InvalidDocument do + assert BSON::BSON_CODER.serialize(doc) + end + + limit = 7 * 1024 * 1024 + conn.stubs(:max_bson_size).returns(limit) + conn.connect + assert_equal limit, conn.max_bson_size + assert_equal limit, BSON::BSON_CODER.max_bson_size + doc = {'n' => 'a' * ((limit) - 11)} + assert_raise_error InvalidDocument, "limited to #{limit}" do + assert BSON::BSON_CODER.serialize(doc) + end + end + + def test_max_bson_size_with_old_mongod + conn = standard_connection(:connect => false) + + admin_db = Object.new + admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1}).twice + conn.expects(:[]).with('admin').returns(admin_db).twice + + conn.connect + assert_equal Mongo::DEFAULT_MAX_BSON_SIZE, BSON::BSON_CODER.max_bson_size + end + context "Saved authentications" do setup do @conn = standard_connection