123456789_123456789_123456789_123456789_123456789_

Class: Mongo::URI::SRVProtocol

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, ::Mongo::URI
Instance Chain:
Inherits: Mongo::URI
Defined in: lib/mongo/uri/srv_protocol.rb

Overview

Parser for a ::Mongo::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

Examples:

Use the uri string to make a client connection.

client = Mongo::Client.new('mongodb+srv://test6.test.build.10gen.cc/')

Since:

  • 2.5.0

Constant Summary

::Mongo::Loggable - Included

PREFIX

::Mongo::URI - Inherited

AUTH_DELIM, AUTH_MECH_MAP, AUTH_USER_PWD_DELIM, DATABASE_DELIM, FORMAT, HELP, HOST_DELIM, HOST_PORT_DELIM, INDIV_URI_OPTS_DELIM, INVALID_HOST, INVALID_OPTS_DELIM, INVALID_OPTS_VALUE_DELIM, INVALID_PORT, INVALID_SCHEME, MONGODB_SCHEME, MONGODB_SRV_SCHEME, PERCENT_CHAR, READ_MODE_MAP, REPEATABLE_OPTIONS, SCHEME, SCHEME_DELIM, UNESCAPED_DATABASE, UNESCAPED_UNIX_SOCKET, UNESCAPED_USER_PWD, UNIX_SOCKET, UNSAFE, URI_OPTS_DELIM, URI_OPTS_VALUE_DELIM

Class Method Summary

::Mongo::URI - Inherited

.get

Get either a ::Mongo::URI object or a SRVProtocol URI object.

.new

Create the new uri from the provided string.

Instance Attribute Summary

::Mongo::URI - Inherited

#options

The uri parser object options.

#servers

The servers specified in the uri.

#uri_options

Mongo::Options::Redacted of the options specified in the uri.

Instance Method Summary

::Mongo::URI - Inherited

#client_options

Gets the options hash that needs to be passed to a ::Mongo::Client on instantiation, so we don’t have to merge the credentials and database in at that point - we only have a single point here.

#credentials

Get the credentials provided in the ::Mongo::URI.

#database

Get the database provided in the ::Mongo::URI.

#srv_records,
#to_s

Get the uri as a string.

#decode, #encode, #options_mapper, #parse!, #parse_database!, #parse_password!, #parse_uri_options!, #parse_user!, #raise_invalid_error!, #raise_invalid_error_no_fmt!,
#reconstruct_uri

Reconstruct the ::Mongo::URI from its parts.

#scheme, #validate_uri_options!

::Mongo::Address::Validator - Included

#validate_address_str!

Takes an address string in ipv4/ipv6/hostname/socket path format and validates its format.

#validate_hostname!

Validates format of the hostname, in particular for further use as the origin in same origin verification.

#validate_port_str!

::Mongo::Loggable - Included

#log_debug

Convenience method to log debug messages with the standard prefix.

#log_error

Convenience method to log error messages with the standard prefix.

#log_fatal

Convenience method to log fatal messages with the standard prefix.

#log_info

Convenience method to log info messages with the standard prefix.

#log_warn

Convenience method to log warn messages with the standard prefix.

#logger

Get the logger instance.

#_mongo_log_prefix, #format_message

Constructor Details

This class inherits a constructor from Mongo::URI

Instance Attribute Details

#query_hostnameString (readonly)

This method is for internal use only.

The hostname that is specified in the ::Mongo::URI and used to look up SRV records.

This attribute needs to be defined because SRVProtocol changes #servers to be the result of the lookup rather than the hostname specified in the ::Mongo::URI.

Returns:

  • (String)

    The hostname used in SRV lookup.

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 72

attr_reader :query_hostname

#srv_records (readonly)

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 39

attr_reader :srv_records

#srv_resultSrv::Result (readonly)

This method is for internal use only.

Returns:

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 60

attr_reader :srv_result

Instance Method Details

#client_optionsHash

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.

Examples:

Get the client options.

uri.client_options

Returns:

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 51

def client_options
  opts = @txt_options.merge(ssl: true)
  opts = opts.merge(uri_options).merge(:database => database)
  @user ? opts.merge(credentials) : opts
end

#get_txt_options(hostname) ⇒ Hash (private)

Obtains the TXT options of a host.

Parameters:

  • hostname (String)

    The hostname whose records should be obtained.

Returns:

  • (Hash)

    The TXT record options (an empyt hash if no TXT records are found).

Raises:

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 199

def get_txt_options(hostname)
  options_string = resolver.get_txt_options_string(hostname)
  if options_string
    parse_txt_options!(options_string)
  else
    {}
  end
end

#parse!(remaining) (private)

Parses the credentials from the ::Mongo::URI and performs DNS queries to obtain the hosts and TXT options.

Parameters:

  • remaining (String)

    The portion of the ::Mongo::URI pertaining to the authentication credentials and the hosts.

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 140

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, uri_options[:srv_service_name], uri_options[:srv_max_hosts])
  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

#parse_txt_options!(string) ⇒ Hash (private)

Parses the TXT record options into a hash and adds the options to set of all ::Mongo::URI options parsed.

Parameters:

  • string (String)

    The concatenated TXT options.

Returns:

  • (Hash)

    The parsed TXT options.

Raises:

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 217

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('=')
    unless VALID_TXT_OPTIONS.include?(key.downcase)
      msg = "TXT records can only specify the options [#{VALID_TXT_OPTIONS.join(', ')}]: #{string}"
      raise Error::InvalidTXTRecord.new(msg)
    end
    options_mapper.add_uri_option(key, value, txt_options)
    txt_options
  end
end

#raise_invalid_error!(details) (private)

Raises an InvalidURI error.

Parameters:

  • details (String)

    A detailed error message.

Raises:

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 120

def raise_invalid_error!(details)
  raise Error::InvalidURI.new(@string, details, FORMAT)
end

#resolverMongo::Srv::Resolver (private)

Gets the SRV resolver.

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 127

def resolver
  @resolver ||= Srv::Resolver.new(
    raise_on_invalid: true,
    resolv_options: options[:resolv_options],
    timeout: options[:connect_timeout],
  )
end

#schemeString (private)

Gets the MongoDB SRV ::Mongo::URI scheme.

Returns:

  • (String)

    The MongoDB SRV URI scheme.

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 111

def scheme
  MONGODB_SRV_SCHEME
end

#validate_srv_hostname(hostname) (private)

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.

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 173

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

#validate_uri_options! (private)

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/uri/srv_protocol.rb', line 230

def validate_uri_options!
  if uri_options[:direct_connection]
    raise_invalid_error_no_fmt!("directConnection=true is incompatible with SRV URIs")
  end

  super
end