Class: Mongo::Protocol::Message Abstract
- Inherits:
-
Object
- Object
- Mongo::Protocol::Message
- Includes:
- Id, Serializers
- Defined in:
- lib/mongo/protocol/message.rb
Overview
A base class providing functionality required by all messages in the MongoDB wire protocol. It provides a minimal DSL for defining typed fields to enable serialization and deserialization over the wire.
Direct Known Subclasses
Constant Summary collapse
- BATCH_SIZE =
The batch size constant.
'batchSize'.freeze
- COLLECTION =
The collection constant.
'collection'.freeze
- LIMIT =
The limit constant.
'limit'.freeze
- ORDERED =
The ordered constant.
'ordered'.freeze
- Q =
The q constant.
'q'.freeze
- MAX_MESSAGE_SIZE =
Default max message size of 48MB.
50331648.freeze
Instance Attribute Summary collapse
-
#request_id ⇒ Fixnum
readonly
Returns the request id for the message.
Class Method Summary collapse
-
.deserialize(io, max_message_size = MAX_MESSAGE_SIZE, expected_response_to = nil, options = {}) ⇒ Message
private
Deserializes messages from an IO stream.
Instance Method Summary collapse
-
#==(other) ⇒ true, false
(also: #eql?)
Tests for equality between two wire protocol messages by comparing class and field values.
-
#hash ⇒ Fixnum
Creates a hash from the values of the fields of a message.
-
#initialize(*args) ⇒ Message
constructor
:nodoc:.
- #maybe_add_server_api(server_api) ⇒ Object
-
#maybe_compress(compressor, zlib_compression_level = nil) ⇒ self
private
Compress the message, if supported by the wire protocol used and if the command being sent permits compression.
-
#maybe_decrypt(context) ⇒ Mongo::Protocol::Msg
Possibly decrypt this message with libmongocrypt.
-
#maybe_encrypt(connection, context) ⇒ Mongo::Protocol::Msg
Possibly encrypt this message with libmongocrypt.
-
#maybe_inflate ⇒ Protocol::Message
private
Inflate a message if it is compressed.
-
#number_returned ⇒ 0
Default number returned value for protocol messages.
-
#replyable? ⇒ false
The default for messages is not to require a reply after sending a message to the server.
-
#serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil, bson_overhead = nil) ⇒ String
(also: #to_s)
Serializes message into bytes that can be sent on the wire.
-
#set_request_id ⇒ Fixnum
Generates a request id for a message.
Methods included from Id
Constructor Details
#initialize(*args) ⇒ Message
:nodoc:
79 80 81 |
# File 'lib/mongo/protocol/message.rb', line 79 def initialize(*args) # :nodoc: set_request_id end |
Instance Attribute Details
#request_id ⇒ Fixnum (readonly)
Returns the request id for the message
86 87 88 |
# File 'lib/mongo/protocol/message.rb', line 86 def request_id @request_id end |
Class Method Details
.deserialize(io, max_message_size = MAX_MESSAGE_SIZE, expected_response_to = nil, options = {}) ⇒ Message
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Deserializes messages from an IO stream.
This method returns decompressed messages (i.e. if the message on the wire was OP_COMPRESSED, this method would typically return the OP_MSG message that is the result of decompression).
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/mongo/protocol/message.rb', line 238 def self.deserialize(io, = MAX_MESSAGE_SIZE, expected_response_to = nil, = {} ) # io is usually a Mongo::Socket instance, which supports the # timeout option. For compatibility with whoever might call this # method with some other IO-like object, pass options only when they # are not empty. = .slice(:timeout, :socket_timeout) if .empty? chunk = io.read(16) else chunk = io.read(16, **) end buf = BSON::ByteBuffer.new(chunk) length, _request_id, response_to, _op_code = deserialize_header(buf) # Protection from potential DOS man-in-the-middle attacks. See # DRIVERS-276. if length > ( || MAX_MESSAGE_SIZE) raise Error::MaxMessageSize.new() end # Protection against returning the response to a previous request. See # RUBY-1117 if expected_response_to && response_to != expected_response_to raise Error::UnexpectedResponse.new(expected_response_to, response_to) end if .empty? chunk = io.read(length - 16) else chunk = io.read(length - 16, **) end buf = BSON::ByteBuffer.new(chunk) = Registry.get(_op_code).allocate .send(:fields).each do |field| if field[:multi] deserialize_array(, buf, field, ) else deserialize_field(, buf, field, ) end end if .is_a?(Msg) .fix_after_deserialization end .maybe_inflate end |
Instance Method Details
#==(other) ⇒ true, false Also known as: eql?
Tests for equality between two wire protocol messages by comparing class and field values.
295 296 297 298 299 300 301 302 |
# File 'lib/mongo/protocol/message.rb', line 295 def ==(other) return false if self.class != other.class fields.all? do |field| name = field[:name] instance_variable_get(name) == other.instance_variable_get(name) end end |
#hash ⇒ Fixnum
Creates a hash from the values of the fields of a message.
308 309 310 |
# File 'lib/mongo/protocol/message.rb', line 308 def hash fields.map { |field| instance_variable_get(field[:name]) }.hash end |
#maybe_add_server_api(server_api) ⇒ Object
173 174 175 |
# File 'lib/mongo/protocol/message.rb', line 173 def maybe_add_server_api(server_api) raise Error::ServerApiNotSupported, "Server API parameters cannot be sent to pre-3.6 MongoDB servers. Please remove the :server_api parameter from Client options or use MongoDB 3.6 or newer" end |
#maybe_compress(compressor, zlib_compression_level = nil) ⇒ self
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Compress the message, if supported by the wire protocol used and if the command being sent permits compression. Otherwise returns self.
112 113 114 |
# File 'lib/mongo/protocol/message.rb', line 112 def maybe_compress(compressor, zlib_compression_level = nil) self end |
#maybe_decrypt(context) ⇒ Mongo::Protocol::Msg
Possibly decrypt this message with libmongocrypt.
152 153 154 155 156 157 158 |
# File 'lib/mongo/protocol/message.rb', line 152 def maybe_decrypt(context) # TODO determine if we should be decrypting data coming from pre-4.2 # servers, potentially using legacy wire protocols. If so we need # to implement decryption for those wire protocols as our current # encryption/decryption code is OP_MSG-specific. self end |
#maybe_encrypt(connection, context) ⇒ Mongo::Protocol::Msg
Possibly encrypt this message with libmongocrypt.
168 169 170 171 |
# File 'lib/mongo/protocol/message.rb', line 168 def maybe_encrypt(connection, context) # Do nothing if the Message subclass has not implemented this method self end |
#maybe_inflate ⇒ Protocol::Message
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Inflate a message if it is compressed.
142 143 144 |
# File 'lib/mongo/protocol/message.rb', line 142 def maybe_inflate self end |
#number_returned ⇒ 0
Default number returned value for protocol messages.
326 |
# File 'lib/mongo/protocol/message.rb', line 326 def number_returned; 0; end |
#replyable? ⇒ false
The default for messages is not to require a reply after sending a message to the server.
97 98 99 |
# File 'lib/mongo/protocol/message.rb', line 97 def replyable? false end |
#serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil, bson_overhead = nil) ⇒ String Also known as: to_s
Serializes message into bytes that can be sent on the wire
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/mongo/protocol/message.rb', line 201 def serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil, bson_overhead = nil) max_size = if max_bson_size && bson_overhead max_bson_size + bson_overhead elsif max_bson_size max_bson_size else nil end start = buffer.length serialize_header(buffer) serialize_fields(buffer, max_size) buffer.replace_int32(start, buffer.length - start) end |
#set_request_id ⇒ Fixnum
Generates a request id for a message
317 318 319 |
# File 'lib/mongo/protocol/message.rb', line 317 def set_request_id @request_id = self.class.next_id end |