class Mongo::URI::SRVProtocol
Parser for a URI using the mongodb+srv protocol, which specifies a DNS to query for SRV records. The driver will query the DNS server for SRV records on {hostname}.{domainname}, prefixed with _mongodb._tcp The SRV records can then be used as the seedlist for a Mongo::Client. The driver also queries for a TXT record providing default connection string options. Only one TXT record is allowed, and only a subset of Mongo::Client options is allowed.
Please refer to the Initial DNS Seedlist Discovery spec for details.
github.com/mongodb/specifications/blob/master/source/initial-dns-seedlist-discovery
@example Use the uri string to make a client connection.
client = Mongo::Client.new('mongodb+srv://test6.test.build.10gen.cc/')
@since 2.5.0
Constants
- DOT_PARTITION
@return [ String ] DOT_PARTITION The '.' character used to delineate the parts of a
hostname.
@deprecated
- FORMAT
- INVALID_DOMAIN
@return [ String ] INVALID_DOMAIN Error message format string indicating that the domain name
of the hostname does not fit the expected form.
@deprecated
- INVALID_HOST
@return [ String ] INVALID_HOST Error message format string indicating that the hostname in
in the URI does not fit the expected form.
- INVALID_PORT
@return [ String ] INVALID_PORT Error message format string indicating that a port was
included with an SRV hostname.
- INVALID_TXT_RECORD_OPTION
@return [ String ] INVALID_TXT_RECORD_OPTION Error message format string indicating that an
unexpected TXT record option was found.
- NO_SRV_RECORDS
@return [ String ] NO_SRV_RECORDS Error message format string indicating that no SRV records
were found.
- VALID_TXT_OPTIONS
@return [ Array<String> ] VALID_TXT_OPTIONS The valid options for a TXT record to specify.
Attributes
@return [ Srv::Result ] SRV lookup result.
@api private
Public Instance Methods
Gets the options hash that needs to be passed to a Mongo::Client on instantiation, so we don't have to merge the txt record options, credentials, and database in at that point - we only have a single point here.
@example Get the client options.
uri.client_options
@return [ Hash ] The options passed to the Mongo::Client
@since 2.5.0
# File lib/mongo/uri/srv_protocol.rb, line 48 def client_options opts = @txt_options.merge(ssl: true) opts = opts.merge(uri_options).merge(:database => database) @user ? opts.merge(credentials) : opts end
Private Instance Methods
Obtains the TXT options of a host.
@param [ String ] hostname The hostname whose records should be obtained.
@return [ Hash ] The TXT record options (an empyt hash if no TXT
records are found).
@raise [ Mongo::Error::InvalidTXTRecord ] If more than one TXT record is found.
# File lib/mongo/uri/srv_protocol.rb, line 200 def get_txt_options(hostname) options_string = resolver.get_txt_options_string(hostname) if options_string parse_txt_options!(options_string) else {} end end
Parses the credentials from the URI and performs DNS queries to obtain the hosts and TXT options.
@param [ String ] remaining The portion of the URI pertaining to the
authentication credentials and the hosts.
# File lib/mongo/uri/srv_protocol.rb, line 141 def parse!(remaining) super if @servers.length != 1 raise_invalid_error!(INVALID_HOST) end hostname = @servers.first validate_srv_hostname(hostname) @query_hostname = hostname @srv_result = resolver.get_records(hostname) if srv_result.empty? raise Error::NoSRVRecords.new(NO_SRV_RECORDS % hostname) end @txt_options = get_txt_options(hostname) || {} records = srv_result.address_strs records.each do |record| validate_address_str!(record) end @servers = records rescue Error::InvalidAddress => e raise_invalid_error!(e.message) end
Parses the TXT record options into a hash and adds the options to set of all URI options parsed.
@param [ String ] string The concatenated TXT options.
@return [ Hash ] The parsed TXT options.
@raise [ Mongo::Error::InvalidTXTRecord ] If the TXT record does not fit the expected form
or the option specified is not a valid TXT option.
# File lib/mongo/uri/srv_protocol.rb, line 218 def parse_txt_options!(string) string.split(INDIV_URI_OPTS_DELIM).reduce({}) do |txt_options, opt| raise Error::InvalidTXTRecord.new(INVALID_OPTS_VALUE_DELIM) unless opt.index(URI_OPTS_VALUE_DELIM) key, value = opt.split(URI_OPTS_VALUE_DELIM) raise Error::InvalidTXTRecord.new(INVALID_TXT_RECORD_OPTION) unless VALID_TXT_OPTIONS.include?(key.downcase) add_uri_option(key, value, txt_options) txt_options end end
Raises an InvalidURI error.
@param [ String ] details A detailed error message.
@raise [ Mongo::Error::InvalidURI ]
# File lib/mongo/uri/srv_protocol.rb, line 122 def raise_invalid_error!(details) raise Error::InvalidURI.new(@string, details, FORMAT) end
Gets the SRV resolver.
@return [ Mongo::Srv::Resolver ]
# File lib/mongo/uri/srv_protocol.rb, line 129 def resolver @resolver ||= Srv::Resolver.new( raise_on_invalid: true, resolv_options: options[:resolv_options], ) end
Validates the hostname used in an SRV URI.
The hostname cannot include a port.
The hostname must not begin with a dot, end with a dot, or have consecutive dots. The hostname must have a minimum of 3 total components (foo.bar.tld).
Raises Error::InvalidURI if validation fails.
# File lib/mongo/uri/srv_protocol.rb, line 174 def validate_srv_hostname(hostname) raise_invalid_error!(INVALID_PORT) if hostname.include?(HOST_PORT_DELIM) if hostname.start_with?('.') raise_invalid_error!("Hostname cannot start with a dot: #{hostname}") end if hostname.end_with?('.') raise_invalid_error!("Hostname cannot end with a dot: #{hostname}") end parts = hostname.split('.') if parts.any?(&:empty?) raise_invalid_error!("Hostname cannot have consecutive dots: #{hostname}") end if parts.length < 3 raise_invalid_error!("Hostname must have a minimum of 3 components (foo.bar.tld): #{hostname}") end end