@@ -430,17 +430,19 @@ def self.uri_option(uri_key, name, extra = {})
430430 uri_option 'sockettimeoutms' , :socket_timeout , :type => :ms_convert
431431 uri_option 'serverselectiontimeoutms' , :server_selection_timeout , :type => :ms_convert
432432 uri_option 'localthresholdms' , :local_threshold , :type => :ms_convert
433+ uri_option 'heartbeatfrequencyms' , :heartbeat_frequency , :type => :ms_convert
434+ uri_option 'maxidletimems' , :max_idle_time , :type => :ms_convert
433435
434436 # Write Options
435437 uri_option 'w' , :w , :group => :write
436- uri_option 'journal' , :j , :group => :write
438+ uri_option 'journal' , :j , :group => :write , :type => :bool
437439 uri_option 'fsync' , :fsync , :group => :write
438- uri_option 'wtimeoutms' , :timeout , :group => :write
440+ uri_option 'wtimeoutms' , :timeout , :group => :write , :type => :unsigned_int
439441
440442 # Read Options
441443 uri_option 'readpreference' , :mode , :group => :read , :type => :read_mode
442444 uri_option 'readpreferencetags' , :tag_sets , :group => :read , :type => :read_tags
443- uri_option 'maxstalenessseconds' , :max_staleness , :group => :read
445+ uri_option 'maxstalenessseconds' , :max_staleness , :group => :read , :type => :max_staleness
444446
445447 # Pool options
446448 uri_option 'minpoolsize' , :min_pool_size
@@ -449,6 +451,13 @@ def self.uri_option(uri_key, name, extra = {})
449451
450452 # Security Options
451453 uri_option 'ssl' , :ssl
454+ uri_option 'tls' , :ssl
455+ uri_option 'tlsallowinvalidcertificates' , :ssl_verify , :type => :inverse_bool
456+ uri_option 'tlscafilepath' , :ssl_ca_cert
457+ uri_option 'tlsclientcertfilepath' , :ssl_cert
458+ uri_option 'tlsclientkeyfilepath' , :ssl_key
459+ uri_option 'tlsclientkeypassword' , :ssl_key_pass_phrase
460+
452461
453462 # Topology options
454463 uri_option 'connect' , :connect
@@ -461,7 +470,9 @@ def self.uri_option(uri_key, name, extra = {})
461470 # Client Options
462471 uri_option 'appname' , :app_name
463472 uri_option 'compressors' , :compressors , :type => :array
464- uri_option 'zlibcompressionlevel' , :zlib_compression_level
473+ uri_option 'readconcernlevel' , :read_concern
474+ uri_option 'retrywrites' , :retry_writes , :type => :bool
475+ uri_option 'zlibcompressionlevel' , :zlib_compression_level , :type => :zlib_compression_level
465476
466477 # Casts option values that do not have a specifically provided
467478 # transformation to the appropriate type.
@@ -571,7 +582,7 @@ def auth_source(value)
571582 #
572583 # @return [Symbol] The transformed authentication mechanism.
573584 def auth_mech ( value )
574- AUTH_MECH_MAP [ value . upcase ]
585+ AUTH_MECH_MAP [ value . upcase ] || log_warn ( " #{ value } is not a valid auth mechanism" )
575586 end
576587
577588 # Read preference mode transformation.
@@ -615,6 +626,94 @@ def auth_mech_props(value)
615626 properties
616627 end
617628
629+ # Parses the zlib compression level.
630+ #
631+ # @param value [ String ] The zlib compression level string.
632+ #
633+ # @return [ Integer | nil ] The compression level value if it is between -1 and 9 (inclusive),
634+ # otherwise nil (and a warning will be raised).
635+ def zlib_compression_level ( value )
636+ if /^-?\d +$/ =~ value
637+ i = value . to_i
638+
639+ if i >= -1 && i <= 9
640+ return i
641+ end
642+ end
643+
644+ log_warn ( "#{ value } is not a valid zlibCompressionLevel" )
645+ nil
646+ end
647+
648+
649+ # Parses a boolean value.
650+ #
651+ # @param value [ String ] The URI option value.
652+ #
653+ # @return [ true | false | nil ] The boolean value parsed out, otherwise nil (and a warning
654+ # will be raised).
655+ def bool ( value )
656+ case value
657+ when "true"
658+ true
659+ when "false"
660+ false
661+ else
662+ log_warn ( "invalid boolean: #{ value } " )
663+ nil
664+ end
665+ end
666+
667+ # Parses a boolean value and returns its inverse. This is used for options where the spec
668+ # defines the boolean value semantics of enabling/disabling something in the reverse way that
669+ # the driver does. For instance, the client option `ssl_verify` will disable certificate
670+ # checking when the value is false, but the spec defines the option
671+ # `tlsAllowInvalidCertificates`, which disables certificate checking when the value is true.
672+ #
673+ # @param value [ String ] The URI option.
674+ #
675+ # @return [ true | false | nil ] The inverse of boolean value parsed out, otherwise nil (and a
676+ # warning will be raised).
677+ def inverse_bool ( value )
678+ !bool ( value )
679+ end
680+
681+ # Parses the max staleness value, which must be either "0" or an integer greater or equal to 90.
682+ #
683+ # @param value [ String ] The max staleness string.
684+ #
685+ # @return [ Integer | nil ] The max staleness integer parsed out if it is valid, otherwise nil
686+ # (and a warning will be raised).
687+ def max_staleness ( value )
688+ if /^\d +$/ =~ value
689+ int = value . to_i
690+
691+ if int >= 0 && int < 90
692+ log_warn ( "max staleness must be either 0 or greater than 90: #{ value } " )
693+ end
694+
695+ return int
696+ end
697+
698+ log_warn ( "Invalid max staleness value: #{ value } " )
699+ nil
700+ end
701+
702+ # Parses an unsigned integer value.
703+ #
704+ # @param value [ String ] The URI option value.
705+ #
706+ # @return [ Integer | nil ] The integer parsed out, otherwise nil (and a warning will be
707+ # raised).
708+ def unsigned_int ( value )
709+ unless /^?\d +$/ =~ value
710+ log_warn ( "Invalid unsigned integer value: #{ value } " )
711+ return nil
712+ end
713+
714+ value . to_i
715+ end
716+
618717 # Ruby's convention is to provide timeouts in seconds, not milliseconds and
619718 # to use fractions where more precision is necessary. The connection string
620719 # options are always in MS so we provide an easy conversion type.
@@ -625,6 +724,11 @@ def auth_mech_props(value)
625724 #
626725 # @since 2.0.0
627726 def ms_convert ( value )
727+ unless /^-?\d +(\. \d +)?$/ =~ value
728+ log_warn ( "Invalid ms value: #{ value } " )
729+ return nil
730+ end
731+
628732 value . to_f / 1000
629733 end
630734
@@ -636,6 +740,11 @@ def ms_convert(value)
636740 def hash_extractor ( value )
637741 value . split ( ',' ) . reduce ( { } ) do |set , tag |
638742 k , v = tag . split ( ':' )
743+ if v . nil?
744+ log_warn ( "#{ value } is not a valid URI hash" )
745+ return nil
746+ end
747+
639748 set . merge ( decode ( k ) . downcase . to_sym => decode ( v ) )
640749 end
641750 end
0 commit comments