class Addressable::URI

Experimental RBS support (using type sampling data from the type_fusion project).

# sig/addressable/uri.rbs

class Addressable::URI
  def self.encode: (String uri, ?Class return_type) -> String
  def self.encode_component: (String? component, ?(Regexp | String) character_class, ?String upcase_encoded) -> String?
  def self.ip_based_schemes: () -> Array[String]
  def self.parse: (String uri) -> Addressable::URI
  def self.port_mapping: () -> Hash
  def authority: () -> String?
  def authority=: (String new_authority) -> nil
  def defer_validation: () -> nil
  def host=: (String new_host) -> nil
  def initialize: (?Hash options) -> void
  def ip_based?: () -> true
  def password=: (nil new_password) -> nil
  def path=: (String new_path) -> nil
  def port=: (nil new_port) -> nil
  def remove_composite_values: () -> nil
  def reset_ivs: () -> nil
  def scheme=: (String new_scheme) -> nil
  def to_s: () -> String
  def user=: (nil new_user) -> nil
  def userinfo: () -> nil
  def validate: () -> nil
end

<a href=“www.ietf.org/rfc/rfc3987.txt”>RFC 3987</a>.
<a href=“www.ietf.org/rfc/rfc3986.txt”>RFC 3986</a>,
This is an implementation of a URI parser based on
#

def self.convert_path(path)

Returns:
  • (Addressable::URI) -

Parameters:
  • path (String, Addressable::URI, #to_str) --
def self.convert_path(path)
  # If we were given nil, return nil.
  return nil unless path
  # If a URI object is passed, just return itself.
  return path if path.kind_of?(self)
  unless path.respond_to?(:to_str)
    raise TypeError, "Can't convert #{path.class} into String."
  end
  # Otherwise, convert to a String
  path = path.to_str.strip
  path.sub!(/^file:\/?\/?/, EMPTY_STR) if path =~ /^file:\/?\/?/
  path = SLASH + path if path =~ /^([a-zA-Z])[\|:]/
  uri = self.parse(path)
  if uri.scheme == nil
    # Adjust windows-style uris
    uri.path.sub!(/^\/?([a-zA-Z])[\|:][\\\/]/) do
      "/#{$1.downcase}:/"
    end
    uri.path.tr!("\\", SLASH)
    if File.exist?(uri.path) &&
        File.stat(uri.path).directory?
      uri.path.chomp!(SLASH)
      uri.path = uri.path + '/'
    end
    # If the path is absolute, set the scheme and host.
    if uri.path.start_with?(SLASH)
      uri.scheme = "file"
      uri.host = EMPTY_STR
    end
    uri.normalize!
  end
  return uri
end

def self.encode(uri, return_type=String)

Experimental RBS support (using type sampling data from the type_fusion project).

def self.encode: (String uri, ?Class return_type) -> String

This signature was generated using 34 samples from 1 application.

Returns:
  • (String, Addressable::URI) -

Parameters:
  • return_type (Class) --
  • uri (String, Addressable::URI, #to_str) --
def self.encode(uri, return_type=String)
  return nil if uri.nil?
  begin
    uri = uri.to_str
  rescue NoMethodError, TypeError
    raise TypeError, "Can't convert #{uri.class} into String."
  end if !uri.is_a? String
  if ![String, ::Addressable::URI].include?(return_type)
    raise TypeError,
      "Expected Class (String or Addressable::URI), " +
      "got #{return_type.inspect}"
  end
  uri_object = uri.kind_of?(self) ? uri : self.parse(uri)
  encoded_uri = Addressable::URI.new(
    :scheme => self.encode_component(uri_object.scheme,
      Addressable::URI::CharacterClasses::SCHEME),
    :authority => self.encode_component(uri_object.authority,
      Addressable::URI::CharacterClasses::AUTHORITY),
    :path => self.encode_component(uri_object.path,
      Addressable::URI::CharacterClasses::PATH),
    :query => self.encode_component(uri_object.query,
      Addressable::URI::CharacterClasses::QUERY),
    :fragment => self.encode_component(uri_object.fragment,
      Addressable::URI::CharacterClasses::FRAGMENT)
  )
  if return_type == String
    return encoded_uri.to_s
  elsif return_type == ::Addressable::URI
    return encoded_uri
  end
end

def self.encode_component(component, character_class=

Experimental RBS support (using type sampling data from the type_fusion project).

def self.encode_component: (String? component, ?(Regexp | String) character_class, ?String upcase_encoded) -> String?

This signature was generated using 201 samples from 3 applications.

Returns:
  • (String) - The encoded component.

Parameters:
  • upcase_encoded (Regexp) --
  • character_class (String, Regexp) --
  • component (String, #to_str) -- The URI component to encode.
def self.encode_component(component, character_class=
    CharacterClasses::RESERVED + CharacterClasses::UNRESERVED,
    upcase_encoded='')
  return nil if component.nil?
  begin
    if component.kind_of?(Symbol) ||
        component.kind_of?(Numeric) ||
        component.kind_of?(TrueClass) ||
        component.kind_of?(FalseClass)
      component = component.to_s
    else
      component = component.to_str
    end
  rescue TypeError, NoMethodError
    raise TypeError, "Can't convert #{component.class} into String."
  end if !component.is_a? String
  if ![String, Regexp].include?(character_class.class)
    raise TypeError,
      "Expected String or Regexp, got #{character_class.inspect}"
  end
  if character_class.kind_of?(String)
    character_class = /[^#{character_class}]/
  end
  # We can't perform regexps on invalid UTF sequences, but
  # here we need to, so switch to ASCII.
  component = component.dup
  component.force_encoding(Encoding::ASCII_8BIT)
  # Avoiding gsub! because there are edge cases with frozen strings
  component = component.gsub(character_class) do |char|
    SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE[char.ord]
  end
  if upcase_encoded.length > 0
    upcase_encoded_chars = upcase_encoded.bytes.map do |byte|
      SEQUENCE_ENCODING_TABLE[byte]
    end
    component = component.gsub(/%(#{upcase_encoded_chars.join('|')})/,
                               &:upcase)
  end
  return component
end

def self.form_encode(form_values, sort=false)

Returns:
  • (String) -

Parameters:
  • sort (TrueClass, FalseClass) --
  • form_values (#to_hash, #to_ary) --
def self.form_encode(form_values, sort=false)
  if form_values.respond_to?(:to_hash)
    form_values = form_values.to_hash.to_a
  elsif form_values.respond_to?(:to_ary)
    form_values = form_values.to_ary
  else
    raise TypeError, "Can't convert #{form_values.class} into Array."
  end
  form_values = form_values.inject([]) do |accu, (key, value)|
    if value.kind_of?(Array)
      value.each do |v|
        accu << [key.to_s, v.to_s]
      end
    else
      accu << [key.to_s, value.to_s]
    end
    accu
  end
  if sort
    # Useful for OAuth and optimizing caching systems
    form_values = form_values.sort
  end
  escaped_form_values = form_values.map do |(key, value)|
    # Line breaks are CRLF pairs
    [
      self.encode_component(
        key.gsub(/(\r\n|\n|\r)/, "\r\n"),
        CharacterClasses::UNRESERVED
      ).gsub("%20", "+"),
      self.encode_component(
        value.gsub(/(\r\n|\n|\r)/, "\r\n"),
        CharacterClasses::UNRESERVED
      ).gsub("%20", "+")
    ]
  end
  return escaped_form_values.map do |(key, value)|
    "#{key}=#{value}"
  end.join("&")
end

def self.form_unencode(encoded_value)

Returns:
  • (Array) -

Parameters:
  • encoded_value (String, #to_str) --
def self.form_unencode(encoded_value)
  if !encoded_value.respond_to?(:to_str)
    raise TypeError, "Can't convert #{encoded_value.class} into String."
  end
  encoded_value = encoded_value.to_str
  split_values = encoded_value.split("&").map do |pair|
    pair.split("=", 2)
  end
  return split_values.map do |(key, value)|
    [
      key ? self.unencode_component(
        key.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n") : nil,
      value ? (self.unencode_component(
        value.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n")) : nil
    ]
  end
end

def self.heuristic_parse(uri, hints={})

Returns:
  • (Addressable::URI) - The parsed URI.

Parameters:
  • hints (Hash) --
  • uri (String, Addressable::URI, #to_str) --
def self.heuristic_parse(uri, hints={})
  # If we were given nil, return nil.
  return nil unless uri
  # If a URI object is passed, just return itself.
  return uri.dup if uri.kind_of?(self)
  # If a URI object of the Ruby standard library variety is passed,
  # convert it to a string, then parse the string.
  # We do the check this way because we don't want to accidentally
  # cause a missing constant exception to be thrown.
  if uri.class.name =~ /^URI\b/
    uri = uri.to_s
  end
  unless uri.respond_to?(:to_str)
    raise TypeError, "Can't convert #{uri.class} into String."
  end
  # Otherwise, convert to a String
  uri = uri.to_str.dup.strip
  hints = {
    :scheme => "http"
  }.merge(hints)
  case uri
  when /^http:\//i
    uri.sub!(/^http:\/+/i, "http://")
  when /^https:\//i
    uri.sub!(/^https:\/+/i, "https://")
  when /^feed:\/+http:\//i
    uri.sub!(/^feed:\/+http:\/+/i, "feed:http://")
  when /^feed:\//i
    uri.sub!(/^feed:\/+/i, "feed://")
  when %r[^file:/{4}]i
    uri.sub!(%r[^file:/+]i, "file:////")
  when %r[^file://localhost/]i
    uri.sub!(%r[^file://localhost/+]i, "file:///")
  when %r[^file:/+]i
    uri.sub!(%r[^file:/+]i, "file:///")
  when /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
    uri.sub!(/^/, hints[:scheme] + "://")
  when /\A\d+\..*:\d+\z/
    uri = "#{hints[:scheme]}://#{uri}"
  end
  match = uri.match(URIREGEX)
  fragments = match.captures
  authority = fragments[3]
  if authority && authority.length > 0
    new_authority = authority.tr("\\", "/").gsub(" ", "%20")
    # NOTE: We want offset 4, not 3!
    offset = match.offset(4)
    uri = uri.dup
    uri[offset[0]...offset[1]] = new_authority
  end
  parsed = self.parse(uri)
  if parsed.scheme =~ /^[^\/?#\.]+\.[^\/?#]+$/
    parsed = self.parse(hints[:scheme] + "://" + uri)
  end
  if parsed.path.include?(".")
    if parsed.path[/\b@\b/]
      parsed.scheme = "mailto" unless parsed.scheme
    elsif new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1]
      parsed.defer_validation do
        new_path = parsed.path.sub(
          Regexp.new("^" + Regexp.escape(new_host)), EMPTY_STR)
        parsed.host = new_host
        parsed.path = new_path
        parsed.scheme = hints[:scheme] unless parsed.scheme
      end
    end
  end
  return parsed
end

def self.ip_based_schemes

Experimental RBS support (using type sampling data from the type_fusion project).

def self.ip_based_schemes: () -> String | String | String | String | String | String | String | String | String | String | String | String

This signature was generated using 88 samples from 2 applications.

//:@:/
use a similar URI form:
Returns an array of known ip-based schemes. These schemes typically
def self.ip_based_schemes
  return self.port_mapping.keys
end

def self.join(*uris)

Returns:
  • (Addressable::URI) - The joined URI.

Parameters:
  • *uris (String, Addressable::URI, #to_str) --
def self.join(*uris)
  uri_objects = uris.collect do |uri|
    unless uri.respond_to?(:to_str)
      raise TypeError, "Can't convert #{uri.class} into String."
    end
    uri.kind_of?(self) ? uri : self.parse(uri.to_str)
  end
  result = uri_objects.shift.dup
  uri_objects.each do |uri|
    result.join!(uri)
  end
  return result
end

def self.normalize_component(component, character_class=

Returns:
  • (String) - The normalized component.

Parameters:
  • leave_encoded (String) --
  • character_class (String, Regexp) --
  • component (String, #to_str) -- The URI component to encode.
def self.normalize_component(component, character_class=
    CharacterClasses::RESERVED + CharacterClasses::UNRESERVED,
    leave_encoded='')
  return nil if component.nil?
  begin
    component = component.to_str
  rescue NoMethodError, TypeError
    raise TypeError, "Can't convert #{component.class} into String."
  end if !component.is_a? String
  if ![String, Regexp].include?(character_class.class)
    raise TypeError,
      "Expected String or Regexp, got #{character_class.inspect}"
  end
  if character_class.kind_of?(String)
    leave_re = if leave_encoded.length > 0
      character_class = "#{character_class}%" unless character_class.include?('%')
      bytes = leave_encoded.bytes
      leave_encoded_pattern = bytes.map { |b| SEQUENCE_ENCODING_TABLE[b] }.join('|')
      "|%(?!#{leave_encoded_pattern}|#{leave_encoded_pattern.upcase})"
    end
    character_class = if leave_re
                        /[^#{character_class}]#{leave_re}/
                      else
                        /[^#{character_class}]/
                      end
  end
  # We can't perform regexps on invalid UTF sequences, but
  # here we need to, so switch to ASCII.
  component = component.dup
  component.force_encoding(Encoding::ASCII_8BIT)
  unencoded = self.unencode_component(component, String, leave_encoded)
  begin
    encoded = self.encode_component(
      unencoded.unicode_normalize(:nfc),
      character_class,
      leave_encoded
    )
  rescue ArgumentError
    encoded = self.encode_component(unencoded)
  end
  encoded.force_encoding(Encoding::UTF_8)
  return encoded
end

def self.normalize_path(path)

Returns:
  • (String) - The normalized path.

Parameters:
  • path (String) -- The path to normalize.
def self.normalize_path(path)
  # Section 5.2.4 of RFC 3986
  return if path.nil?
  normalized_path = path.dup
  loop do
    mod ||= normalized_path.gsub!(RULE_2A, SLASH)
    pair = normalized_path.match(RULE_2B_2C)
    if pair
      parent  = pair[1]
      current = pair[2]
    else
      parent  = nil
      current = nil
    end
    regexp = "/#{Regexp.escape(parent.to_s)}/\\.\\./|"
    regexp += "(/#{Regexp.escape(current.to_s)}/\\.\\.$)"
    if pair && ((parent != SELF_REF && parent != PARENT) ||
        (current != SELF_REF && current != PARENT))
      mod ||= normalized_path.gsub!(Regexp.new(regexp), SLASH)
    end
    mod ||= normalized_path.gsub!(RULE_2D, EMPTY_STR)
    # Non-standard, removes prefixed dotted segments from path.
    mod ||= normalized_path.gsub!(RULE_PREFIXED_PARENT, SLASH)
    break if mod.nil?
  end
  normalized_path
end

def self.normalized_encode(uri, return_type=String)

Returns:
  • (String, Addressable::URI) -

Parameters:
  • return_type (Class) --
  • uri (String, Addressable::URI, #to_str) --
def self.normalized_encode(uri, return_type=String)
  begin
    uri = uri.to_str
  rescue NoMethodError, TypeError
    raise TypeError, "Can't convert #{uri.class} into String."
  end if !uri.is_a? String
  if ![String, ::Addressable::URI].include?(return_type)
    raise TypeError,
      "Expected Class (String or Addressable::URI), " +
      "got #{return_type.inspect}"
  end
  uri_object = uri.kind_of?(self) ? uri : self.parse(uri)
  components = {
    :scheme => self.unencode_component(uri_object.scheme),
    :user => self.unencode_component(uri_object.user),
    :password => self.unencode_component(uri_object.password),
    :host => self.unencode_component(uri_object.host),
    :port => (uri_object.port.nil? ? nil : uri_object.port.to_s),
    :path => self.unencode_component(uri_object.path),
    :query => self.unencode_component(uri_object.query),
    :fragment => self.unencode_component(uri_object.fragment)
  }
  components.each do |key, value|
    if value != nil
      begin
        components[key] = value.to_str.unicode_normalize(:nfc)
      rescue ArgumentError
        # Likely a malformed UTF-8 character, skip unicode normalization
        components[key] = value.to_str
      end
    end
  end
  encoded_uri = Addressable::URI.new(
    :scheme => self.encode_component(components[:scheme],
      Addressable::URI::CharacterClasses::SCHEME),
    :user => self.encode_component(components[:user],
      Addressable::URI::CharacterClasses::UNRESERVED),
    :password => self.encode_component(components[:password],
      Addressable::URI::CharacterClasses::UNRESERVED),
    :host => components[:host],
    :port => components[:port],
    :path => self.encode_component(components[:path],
      Addressable::URI::CharacterClasses::PATH),
    :query => self.encode_component(components[:query],
      Addressable::URI::CharacterClasses::QUERY),
    :fragment => self.encode_component(components[:fragment],
      Addressable::URI::CharacterClasses::FRAGMENT)
  )
  if return_type == String
    return encoded_uri.to_s
  elsif return_type == ::Addressable::URI
    return encoded_uri
  end
end

def self.parse(uri)

Experimental RBS support (using type sampling data from the type_fusion project).

def self.parse: (String uri) -> Addressable::URI

This signature was generated using 100 samples from 2 applications.

Returns:
  • (Addressable::URI) - The parsed URI.

Parameters:
  • uri (String, Addressable::URI, #to_str) --
def self.parse(uri)
  # If we were given nil, return nil.
  return nil unless uri
  # If a URI object is passed, just return itself.
  return uri.dup if uri.kind_of?(self)
  # If a URI object of the Ruby standard library variety is passed,
  # convert it to a string, then parse the string.
  # We do the check this way because we don't want to accidentally
  # cause a missing constant exception to be thrown.
  if uri.class.name =~ /^URI\b/
    uri = uri.to_s
  end
  # Otherwise, convert to a String
  begin
    uri = uri.to_str
  rescue TypeError, NoMethodError
    raise TypeError, "Can't convert #{uri.class} into String."
  end unless uri.is_a?(String)
  # This Regexp supplied as an example in RFC 3986, and it works great.
  scan = uri.scan(URIREGEX)
  fragments = scan[0]
  scheme = fragments[1]
  authority = fragments[3]
  path = fragments[4]
  query = fragments[6]
  fragment = fragments[8]
  user = nil
  password = nil
  host = nil
  port = nil
  if authority != nil
    # The Regexp above doesn't split apart the authority.
    userinfo = authority[/^([^\[\]]*)@/, 1]
    if userinfo != nil
      user = userinfo.strip[/^([^:]*):?/, 1]
      password = userinfo.strip[/:(.*)$/, 1]
    end
    host = authority.sub(
      /^([^\[\]]*)@/, EMPTY_STR
    ).sub(
      /:([^:@\[\]]*?)$/, EMPTY_STR
    )
    port = authority[/:([^:@\[\]]*?)$/, 1]
    port = nil if port == EMPTY_STR
  end
  return new(
    :scheme => scheme,
    :user => user,
    :password => password,
    :host => host,
    :port => port,
    :path => path,
    :query => query,
    :fragment => fragment
  )
end

def self.port_mapping

Experimental RBS support (using type sampling data from the type_fusion project).

def self.port_mapping: () -> http | Integer | https | Integer | ftp | Integer | tftp | Integer | sftp | Integer | ssh | Integer | svn+ssh | Integer | telnet | Integer | nntp | Integer | gopher | Integer | wais | Integer | ldap | Integer | prospero | Integer

This signature was generated using 65 samples from 3 applications.

for better URI normalization.
numbers. Adding new schemes to this hash, as necessary, will allow
Returns a hash of common IP-based schemes and their default port
def self.port_mapping
  PORT_MAPPING
end

def self.unencode(uri, return_type=String, leave_encoded='')

Returns:
  • (String, Addressable::URI) -

Parameters:
  • leave_encoded (String) --
  • return_type (Class) --
  • uri (String, Addressable::URI, #to_str) --
def self.unencode(uri, return_type=String, leave_encoded='')
  return nil if uri.nil?
  begin
    uri = uri.to_str
  rescue NoMethodError, TypeError
    raise TypeError, "Can't convert #{uri.class} into String."
  end if !uri.is_a? String
  if ![String, ::Addressable::URI].include?(return_type)
    raise TypeError,
      "Expected Class (String or Addressable::URI), " +
      "got #{return_type.inspect}"
  end
  result = uri.gsub(/%[0-9a-f]{2}/i) do |sequence|
    c = sequence[1..3].to_i(16).chr
    c.force_encoding(sequence.encoding)
    leave_encoded.include?(c) ? sequence : c
  end
  result.force_encoding(Encoding::UTF_8)
  if return_type == String
    return result
  elsif return_type == ::Addressable::URI
    return ::Addressable::URI.parse(result)
  end
end

def ==(uri)

Returns:
  • (TrueClass, FalseClass) -

Parameters:
  • uri (Object) -- The URI to compare.
def ==(uri)
  return false unless uri.kind_of?(URI)
  return self.normalize.to_s == uri.normalize.to_s
end

def ===(uri)

Returns:
  • (TrueClass, FalseClass) -

Parameters:
  • uri (Object) -- The URI to compare.
def ===(uri)
  if uri.respond_to?(:normalize)
    uri_string = uri.normalize.to_s
  else
    begin
      uri_string = ::Addressable::URI.parse(uri).normalize.to_s
    rescue InvalidURIError, TypeError
      return false
    end
  end
  return self.normalize.to_s == uri_string
end

def absolute?

Returns:
  • (TrueClass, FalseClass) -
def absolute?
  return !relative?
end

def authority

Experimental RBS support (using type sampling data from the type_fusion project).

def authority: () -> String?

This signature was generated using 244 samples from 4 applications.

Returns:
  • (String) - The authority component.
def authority
  self.host && @authority ||= begin
    authority = String.new
    if self.userinfo != nil
      authority << "#{self.userinfo}@"
    end
    authority << self.host
    if self.port != nil
      authority << ":#{self.port}"
    end
    authority
  end
end

def authority=(new_authority)

Experimental RBS support (using type sampling data from the type_fusion project).

def authority=: (String new_authority) -> nil

This signature was generated using 33 samples from 2 applications.

Parameters:
  • new_authority (String, #to_str) -- The new authority component.
def authority=(new_authority)
  if new_authority
    if !new_authority.respond_to?(:to_str)
      raise TypeError, "Can't convert #{new_authority.class} into String."
    end
    new_authority = new_authority.to_str
    new_userinfo = new_authority[/^([^\[\]]*)@/, 1]
    if new_userinfo
      new_user = new_userinfo.strip[/^([^:]*):?/, 1]
      new_password = new_userinfo.strip[/:(.*)$/, 1]
    end
    new_host = new_authority.sub(
      /^([^\[\]]*)@/, EMPTY_STR
    ).sub(
      /:([^:@\[\]]*?)$/, EMPTY_STR
    )
    new_port =
      new_authority[/:([^:@\[\]]*?)$/, 1]
  end
  # Password assigned first to ensure validity in case of nil
  self.password = new_password
  self.user = new_user
  self.host = new_host
  self.port = new_port
  # Reset dependent values
  @userinfo = nil
  @normalized_userinfo = NONE
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def basename

Returns:
  • (String) - The path's basename.
def basename
  # Path cannot be nil
  return File.basename(self.path).sub(/;[^\/]*$/, EMPTY_STR)
end

def default_port

Returns:
  • (Integer) - The default port.
def default_port
  URI.port_mapping[self.scheme.strip.downcase] if self.scheme
end

def defer_validation

Experimental RBS support (using type sampling data from the type_fusion project).

def defer_validation: () -> nil

This signature was generated using 119 samples from 4 applications.

Parameters:
  • block (Proc) --
def defer_validation
  raise LocalJumpError, "No block given." unless block_given?
  @validation_deferred = true
  yield
  @validation_deferred = false
  validate
ensure
  @validation_deferred = false
end

def display_uri

Returns:
  • (Addressable::URI) - A URI suitable for display purposes.
def display_uri
  display_uri = self.normalize
  display_uri.host = ::Addressable::IDNA.to_unicode(display_uri.host)
  return display_uri
end

def domain

Addressable::URI.parse("http://www.example.co.uk").domain # => "example.co.uk"
@example

Returns the public suffix domain for this host.
#
def domain
  PublicSuffix.domain(self.host, ignore_private: true)
end

def dup

Returns:
  • (Addressable::URI) - The cloned URI.
def dup
  duplicated_uri = self.class.new(
    :scheme => self.scheme ? self.scheme.dup : nil,
    :user => self.user ? self.user.dup : nil,
    :password => self.password ? self.password.dup : nil,
    :host => self.host ? self.host.dup : nil,
    :port => self.port,
    :path => self.path ? self.path.dup : nil,
    :query => self.query ? self.query.dup : nil,
    :fragment => self.fragment ? self.fragment.dup : nil
  )
  return duplicated_uri
end

def empty?

Returns:
  • (TrueClass, FalseClass) -
def empty?
  return self.to_s.empty?
end

def encode_with(coder)

def encode_with(coder)
  instance_variables.each do |ivar|
    value = instance_variable_get(ivar)
    if value != NONE
      key = ivar.to_s.slice(1..-1)
      coder[key] = value
    end
  end
  nil
end

def eql?(uri)

Returns:
  • (TrueClass, FalseClass) -

Parameters:
  • uri (Object) -- The URI to compare.
def eql?(uri)
  return false unless uri.kind_of?(URI)
  return self.to_s == uri.to_s
end

def extname

Returns:
  • (String) - The path's extname.
def extname
  return nil unless self.path
  return File.extname(self.basename)
end

def force_utf8_encoding_if_needed(str)

Other tags:
    Api: - private
def force_utf8_encoding_if_needed(str)
  if str && str.encoding != Encoding::UTF_8
    str.force_encoding(Encoding::UTF_8)
  end
end

def fragment=(new_fragment)

Parameters:
  • new_fragment (String, #to_str) -- The new fragment component.
def fragment=(new_fragment)
  if new_fragment && !new_fragment.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_fragment.class} into String."
  end
  @fragment = new_fragment ? new_fragment.to_str : nil
  # Reset dependent values
  @normalized_fragment = NONE
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def freeze

Returns:
  • (Addressable::URI) - The frozen URI object.
def freeze
  self.normalized_scheme
  self.normalized_user
  self.normalized_password
  self.normalized_userinfo
  self.normalized_host
  self.normalized_port
  self.normalized_authority
  self.normalized_site
  self.normalized_path
  self.normalized_query
  self.normalized_fragment
  self.hash
  super
end

def hash

Returns:
  • (Integer) - A hash of the URI.
def hash
  @hash ||= self.to_s.hash * -1
end

def host=(new_host)

Experimental RBS support (using type sampling data from the type_fusion project).

def host=: (String new_host) -> nil

This signature was generated using 75 samples from 3 applications.

Parameters:
  • new_host (String, #to_str) -- The new host component.
def host=(new_host)
  if new_host && !new_host.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_host.class} into String."
  end
  @host = new_host ? new_host.to_str : nil
  # Reset dependent values
  @authority = nil
  @normalized_host = nil
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def hostname

Returns:
  • (String) - The hostname for this URI.

Other tags:
    See: Addressable::URI#host -
def hostname
  v = self.host
  /\A\[(.*)\]\z/ =~ v ? $1 : v
end

def hostname=(new_hostname)

Parameters:
  • new_hostname (String, #to_str) -- The new hostname for this URI.

Other tags:
    See: Addressable::URI#host= -
def hostname=(new_hostname)
  if new_hostname &&
      (new_hostname.respond_to?(:ipv4?) || new_hostname.respond_to?(:ipv6?))
    new_hostname = new_hostname.to_s
  elsif new_hostname && !new_hostname.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_hostname.class} into String."
  end
  v = new_hostname ? new_hostname.to_str : nil
  v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v
  self.host = v
end

def inferred_port

Returns:
  • (Integer) - The inferred port component.
def inferred_port
  if self.port.to_i == 0
    self.default_port
  else
    self.port.to_i
  end
end

def init_with(coder)

def init_with(coder)
  reset_ivs
  coder.map.each do |key, value|
    instance_variable_set("@#{key}", value)
  end
  nil
end

def initialize(options={})

Experimental RBS support (using type sampling data from the type_fusion project).

def initialize: (?(scheme | String | authority | String | path | String | query | NilClass | fragment | NilClass | scheme | String | user | NilClass | password | NilClass | host | String | port | NilClass | path | String | query | NilClass | fragment | NilClass | scheme | NilClass | user | NilClass | password | NilClass | host | NilClass | port | NilClass | path | String | query | NilClass | fragment | NilClass) options) -> void

This signature was generated using 128 samples from 3 applications.

Returns:
  • (Addressable::URI) - The constructed URI object.

Options Hash: (**[String,)
  • #to_str (]) -- to_str] fragment The fragment component.
  • #to_str (]) -- to_str] query The query component.
  • #to_str (]) -- to_str] path The path component.
  • #to_str (]) -- to_str] authority
  • #to_str (]) -- to_str] port The port component.
  • #to_str (]) -- to_str] host The host component.
  • #to_str (]) -- to_str] userinfo
  • #to_str (]) -- to_str] password The password component.
  • #to_str (]) -- to_str] user The user component.
  • #to_str (]) -- to_str] scheme The scheme component.
def initialize(options={})
  if options.has_key?(:authority)
    if (options.keys & [:userinfo, :user, :password, :host, :port]).any?
      raise ArgumentError,
        "Cannot specify both an authority and any of the components " +
        "within the authority."
    end
  end
  if options.has_key?(:userinfo)
    if (options.keys & [:user, :password]).any?
      raise ArgumentError,
        "Cannot specify both a userinfo and either the user or password."
    end
  end
  reset_ivs
  defer_validation do
    # Bunch of crazy logic required because of the composite components
    # like userinfo and authority.
    self.scheme = options[:scheme] if options[:scheme]
    self.user = options[:user] if options[:user]
    self.password = options[:password] if options[:password]
    self.userinfo = options[:userinfo] if options[:userinfo]
    self.host = options[:host] if options[:host]
    self.port = options[:port] if options[:port]
    self.authority = options[:authority] if options[:authority]
    self.path = options[:path] if options[:path]
    self.query = options[:query] if options[:query]
    self.query_values = options[:query_values] if options[:query_values]
    self.fragment = options[:fragment] if options[:fragment]
  end
  to_s # force path validation
end

def inspect

Returns:
  • (String) - The URI object's state, as a String.
def inspect
  sprintf("#<%s:%#0x URI:%s>", URI.to_s, self.object_id, self.to_s)
end

def ip_based?

Experimental RBS support (using type sampling data from the type_fusion project).

def ip_based?: () -> true

This signature was generated using 62 samples from 3 applications.

Returns:
  • (TrueClass, FalseClass) -
def ip_based?
  if self.scheme
    return URI.ip_based_schemes.include?(
      self.scheme.strip.downcase)
  end
  return false
end

def join(uri)

Returns:
  • (Addressable::URI) - The joined URI.

Parameters:
  • The (String, Addressable::URI, #to_str) -- URI to join with.
def join(uri)
  if !uri.respond_to?(:to_str)
    raise TypeError, "Can't convert #{uri.class} into String."
  end
  if !uri.kind_of?(URI)
    # Otherwise, convert to a String, then parse.
    uri = URI.parse(uri.to_str)
  end
  if uri.to_s.empty?
    return self.dup
  end
  joined_scheme = nil
  joined_user = nil
  joined_password = nil
  joined_host = nil
  joined_port = nil
  joined_path = nil
  joined_query = nil
  joined_fragment = nil
  # Section 5.2.2 of RFC 3986
  if uri.scheme != nil
    joined_scheme = uri.scheme
    joined_user = uri.user
    joined_password = uri.password
    joined_host = uri.host
    joined_port = uri.port
    joined_path = URI.normalize_path(uri.path)
    joined_query = uri.query
  else
    if uri.authority != nil
      joined_user = uri.user
      joined_password = uri.password
      joined_host = uri.host
      joined_port = uri.port
      joined_path = URI.normalize_path(uri.path)
      joined_query = uri.query
    else
      if uri.path == nil || uri.path.empty?
        joined_path = self.path
        if uri.query != nil
          joined_query = uri.query
        else
          joined_query = self.query
        end
      else
        if uri.path[0..0] == SLASH
          joined_path = URI.normalize_path(uri.path)
        else
          base_path = self.path.dup
          base_path = EMPTY_STR if base_path == nil
          base_path = URI.normalize_path(base_path)
          # Section 5.2.3 of RFC 3986
          #
          # Removes the right-most path segment from the base path.
          if base_path.include?(SLASH)
            base_path.sub!(/\/[^\/]+$/, SLASH)
          else
            base_path = EMPTY_STR
          end
          # If the base path is empty and an authority segment has been
          # defined, use a base path of SLASH
          if base_path.empty? && self.authority != nil
            base_path = SLASH
          end
          joined_path = URI.normalize_path(base_path + uri.path)
        end
        joined_query = uri.query
      end
      joined_user = self.user
      joined_password = self.password
      joined_host = self.host
      joined_port = self.port
    end
    joined_scheme = self.scheme
  end
  joined_fragment = uri.fragment
  return self.class.new(
    :scheme => joined_scheme,
    :user => joined_user,
    :password => joined_password,
    :host => joined_host,
    :port => joined_port,
    :path => joined_path,
    :query => joined_query,
    :fragment => joined_fragment
  )
end

def join!(uri)

Other tags:
    See: Addressable::URI#join -

Returns:
  • (Addressable::URI) - The joined URI.

Parameters:
  • The (String, Addressable::URI, #to_str) -- URI to join with.
def join!(uri)
  replace_self(self.join(uri))
end

def merge(hash)

Other tags:
    See: Hash#merge -

Returns:
  • (Addressable::URI) - The merged URI.

Parameters:
  • The (Hash, Addressable::URI, #to_hash) -- components to merge with.
def merge(hash)
  unless hash.respond_to?(:to_hash)
    raise TypeError, "Can't convert #{hash.class} into Hash."
  end
  hash = hash.to_hash
  if hash.has_key?(:authority)
    if (hash.keys & [:userinfo, :user, :password, :host, :port]).any?
      raise ArgumentError,
        "Cannot specify both an authority and any of the components " +
        "within the authority."
    end
  end
  if hash.has_key?(:userinfo)
    if (hash.keys & [:user, :password]).any?
      raise ArgumentError,
        "Cannot specify both a userinfo and either the user or password."
    end
  end
  uri = self.class.new
  uri.defer_validation do
    # Bunch of crazy logic required because of the composite components
    # like userinfo and authority.
    uri.scheme =
      hash.has_key?(:scheme) ? hash[:scheme] : self.scheme
    if hash.has_key?(:authority)
      uri.authority =
        hash.has_key?(:authority) ? hash[:authority] : self.authority
    end
    if hash.has_key?(:userinfo)
      uri.userinfo =
        hash.has_key?(:userinfo) ? hash[:userinfo] : self.userinfo
    end
    if !hash.has_key?(:userinfo) && !hash.has_key?(:authority)
      uri.user =
        hash.has_key?(:user) ? hash[:user] : self.user
      uri.password =
        hash.has_key?(:password) ? hash[:password] : self.password
    end
    if !hash.has_key?(:authority)
      uri.host =
        hash.has_key?(:host) ? hash[:host] : self.host
      uri.port =
        hash.has_key?(:port) ? hash[:port] : self.port
    end
    uri.path =
      hash.has_key?(:path) ? hash[:path] : self.path
    uri.query =
      hash.has_key?(:query) ? hash[:query] : self.query
    uri.fragment =
      hash.has_key?(:fragment) ? hash[:fragment] : self.fragment
  end
  return uri
end

def merge!(uri)

Other tags:
    See: Addressable::URI#merge -

Returns:
  • (Addressable::URI) - The merged URI.

Parameters:
  • The (Hash, Addressable::URI, #to_hash) -- components to merge with.
def merge!(uri)
  replace_self(self.merge(uri))
end

def normalize

Returns:
  • (Addressable::URI) - The normalized URI.
def normalize
  # This is a special exception for the frequently misused feed
  # URI scheme.
  if normalized_scheme == "feed"
    if self.to_s =~ /^feed:\/*http:\/*/
      return URI.parse(
        self.to_s[/^feed:\/*(http:\/*.*)/, 1]
      ).normalize
    end
  end
  return self.class.new(
    :scheme => normalized_scheme,
    :authority => normalized_authority,
    :path => normalized_path,
    :query => normalized_query,
    :fragment => normalized_fragment
  )
end

def normalize!

Other tags:
    See: Addressable::URI#normalize -

Returns:
  • (Addressable::URI) - The normalized URI.
def normalize!
  replace_self(self.normalize)
end

def normalized_authority

Returns:
  • (String) - The authority component, normalized.
def normalized_authority
  return nil unless self.authority
  @normalized_authority ||= begin
    authority = String.new
    if self.normalized_userinfo != nil
      authority << "#{self.normalized_userinfo}@"
    end
    authority << self.normalized_host
    if self.normalized_port != nil
      authority << ":#{self.normalized_port}"
    end
    authority
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_authority)
  @normalized_authority
end

def normalized_fragment

Returns:
  • (String) - The fragment component, normalized.
def normalized_fragment
  return nil unless self.fragment
  return @normalized_fragment unless @normalized_fragment == NONE
  @normalized_fragment = begin
    component = Addressable::URI.normalize_component(
      self.fragment,
      Addressable::URI::NormalizeCharacterClasses::FRAGMENT
    )
    component == "" ? nil : component
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_fragment)
  @normalized_fragment
end

def normalized_host

Returns:
  • (String) - The host component, normalized.
def normalized_host
  return nil unless self.host
  @normalized_host ||= begin
    if !self.host.strip.empty?
      result = ::Addressable::IDNA.to_ascii(
        URI.unencode_component(self.host.strip.downcase)
      )
      if result =~ /[^\.]\.$/
        # Single trailing dots are unnecessary.
        result = result[0...-1]
      end
      result = Addressable::URI.normalize_component(
        result,
        NormalizeCharacterClasses::HOST
      )
      result
    else
      EMPTY_STR.dup
    end
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_host)
  @normalized_host
end

def normalized_password

Returns:
  • (String) - The password component, normalized.
def normalized_password
  return nil unless self.password
  return @normalized_password unless @normalized_password == NONE
  @normalized_password = begin
    if self.normalized_scheme =~ /https?/ && self.password.strip.empty? &&
        (!self.user || self.user.strip.empty?)
      nil
    else
      Addressable::URI.normalize_component(
        self.password.strip,
        Addressable::URI::NormalizeCharacterClasses::UNRESERVED
      )
    end
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_password)
  @normalized_password
end

def normalized_path

Returns:
  • (String) - The path component, normalized.
def normalized_path
  @normalized_path ||= begin
    path = self.path.to_s
    if self.scheme == nil && path =~ NORMPATH
      # Relative paths with colons in the first segment are ambiguous.
      path = path.sub(":", "%2F")
    end
    # String#split(delimeter, -1) uses the more strict splitting behavior
    # found by default in Python.
    result = path.strip.split(SLASH, -1).map do |segment|
      Addressable::URI.normalize_component(
        segment,
        Addressable::URI::NormalizeCharacterClasses::PCHAR
      )
    end.join(SLASH)
    result = URI.normalize_path(result)
    if result.empty? &&
        ["http", "https", "ftp", "tftp"].include?(self.normalized_scheme)
      result = SLASH.dup
    end
    result
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_path)
  @normalized_path
end

def normalized_port

Returns:
  • (Integer) - The port component, normalized.
def normalized_port
  return nil unless self.port
  return @normalized_port unless @normalized_port == NONE
  @normalized_port = begin
    if URI.port_mapping[self.normalized_scheme] == self.port
      nil
    else
      self.port
    end
  end
end

def normalized_query(*flags)

Returns:
  • (String) - The query component, normalized.
def normalized_query(*flags)
  return nil unless self.query
  return @normalized_query unless @normalized_query == NONE
  @normalized_query = begin
    modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup
    # Make sure possible key-value pair delimiters are escaped.
    modified_query_class.sub!("\\&", "").sub!("\\;", "")
    pairs = (query || "").split("&", -1)
    pairs.delete_if(&:empty?).uniq! if flags.include?(:compacted)
    pairs.sort! if flags.include?(:sorted)
    component = pairs.map do |pair|
      Addressable::URI.normalize_component(
        pair,
        Addressable::URI::NormalizeCharacterClasses::QUERY,
        "+"
      )
    end.join("&")
    component == "" ? nil : component
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_query)
  @normalized_query
end

def normalized_scheme

Returns:
  • (String) - The scheme component, normalized.
def normalized_scheme
  return nil unless self.scheme
  if @normalized_scheme == NONE
    @normalized_scheme = if self.scheme =~ /^\s*ssh\+svn\s*$/i
      "svn+ssh".dup
    else
      Addressable::URI.normalize_component(
        self.scheme.strip.downcase,
        Addressable::URI::NormalizeCharacterClasses::SCHEME
      )
    end
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_scheme)
  @normalized_scheme
end

def normalized_site

Returns:
  • (String) - The normalized components that identify a site.
def normalized_site
  return nil unless self.site
  @normalized_site ||= begin
    site_string = "".dup
    if self.normalized_scheme != nil
      site_string << "#{self.normalized_scheme}:"
    end
    if self.normalized_authority != nil
      site_string << "//#{self.normalized_authority}"
    end
    site_string
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_site)
  @normalized_site
end

def normalized_user

Returns:
  • (String) - The user component, normalized.
def normalized_user
  return nil unless self.user
  return @normalized_user unless @normalized_user == NONE
  @normalized_user = begin
    if normalized_scheme =~ /https?/ && self.user.strip.empty? &&
        (!self.password || self.password.strip.empty?)
      nil
    else
      Addressable::URI.normalize_component(
        self.user.strip,
        Addressable::URI::NormalizeCharacterClasses::UNRESERVED
      )
    end
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_user)
  @normalized_user
end

def normalized_userinfo

Returns:
  • (String) - The userinfo component, normalized.
def normalized_userinfo
  return nil unless self.userinfo
  return @normalized_userinfo unless @normalized_userinfo == NONE
  @normalized_userinfo = begin
    current_user = self.normalized_user
    current_password = self.normalized_password
    if !current_user && !current_password
      nil
    elsif current_user && current_password
      "#{current_user}:#{current_password}".dup
    elsif current_user && !current_password
      "#{current_user}".dup
    end
  end
  # All normalized values should be UTF-8
  force_utf8_encoding_if_needed(@normalized_userinfo)
  @normalized_userinfo
end

def omit(*components)

Returns:
  • (Addressable::URI) - The URI with components omitted.

Parameters:
  • *components (Symbol) -- The components to be omitted.
def omit(*components)
  invalid_components = components - [
    :scheme, :user, :password, :userinfo, :host, :port, :authority,
    :path, :query, :fragment
  ]
  unless invalid_components.empty?
    raise ArgumentError,
      "Invalid component names: #{invalid_components.inspect}."
  end
  duplicated_uri = self.dup
  duplicated_uri.defer_validation do
    components.each do |component|
      duplicated_uri.send((component.to_s + "=").to_sym, nil)
    end
    duplicated_uri.user = duplicated_uri.normalized_user
  end
  duplicated_uri
end

def omit!(*components)

Other tags:
    See: Addressable::URI#omit -

Returns:
  • (Addressable::URI) - The URI with components omitted.

Parameters:
  • *components (Symbol) -- The components to be omitted.
def omit!(*components)
  replace_self(self.omit(*components))
end

def origin

Returns:
  • (String) - The serialized origin.
def origin
  if self.scheme && self.authority
    if self.normalized_port
      "#{self.normalized_scheme}://#{self.normalized_host}" +
      ":#{self.normalized_port}"
    else
      "#{self.normalized_scheme}://#{self.normalized_host}"
    end
  else
    "null"
  end
end

def origin=(new_origin)

Parameters:
  • new_origin (String, #to_str) -- The new origin component.
def origin=(new_origin)
  if new_origin
    if !new_origin.respond_to?(:to_str)
      raise TypeError, "Can't convert #{new_origin.class} into String."
    end
    new_origin = new_origin.to_str
    new_scheme = new_origin[/^([^:\/?#]+):\/\//, 1]
    unless new_scheme
      raise InvalidURIError, 'An origin cannot omit the scheme.'
    end
    new_host = new_origin[/:\/\/([^\/?#:]+)/, 1]
    unless new_host
      raise InvalidURIError, 'An origin cannot omit the host.'
    end
    new_port = new_origin[/:([^:@\[\]\/]*?)$/, 1]
  end
  self.scheme = new_scheme
  self.host = new_host
  self.port = new_port
  self.userinfo = nil
  # Reset dependent values
  @userinfo = nil
  @normalized_userinfo = NONE
  @authority = nil
  @normalized_authority = nil
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def password=(new_password)

Experimental RBS support (using type sampling data from the type_fusion project).

def password=: (nil new_password) -> nil

This signature was generated using 37 samples from 3 applications.

Parameters:
  • new_password (String, #to_str) -- The new password component.
def password=(new_password)
  if new_password && !new_password.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_password.class} into String."
  end
  @password = new_password ? new_password.to_str : nil
  # You can't have a nil user with a non-nil password
  if @password != nil
    self.user = EMPTY_STR if user.nil?
  end
  # Reset dependent values
  @userinfo = nil
  @normalized_userinfo = NONE
  @authority = nil
  @normalized_password = NONE
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def path=(new_path)

Experimental RBS support (using type sampling data from the type_fusion project).

def path=: (String new_path) -> nil

This signature was generated using 138 samples from 4 applications.

Parameters:
  • new_path (String, #to_str) -- The new path component.
def path=(new_path)
  if new_path && !new_path.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_path.class} into String."
  end
  @path = (new_path || EMPTY_STR).to_str
  if !@path.empty? && @path[0..0] != SLASH && host != nil
    @path = "/#{@path}"
  end
  # Reset dependent values
  @normalized_path = nil
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def port=(new_port)

Experimental RBS support (using type sampling data from the type_fusion project).

def port=: (nil new_port) -> nil

This signature was generated using 33 samples from 1 application.

Parameters:
  • new_port (String, Integer, #to_s) -- The new port component.
def port=(new_port)
  if new_port != nil && new_port.respond_to?(:to_str)
    new_port = Addressable::URI.unencode_component(new_port.to_str)
  end
  if new_port.respond_to?(:valid_encoding?) && !new_port.valid_encoding?
    raise InvalidURIError, "Invalid encoding in port"
  end
  if new_port != nil && !(new_port.to_s =~ /^\d+$/)
    raise InvalidURIError,
      "Invalid port number: #{new_port.inspect}"
  end
  @port = new_port.to_s.to_i
  @port = nil if @port == 0
  # Reset dependent values
  @authority = nil
  @normalized_port = NONE
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def query=(new_query)

Parameters:
  • new_query (String, #to_str) -- The new query component.
def query=(new_query)
  if new_query && !new_query.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_query.class} into String."
  end
  @query = new_query ? new_query.to_str : nil
  # Reset dependent values
  @normalized_query = NONE
  remove_composite_values
end

def query_values(return_type=Hash)

Returns:
  • (Hash, Array, nil) - The query string parsed as a Hash or Array

Parameters:
  • return_type (Class) -- The return type desired. Value must be either
def query_values(return_type=Hash)
  empty_accumulator = Array == return_type ? [] : {}
  if return_type != Hash && return_type != Array
    raise ArgumentError, "Invalid return type. Must be Hash or Array."
  end
  return nil if self.query == nil
  split_query = self.query.split("&").map do |pair|
    pair.split("=", 2) if pair && !pair.empty?
  end.compact
  return split_query.inject(empty_accumulator.dup) do |accu, pair|
    # I'd rather use key/value identifiers instead of array lookups,
    # but in this case I really want to maintain the exact pair structure,
    # so it's best to make all changes in-place.
    pair[0] = URI.unencode_component(pair[0])
    if pair[1].respond_to?(:to_str)
      value = pair[1].to_str
      # I loathe the fact that I have to do this. Stupid HTML 4.01.
      # Treating '+' as a space was just an unbelievably bad idea.
      # There was nothing wrong with '%20'!
      # If it ain't broke, don't fix it!
      value = value.tr("+", " ") if ["http", "https", nil].include?(scheme)
      pair[1] = URI.unencode_component(value)
    end
    if return_type == Hash
      accu[pair[0]] = pair[1]
    else
      accu << pair
    end
    accu
  end
end

def query_values=(new_query_values)

Parameters:
  • new_query_values (Hash, #to_hash, Array) -- The new query values.
def query_values=(new_query_values)
  if new_query_values == nil
    self.query = nil
    return nil
  end
  if !new_query_values.is_a?(Array)
    if !new_query_values.respond_to?(:to_hash)
      raise TypeError,
        "Can't convert #{new_query_values.class} into Hash."
    end
    new_query_values = new_query_values.to_hash
    new_query_values = new_query_values.map do |key, value|
      key = key.to_s if key.kind_of?(Symbol)
      [key, value]
    end
    # Useful default for OAuth and caching.
    # Only to be used for non-Array inputs. Arrays should preserve order.
    new_query_values.sort!
  end
  # new_query_values have form [['key1', 'value1'], ['key2', 'value2']]
  buffer = "".dup
  new_query_values.each do |key, value|
    encoded_key = URI.encode_component(
      key, CharacterClasses::UNRESERVED
    )
    if value == nil
      buffer << "#{encoded_key}&"
    elsif value.kind_of?(Array)
      value.each do |sub_value|
        encoded_value = URI.encode_component(
          sub_value, CharacterClasses::UNRESERVED
        )
        buffer << "#{encoded_key}=#{encoded_value}&"
      end
    else
      encoded_value = URI.encode_component(
        value, CharacterClasses::UNRESERVED
      )
      buffer << "#{encoded_key}=#{encoded_value}&"
    end
  end
  self.query = buffer.chop
end

def relative?

Returns:
  • (TrueClass, FalseClass) -
def relative?
  return self.scheme.nil?
end

def remove_composite_values

Experimental RBS support (using type sampling data from the type_fusion project).

def remove_composite_values: () -> nil

This signature was generated using 434 samples from 4 applications.

Other tags:
    Api: - private
def remove_composite_values
  @uri_string = nil
  @hash = nil
end

def replace_self(uri)

Returns:
  • (Addressable::URI) - self.

Parameters:
  • uri (Addressable::URI) -- The URI to replace self with.
def replace_self(uri)
  # Reset dependent values
  reset_ivs
  @scheme = uri.scheme
  @user = uri.user
  @password = uri.password
  @host = uri.host
  @port = uri.port
  @path = uri.path
  @query = uri.query
  @fragment = uri.fragment
  return self
end

def request_uri

Returns:
  • (String) - The request URI required for an HTTP request.
def request_uri
  return nil if self.absolute? && self.scheme !~ /^https?$/i
  return (
    (!self.path.empty? ? self.path : SLASH) +
    (self.query ? "?#{self.query}" : EMPTY_STR)
  )
end

def request_uri=(new_request_uri)

Parameters:
  • new_request_uri (String, #to_str) -- The new HTTP request URI.
def request_uri=(new_request_uri)
  if !new_request_uri.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_request_uri.class} into String."
  end
  if self.absolute? && self.scheme !~ /^https?$/i
    raise InvalidURIError,
      "Cannot set an HTTP request URI for a non-HTTP URI."
  end
  new_request_uri = new_request_uri.to_str
  path_component = new_request_uri[/^([^\?]*)\??(?:.*)$/, 1]
  query_component = new_request_uri[/^(?:[^\?]*)\?(.*)$/, 1]
  path_component = path_component.to_s
  path_component = (!path_component.empty? ? path_component : SLASH)
  self.path = path_component
  self.query = query_component
  # Reset dependent values
  remove_composite_values
end

def reset_ivs

Experimental RBS support (using type sampling data from the type_fusion project).

def reset_ivs: () -> nil

This signature was generated using 127 samples from 4 applications.

Other tags:
    Api: - private
def reset_ivs
  @scheme = nil
  @user = nil
  @normalized_scheme = NONE
  @normalized_user = NONE
  @uri_string = nil
  @hash = nil
  @userinfo = nil
  @normalized_userinfo = NONE
  @authority = nil
  @password = nil
  @normalized_authority = nil
  @port = nil
  @normalized_password = NONE
  @host = nil
  @normalized_host = nil
  @normalized_port = NONE
  @path = EMPTY_STR
  @normalized_path = nil
  @normalized_query = NONE
  @fragment = nil
  @normalized_fragment = NONE
  @query = nil
end

def route_from(uri)

Returns:
  • (Addressable::URI) -

Parameters:
  • uri (String, Addressable::URI, #to_str) -- The URI to route from.
def route_from(uri)
  uri = URI.parse(uri).normalize
  normalized_self = self.normalize
  if normalized_self.relative?
    raise ArgumentError, "Expected absolute URI, got: #{self.to_s}"
  end
  if uri.relative?
    raise ArgumentError, "Expected absolute URI, got: #{uri.to_s}"
  end
  if normalized_self == uri
    return Addressable::URI.parse("##{normalized_self.fragment}")
  end
  components = normalized_self.to_hash
  if normalized_self.scheme == uri.scheme
    components[:scheme] = nil
    if normalized_self.authority == uri.authority
      components[:user] = nil
      components[:password] = nil
      components[:host] = nil
      components[:port] = nil
      if normalized_self.path == uri.path
        components[:path] = nil
        if normalized_self.query == uri.query
          components[:query] = nil
        end
      else
        if uri.path != SLASH and components[:path]
          self_splitted_path = split_path(components[:path])
          uri_splitted_path = split_path(uri.path)
          self_dir = self_splitted_path.shift
          uri_dir = uri_splitted_path.shift
          while !self_splitted_path.empty? && !uri_splitted_path.empty? and self_dir == uri_dir
            self_dir = self_splitted_path.shift
            uri_dir = uri_splitted_path.shift
          end
          components[:path] = (uri_splitted_path.fill('..') + [self_dir] + self_splitted_path).join(SLASH)
        end
      end
    end
  end
  # Avoid network-path references.
  if components[:host] != nil
    components[:scheme] = normalized_self.scheme
  end
  return Addressable::URI.new(
    :scheme => components[:scheme],
    :user => components[:user],
    :password => components[:password],
    :host => components[:host],
    :port => components[:port],
    :path => components[:path],
    :query => components[:query],
    :fragment => components[:fragment]
  )
end

def route_to(uri)

Returns:
  • (Addressable::URI) -

Parameters:
  • uri (String, Addressable::URI, #to_str) -- The URI to route to.
def route_to(uri)
  return URI.parse(uri).route_from(self)
end

def scheme=(new_scheme)

Experimental RBS support (using type sampling data from the type_fusion project).

def scheme=: (String new_scheme) -> nil

This signature was generated using 66 samples from 3 applications.

Parameters:
  • new_scheme (String, #to_str) -- The new scheme component.
def scheme=(new_scheme)
  if new_scheme && !new_scheme.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_scheme.class} into String."
  elsif new_scheme
    new_scheme = new_scheme.to_str
  end
  if new_scheme && new_scheme !~ /\A[a-z][a-z0-9\.\+\-]*\z/i
    raise InvalidURIError, "Invalid scheme format: '#{new_scheme}'"
  end
  @scheme = new_scheme
  @scheme = nil if @scheme.to_s.strip.empty?
  # Reset dependent values
  @normalized_scheme = NONE
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def site

Returns:
  • (String) - The components that identify a site.
def site
  (self.scheme || self.authority) && @site ||= begin
    site_string = "".dup
    site_string << "#{self.scheme}:" if self.scheme != nil
    site_string << "//#{self.authority}" if self.authority != nil
    site_string
  end
end

def site=(new_site)

Parameters:
  • new_site (String, #to_str) -- The new site value.
def site=(new_site)
  if new_site
    if !new_site.respond_to?(:to_str)
      raise TypeError, "Can't convert #{new_site.class} into String."
    end
    new_site = new_site.to_str
    # These two regular expressions derived from the primary parsing
    # expression
    self.scheme = new_site[/^(?:([^:\/?#]+):)?(?:\/\/(?:[^\/?#]*))?$/, 1]
    self.authority = new_site[
      /^(?:(?:[^:\/?#]+):)?(?:\/\/([^\/?#]*))?$/, 1
    ]
  else
    self.scheme = nil
    self.authority = nil
  end
end

def split_path(path)

Returns:
  • (Array) - An array of parts of path.

Parameters:
  • path (String) -- The path to split.
def split_path(path)
  splitted = path.split(SLASH)
  splitted << EMPTY_STR if path.end_with? SLASH
  splitted
end

def tld

Addressable::URI.parse("http://www.example.co.uk").tld # => "co.uk"
@example

Returns the top-level domain for this host.
#
def tld
  PublicSuffix.parse(self.host, ignore_private: true).tld
end

def tld=(new_tld)

Parameters:
  • new_tld (String, #to_str) -- The new top-level domain.
def tld=(new_tld)
  replaced_tld = host.sub(/#{tld}\z/, new_tld)
  self.host = PublicSuffix::Domain.new(replaced_tld).to_s
end

def to_hash

Returns:
  • (Hash) - The URI as a Hash of components.
def to_hash
  return {
    :scheme => self.scheme,
    :user => self.user,
    :password => self.password,
    :host => self.host,
    :port => self.port,
    :path => self.path,
    :query => self.query,
    :fragment => self.fragment
  }
end

def to_s

Experimental RBS support (using type sampling data from the type_fusion project).

def to_s: () -> String

This signature was generated using 181 samples from 4 applications.

Returns:
  • (String) - The URI's String representation.
def to_s
  if self.scheme == nil && self.path != nil && !self.path.empty? &&
      self.path =~ NORMPATH
    raise InvalidURIError,
      "Cannot assemble URI string with ambiguous path: '#{self.path}'"
  end
  @uri_string ||= begin
    uri_string = String.new
    uri_string << "#{self.scheme}:" if self.scheme != nil
    uri_string << "//#{self.authority}" if self.authority != nil
    uri_string << self.path.to_s
    uri_string << "?#{self.query}" if self.query != nil
    uri_string << "##{self.fragment}" if self.fragment != nil
    uri_string.force_encoding(Encoding::UTF_8)
    uri_string
  end
end

def user=(new_user)

Experimental RBS support (using type sampling data from the type_fusion project).

def user=: (nil new_user) -> nil

This signature was generated using 47 samples from 2 applications.

Parameters:
  • new_user (String, #to_str) -- The new user component.
def user=(new_user)
  if new_user && !new_user.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_user.class} into String."
  end
  @user = new_user ? new_user.to_str : nil
  # You can't have a nil user with a non-nil password
  if password != nil
    @user = EMPTY_STR unless user
  end
  # Reset dependent values
  @userinfo = nil
  @normalized_userinfo = NONE
  @authority = nil
  @normalized_user = NONE
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def userinfo

Experimental RBS support (using type sampling data from the type_fusion project).

def userinfo: () -> nil

This signature was generated using 72 samples from 2 applications.

Returns:
  • (String) - The userinfo component.
def userinfo
  current_user = self.user
  current_password = self.password
  (current_user || current_password) && @userinfo ||= begin
    if current_user && current_password
      "#{current_user}:#{current_password}"
    elsif current_user && !current_password
      "#{current_user}"
    end
  end
end

def userinfo=(new_userinfo)

Parameters:
  • new_userinfo (String, #to_str) -- The new userinfo component.
def userinfo=(new_userinfo)
  if new_userinfo && !new_userinfo.respond_to?(:to_str)
    raise TypeError, "Can't convert #{new_userinfo.class} into String."
  end
  new_user, new_password = if new_userinfo
    [
      new_userinfo.to_str.strip[/^(.*):/, 1],
      new_userinfo.to_str.strip[/:(.*)$/, 1]
    ]
  else
    [nil, nil]
  end
  # Password assigned first to ensure validity in case of nil
  self.password = new_password
  self.user = new_user
  # Reset dependent values
  @authority = nil
  remove_composite_values
  # Ensure we haven't created an invalid URI
  validate()
end

def validate

Experimental RBS support (using type sampling data from the type_fusion project).

def validate: () -> nil

This signature was generated using 548 samples from 4 applications.

Ensures that the URI is valid.
#
def validate
  return if !!@validation_deferred
  if self.scheme != nil && self.ip_based? &&
      (self.host == nil || self.host.empty?) &&
      (self.path == nil || self.path.empty?)
    raise InvalidURIError,
      "Absolute URI missing hierarchical segment: '#{self.to_s}'"
  end
  if self.host == nil
    if self.port != nil ||
        self.user != nil ||
        self.password != nil
      raise InvalidURIError, "Hostname not supplied: '#{self.to_s}'"
    end
  end
  if self.path != nil && !self.path.empty? && self.path[0..0] != SLASH &&
      self.authority != nil
    raise InvalidURIError,
      "Cannot have a relative path with an authority set: '#{self.to_s}'"
  end
  if self.path != nil && !self.path.empty? &&
      self.path[0..1] == SLASH + SLASH && self.authority == nil
    raise InvalidURIError,
      "Cannot have a path with two leading slashes " +
      "without an authority set: '#{self.to_s}'"
  end
  unreserved = CharacterClasses::UNRESERVED
  sub_delims = CharacterClasses::SUB_DELIMS
  if !self.host.nil? && (self.host =~ /[<>{}\/\\\?\#\@"[[:space:]]]/ ||
      (self.host[/^\[(.*)\]$/, 1] != nil && self.host[/^\[(.*)\]$/, 1] !~
      Regexp.new("^[#{unreserved}#{sub_delims}:]*$")))
    raise InvalidURIError, "Invalid character in host: '#{self.host.to_s}'"
  end
  return nil
end