class URI::Generic - Documentation for Ruby 3.3

# class URI::Generic

Base class for all `URI` classes. Implements generic `URI` syntax as per RFC 2396.

### Constants

COMPONENT

  An `Array` of the available components for `URI::Generic`.

DEFAULT_PORT

  A Default port of nil for `URI::Generic`.

### Attributes

fragment[R]

Returns the fragment component of the `URI`.

    URI("http://foo/bar/baz?search=FooBar#ponies").fragment #=> "ponies"

host[R]

Returns the host component of the `URI`.

    URI("http://foo/bar/baz").host #=> "foo"

It returns nil if no host component exists.

    URI("mailto:foo@example.org").host #=> nil

The component does not contain the port number.

    URI("http://foo:8080/bar/baz").host #=> "foo"

Since IPv6 addresses are wrapped with brackets in URIs, this method returns IPv6 addresses wrapped with brackets. This form is not appropriate to pass to socket methods such as `TCPSocket.open`. If unwrapped host names are required, use the `hostname` method.

    URI("http://[::1]/bar/baz").host     #=> "[::1]"
    URI("http://[::1]/bar/baz").hostname #=> "::1"

opaque[R]

Returns the opaque part of the `URI`.

    URI("mailto:foo@example.org").opaque #=> "foo@example.org"
    URI("http://foo/bar/baz").opaque     #=> nil

The portion of the path that does not make use of the slash ‘/’. The path typically refers to an absolute path or an opaque part. (See RFC2396 Section 3 and 5.2.)

path[R]

Returns the path component of the `URI`.

    URI("http://foo/bar/baz").path #=> "/bar/baz"

port[R]

Returns the port component of the `URI`.

    URI("http://foo/bar/baz").port      #=> 80
    URI("http://foo:8080/bar/baz").port #=> 8080

query[R]

Returns the query component of the `URI`.

    URI("http://foo/bar/baz?search=FooBar").query #=> "search=FooBar"

scheme[R]

Returns the scheme component of the `URI`.

    URI("http://foo/bar/baz").scheme #=> "http"

### Public Class Methods

build(args) click to toggle source

## Synopsis¶ ↑

See `::new`.

## Description¶ ↑

Creates a new `URI::Generic` instance from components of `URI::Generic` with check. Components are: scheme, userinfo, host, port, registry, path, opaque, query, and fragment. You can provide arguments either by an `Array` or a `Hash`. See `::new` for hash keys to use or for order of array items.

    # File lib/uri/generic.rb, line 116
    def self.build(args)
      if args.kind_of?(Array) &&
          args.size == ::URI::Generic::COMPONENT.size
        tmp = args.dup
      elsif args.kind_of?(Hash)
        tmp = ::URI::Generic::COMPONENT.collect do |c|
          if args.include?(c)
            args[c]
          else
            nil
          end
        end
      else
        component = self.class.component rescue ::URI::Generic::COMPONENT
        raise ArgumentError,
        "expected Array of or Hash of components of #{self.class} (#{component.join(', ')})"
      end

      tmp << nil
      tmp << true
      return self.new(*tmp)
    end

build2(args) click to toggle source

## Synopsis¶ ↑

See `::new`.

## Description¶ ↑

At first, tries to create a new `URI::Generic` instance using `URI::Generic::build`. But, if exception `URI::InvalidComponentError` is raised, then it does URI::Escape.escape all `URI` components and tries again.

    # File lib/uri/generic.rb, line 78
    def self.build2(args)
      begin
        return self.build(args)
      rescue InvalidComponentError
        if args.kind_of?(Array)
          return self.build(args.collect{|x|
            if x.is_a?(String)
              DEFAULT_PARSER.escape(x)
            else
              x
            end
          })
        elsif args.kind_of?(Hash)
          tmp = {}
          args.each do |key, value|
            tmp[key] = if value
                DEFAULT_PARSER.escape(value)
              else
                value
              end
          end
          return self.build(tmp)
        end
      end
    end

component() click to toggle source

Components of the `URI` in the order.

    # File lib/uri/generic.rb, line 57
    def self.component
      self::COMPONENT
    end

default_port() click to toggle source

Returns default port.

    # File lib/uri/generic.rb, line 32
    def self.default_port
      self::DEFAULT_PORT
    end

new(scheme, userinfo, host, port, registry, path, opaque, query, fragment, parser = DEFAULT_PARSER, arg_check = false) click to toggle source

## Args¶ ↑

`scheme`

  Protocol scheme, i.e. ‘http’,‘ftp’,‘mailto’ and so on.

`userinfo`

  User name and password, i.e. ‘sdmitry:bla’.

`host`

  Server host name.

`port`

  Server port.

`registry`

  Registry of naming authorities.

`path`

  Path on server.

`opaque`

  Opaque part.

`query`

  Query data.

`fragment`

  Part of the `URI` after ‘#’ character.

`parser`

  `Parser` for internal use [URI::DEFAULT_PARSER by default].

`arg_check`

  Check arguments [false by default].

## Description¶ ↑

Creates a new `URI::Generic` instance from “generic” components without check.

    # File lib/uri/generic.rb, line 169
    def initialize(scheme,
                   userinfo, host, port, registry,
                   path, opaque,
                   query,
                   fragment,
                   parser = DEFAULT_PARSER,
                   arg_check = false)
      @scheme = nil
      @user = nil
      @password = nil
      @host = nil
      @port = nil
      @path = nil
      @query = nil
      @opaque = nil
      @fragment = nil
      @parser = parser == DEFAULT_PARSER ? nil : parser

      if arg_check
        self.scheme = scheme
        self.hostname = host
        self.port = port
        self.userinfo = userinfo
        self.path = path
        self.query = query
        self.opaque = opaque
        self.fragment = fragment
      else
        self.set_scheme(scheme)
        self.set_host(host)
        self.set_port(port)
        self.set_userinfo(userinfo)
        self.set_path(path)
        self.query = query
        self.set_opaque(opaque)
        self.fragment=(fragment)
      end
      if registry
        raise InvalidURIError,
          "the scheme #{@scheme} does not accept registry part: #{registry} (or bad hostname?)"
      end

      @scheme&.freeze
      self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
      self.set_port(self.default_port) if self.default_port && !@port
    end

### Public Instance Methods

+(oth)
Alias for: merge
-(oth)
Alias for: route_from
==(oth) click to toggle source

Compares two URIs.

    # File lib/uri/generic.rb, line 1396
    def ==(oth)
      if self.class == oth.class
        self.normalize.component_ary == oth.normalize.component_ary
      else
        false
      end
    end

absolute()
Alias for: absolute?
absolute?() click to toggle source

Returns true if `URI` has a scheme (e.g. http:// or https://) specified.

    # File lib/uri/generic.rb, line 987
    def absolute?
      if @scheme
        true
      else
        false
      end
    end

Also aliased as: absolute
authority() click to toggle source

Returns the authority info (array of user, password, host and port), if any is set. Or returns `nil`.

    # File lib/uri/generic.rb, line 579
    def authority
      return @user, @password, @host, @port if @user || @password || @host || @port
    end

coerce(oth) click to toggle source

## Args¶ ↑

`v`

  `URI` or `String`

## Description¶ ↑

Attempts to parse other `URI` `oth`, returns [parsed_oth, self].

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com")
    uri.coerce("http://foo.com")
    #=> [#<URI::HTTP http://foo.com>, #<URI::HTTP http://my.example.com>]

Calls superclass method

    # File lib/uri/generic.rb, line 1486
    def coerce(oth)
      case oth
      when String
        oth = parser.parse(oth)
      else
        super
      end

      return oth, self
    end

component() click to toggle source

Components of the `URI` in the order.

    # File lib/uri/generic.rb, line 313
    def component
      self.class.component
    end

decoded_password() click to toggle source

Returns the password component after `URI` decoding.

    # File lib/uri/generic.rb, line 589
    def decoded_password
      URI.decode_uri_component(@password) if @password
    end

decoded_user() click to toggle source

Returns the user component after `URI` decoding.

    # File lib/uri/generic.rb, line 584
    def decoded_user
      URI.decode_uri_component(@user) if @user
    end

default_port() click to toggle source

Returns default port.

    # File lib/uri/generic.rb, line 39
    def default_port
      self.class.default_port
    end

eql?(oth) click to toggle source

    # File lib/uri/generic.rb, line 1408
    def eql?(oth)
      self.class == oth.class &&
      parser == oth.parser &&
      self.component_ary.eql?(oth.component_ary)
    end

find_proxy(env=ENV) click to toggle source

Returns a proxy `URI`. The proxy `URI` is obtained from environment variables such as http_proxy, ftp_proxy, no_proxy, etc. If there is no proper proxy, nil is returned.

If the optional parameter `env` is specified, it is used instead of `ENV`.

Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.) are examined, too.

But http_proxy and HTTP_PROXY is treated specially under `CGI` environment. It’s because HTTP_PROXY may be set by Proxy: header. So HTTP_PROXY is not used. http_proxy is not used too if the variable is case insensitive. CGI_HTTP_PROXY can be used instead.

    # File lib/uri/generic.rb, line 1512
    def find_proxy(env=ENV)
      raise BadURIError, "relative URI: #{self}" if self.relative?
      name = self.scheme.downcase + '_proxy'
      proxy_uri = nil
      if name == 'http_proxy' && env.include?('REQUEST_METHOD') # CGI?
        # HTTP_PROXY conflicts with *_proxy for proxy settings and
        # HTTP_* for header information in CGI.
        # So it should be careful to use it.
        pairs = env.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
        case pairs.length
        when 0 # no proxy setting anyway.
          proxy_uri = nil
        when 1
          k, _ = pairs.shift
          if k == 'http_proxy' && env[k.upcase] == nil
            # http_proxy is safe to use because ENV is case sensitive.
            proxy_uri = env[name]
          else
            proxy_uri = nil
          end
        else # http_proxy is safe to use because ENV is case sensitive.
          proxy_uri = env.to_hash[name]
        end
        if !proxy_uri
          # Use CGI_HTTP_PROXY.  cf. libwww-perl.
          proxy_uri = env["CGI_#{name.upcase}"]
        end
      elsif name == 'http_proxy'
        if RUBY_ENGINE == 'jruby' && p_addr = ENV_JAVA['http.proxyHost']
          p_port = ENV_JAVA['http.proxyPort']
          if p_user = ENV_JAVA['http.proxyUser']
            p_pass = ENV_JAVA['http.proxyPass']
            proxy_uri = "http://#{p_user}:#{p_pass}@#{p_addr}:#{p_port}"
          else
            proxy_uri = "http://#{p_addr}:#{p_port}"
          end
        else
          unless proxy_uri = env[name]
            if proxy_uri = env[name.upcase]
              warn 'The environment variable HTTP_PROXY is discouraged.  Use http_proxy.', uplevel: 1
            end
          end
        end
      else
        proxy_uri = env[name] || env[name.upcase]
      end

      if proxy_uri.nil? || proxy_uri.empty?
        return nil
      end

      if self.hostname
        begin
          addr = IPSocket.getaddress(self.hostname)
          return nil if /\A127\.|\A::1\z/ =~ addr
        rescue SocketError
        end
      end

      name = 'no_proxy'
      if no_proxy = env[name] || env[name.upcase]
        return nil unless URI::Generic.use_proxy?(self.hostname, addr, self.port, no_proxy)
      end
      URI.parse(proxy_uri)
    end

fragment=(v) click to toggle source

Checks the fragment `v` component against the `URI::Parser` `Regexp` for :FRAGMENT.

## Args¶ ↑

`v`

  `String`

## Description¶ ↑

Public setter for the fragment component `v` (with validation).

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com/?id=25#time=1305212049")
    uri.fragment = "time=1305212086"
    uri.to_s  #=> "http://my.example.com/?id=25#time=1305212086"

    # File lib/uri/generic.rb, line 944
    def fragment=(v)
      return @fragment = nil unless v

      x = v.to_str
      v = x.dup if x.equal? v
      v.encode!(Encoding::UTF_8) rescue nil
      v.delete!("\t\r\n")
      v.force_encoding(Encoding::ASCII_8BIT)
      v.gsub!(/(?!%\h\h|[!-~])./n){'%%%02X' % $&.ord}
      v.force_encoding(Encoding::US_ASCII)
      @fragment = v
    end

hash() click to toggle source

    # File lib/uri/generic.rb, line 1404
    def hash
      self.component_ary.hash
    end

hierarchical?() click to toggle source

Returns true if `URI` is hierarchical.

## Description¶ ↑

`URI` has components listed in order of decreasing significance from left to right, see RFC3986 tools.ietf.org/html/rfc3986 1.2.3.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com/")
    uri.hierarchical?
    #=> true
    uri = URI.parse("mailto:joe@example.com")
    uri.hierarchical?
    #=> false

    # File lib/uri/generic.rb, line 976
    def hierarchical?
      if @path
        true
      else
        false
      end
    end

host=(v) click to toggle source

## Args¶ ↑

`v`

  `String`

## Description¶ ↑

Public setter for the host component `v` (with validation).

See also `URI::Generic.check_host`.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com")
    uri.host = "foo.com"
    uri.to_s  #=> "http://foo.com"

    # File lib/uri/generic.rb, line 652
    def host=(v)
      check_host(v)
      set_host(v)
      set_userinfo(nil)
      v
    end

hostname() click to toggle source

Extract the host part of the `URI` and unwrap brackets for IPv6 addresses.

This method is the same as `URI::Generic#host` except brackets for IPv6 (and future IP) addresses are removed.

    uri = URI("http://[::1]/bar")
    uri.hostname      #=> "::1"
    uri.host          #=> "[::1]"

    # File lib/uri/generic.rb, line 668
    def hostname
      v = self.host
      v&.start_with?('[') && v.end_with?(']') ? v[1..-2] : v
    end

hostname=(v) click to toggle source

Sets the host part of the `URI` as the argument with brackets for IPv6 addresses.

This method is the same as `URI::Generic#host=` except the argument can be a bare IPv6 address.

    uri = URI("http://foo/bar")
    uri.hostname = "::1"
    uri.to_s  #=> "http://[::1]/bar"

If the argument seems to be an IPv6 address, it is wrapped with brackets.

    # File lib/uri/generic.rb, line 685
    def hostname=(v)
      v = "[#{v}]" if !(v&.start_with?('[') && v&.end_with?(']')) && v&.index(':')
      self.host = v
    end

inspect() click to toggle source

    # File lib/uri/generic.rb, line 1463
    def inspect
      "#<#{self.class} #{self}>"
    end

merge(oth) click to toggle source

## Args¶ ↑

`oth`

  `URI` or `String`

## Description¶ ↑

Merges two URIs.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com")
    uri.merge("/main.rbx?page=1")
    # => "http://my.example.com/main.rbx?page=1"

    # File lib/uri/generic.rb, line 1124
    def merge(oth)
      rel = parser.__send__(:convert_to_uri, oth)

      if rel.absolute?
        #raise BadURIError, "both URI are absolute" if absolute?
        # hmm... should return oth for usability?
        return rel
      end

      unless self.absolute?
        raise BadURIError, "both URI are relative"
      end

      base = self.dup

      authority = rel.authority

      # RFC2396, Section 5.2, 2)
      if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query
        base.fragment=(rel.fragment) if rel.fragment
        return base
      end

      base.query = nil
      base.fragment=(nil)

      # RFC2396, Section 5.2, 4)
      if authority
        base.set_authority(*authority)
        base.set_path(rel.path)
      elsif base.path && rel.path
        base.set_path(merge_path(base.path, rel.path))
      end

      # RFC2396, Section 5.2, 7)
      base.query = rel.query       if rel.query
      base.fragment=(rel.fragment) if rel.fragment

      return base
    end

Also aliased as: +
merge!(oth) click to toggle source

## Args¶ ↑

`oth`

  `URI` or `String`

## Description¶ ↑

Destructive form of `merge`.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com")
    uri.merge!("/main.rbx?page=1")
    uri.to_s  # => "http://my.example.com/main.rbx?page=1"

    # File lib/uri/generic.rb, line 1096
    def merge!(oth)
      t = merge(oth)
      if self == t
        nil
      else
        replace!(t)
        self
      end
    end

normalize() click to toggle source

Returns normalized `URI`.

    require 'uri'

    URI("HTTP://my.EXAMPLE.com").normalize
    #=> #<URI::HTTP http://my.example.com/>

Normalization here means:

- scheme and host are converted to lowercase,

- an empty path component is set to “/”.

    # File lib/uri/generic.rb, line 1331
    def normalize
      uri = dup
      uri.normalize!
      uri
    end

normalize!() click to toggle source

Destructive version of `normalize`.

    # File lib/uri/generic.rb, line 1340
    def normalize!
      if path&.empty?
        set_path('/')
      end
      if scheme && scheme != scheme.downcase
        set_scheme(self.scheme.downcase)
      end
      if host && host != host.downcase
        set_host(self.host.downcase)
      end
    end

opaque=(v) click to toggle source

## Args¶ ↑

`v`

  `String`

## Description¶ ↑

Public setter for the opaque component `v` (with validation).

See also `URI::Generic.check_opaque`.

    # File lib/uri/generic.rb, line 916
    def opaque=(v)
      check_opaque(v)
      set_opaque(v)
      v
    end

parser() click to toggle source

Returns the parser to be used.

Unless a `URI::Parser` is defined, DEFAULT_PARSER is used.

    # File lib/uri/generic.rb, line 289
    def parser
      if !defined?(@parser) || !@parser
        DEFAULT_PARSER
      else
        @parser || DEFAULT_PARSER
      end
    end

password() click to toggle source

Returns the password component (without `URI` decoding).

    # File lib/uri/generic.rb, line 573
    def password
      @password
    end

password=(password) click to toggle source

## Args¶ ↑

`v`

  `String`

## Description¶ ↑

Public setter for the `password` component (with validation).

See also `URI::Generic.check_password`.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://john:S3nsit1ve@my.example.com")
    uri.password = "V3ry_S3nsit1ve"
    uri.to_s  #=> "http://john:V3ry_S3nsit1ve@my.example.com"

    # File lib/uri/generic.rb, line 498
    def password=(password)
      check_password(password)
      set_password(password)
      # returns password
    end

path=(v) click to toggle source

## Args¶ ↑

`v`

  `String`

## Description¶ ↑

Public setter for the path component `v` (with validation).

See also `URI::Generic.check_path`.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com/pub/files")
    uri.path = "/faq/"
    uri.to_s  #=> "http://my.example.com/faq/"

    # File lib/uri/generic.rb, line 830
    def path=(v)
      check_path(v)
      set_path(v)
      v
    end

port=(v) click to toggle source

## Args¶ ↑

`v`

  `String`

## Description¶ ↑

Public setter for the port component `v` (with validation).

See also `URI::Generic.check_port`.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com")
    uri.port = 8080
    uri.to_s  #=> "http://my.example.com:8080"

    # File lib/uri/generic.rb, line 743
    def port=(v)
      check_port(v)
      set_port(v)
      set_userinfo(nil)
      port
    end

query=(v) click to toggle source

## Args¶ ↑

`v`

  `String`

## Description¶ ↑

Public setter for the query component `v`.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com/?id=25")
    uri.query = "id=1"
    uri.to_s  #=> "http://my.example.com/?id=1"

    # File lib/uri/generic.rb, line 854
    def query=(v)
      return @query = nil unless v
      raise InvalidURIError, "query conflicts with opaque" if @opaque

      x = v.to_str
      v = x.dup if x.equal? v
      v.encode!(Encoding::UTF_8) rescue nil
      v.delete!("\t\r\n")
      v.force_encoding(Encoding::ASCII_8BIT)
      raise InvalidURIError, "invalid percent escape: #{$1}" if /(%\H\H)/n.match(v)
      v.gsub!(/(?!%\h\h|[!$-&(-;=?-_a-~])./n.freeze){'%%%02X' % $&.ord}
      v.force_encoding(Encoding::US_ASCII)
      @query = v
    end

registry=(v) click to toggle source

    # File lib/uri/generic.rb, line 760
    def registry=(v)
      raise InvalidURIError, "can not set registry"
    end

relative?() click to toggle source

Returns true if `URI` does not have a scheme (e.g. http:// or https://) specified.

    # File lib/uri/generic.rb, line 999
    def relative?
      !absolute?
    end

route_from(oth) click to toggle source

## Args¶ ↑

`oth`

  `URI` or `String`

## Description¶ ↑

Calculates relative path from oth to self.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse('http://my.example.com/main.rbx?page=1')
    uri.route_from('http://my.example.com')
    #=> #<URI::Generic /main.rbx?page=1>

    # File lib/uri/generic.rb, line 1274
    def route_from(oth)
      # you can modify `rel', but can not `oth'.
      begin
        oth, rel = route_from0(oth)
      rescue
        raise $!.class, $!.message
      end
      if oth == rel
        return rel
      end

      rel.set_path(route_from_path(oth.path, self.path))
      if rel.path == './' && self.query
        # "./?foo" -> "?foo"
        rel.set_path('')
      end

      return rel
    end

Also aliased as: -
route_to(oth) click to toggle source

## Args¶ ↑

`oth`

  `URI` or `String`

## Description¶ ↑

Calculates relative path to oth from self.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse('http://my.example.com')
    uri.route_to('http://my.example.com/main.rbx?page=1')
    #=> #<URI::Generic /main.rbx?page=1>

    # File lib/uri/generic.rb, line 1314
    def route_to(oth)
      parser.__send__(:convert_to_uri, oth).route_from(self)
    end

scheme=(v) click to toggle source

## Args¶ ↑

`v`

  `String`

## Description¶ ↑

Public setter for the scheme component `v` (with validation).

See also `URI::Generic.check_scheme`.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://my.example.com")
    uri.scheme = "https"
    uri.to_s  #=> "https://my.example.com"

    # File lib/uri/generic.rb, line 360
    def scheme=(v)
      check_scheme(v)
      set_scheme(v)
      v
    end

select(*components) click to toggle source

## Args¶ ↑

`components`

  Multiple `Symbol` arguments defined in `URI::HTTP`.

## Description¶ ↑

Selects specified components from `URI`.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse('http://myuser:mypass@my.example.com/test.rbx')
    uri.select(:userinfo, :host, :path)
    # => ["myuser:mypass", "my.example.com", "/test.rbx"]

    # File lib/uri/generic.rb, line 1452
    def select(*components)
      components.collect do |c|
        if component.include?(c)
          self.__send__(c)
        else
          raise ArgumentError,
            "expected of components of #{self.class} (#{self.class.component.join(', ')})"
        end
      end
    end

to_s() click to toggle source

Constructs `String` from `URI`.

    # File lib/uri/generic.rb, line 1355
    def to_s
      str = ''.dup
      if @scheme
        str << @scheme
        str << ':'
      end

      if @opaque
        str << @opaque
      else
        if @host || %w[file postgres].include?(@scheme)
          str << '//'
        end
        if self.userinfo
          str << self.userinfo
          str << '@'
        end
        if @host
          str << @host
        end
        if @port && @port != self.default_port
          str << ':'
          str << @port.to_s
        end
        str << @path
        if @query
          str << '?'
          str << @query
        end
      end
      if @fragment
        str << '#'
        str << @fragment
      end
      str
    end

Also aliased as: to_str
to_str()
Alias for: to_s
user() click to toggle source

Returns the user component (without `URI` decoding).

    # File lib/uri/generic.rb, line 568
    def user
      @user
    end

user=(user) click to toggle source

## Args¶ ↑

`v`

  `String`

## Description¶ ↑

Public setter for the `user` component (with validation).

See also `URI::Generic.check_user`.

## Usage¶ ↑

    require 'uri'

    uri = URI.parse("http://john:S3nsit1ve@my.example.com")
    uri.user = "sam"
    uri.to_s  #=> "http://sam:V3ry_S3nsit1ve@my.example.com"

    # File lib/uri/generic.rb, line 471
    def user=(user)
      check_user(user)
      set_user(user)
      # returns user
    end

userinfo() click to toggle source

Returns the userinfo, either as ‘user’ or ‘user:password’.

    # File lib/uri/generic.rb, line 557
    def userinfo
      if @user.nil?
        nil
      elsif @password.nil?
        @user
      else
        @user + ':' + @password
      end
    end

userinfo=(userinfo) click to toggle source

Sets userinfo, argument is string like ‘name:pass’.

    # File lib/uri/generic.rb, line 441
    def userinfo=(userinfo)
      if userinfo.nil?
        return nil
      end
      check_userinfo(*userinfo)
      set_userinfo(*userinfo)
      # returns userinfo
    end

### Protected Instance Methods

component_ary() click to toggle source

Returns an `Array` of the components defined from the `COMPONENT` `Array`.

    # File lib/uri/generic.rb, line 1428
    def component_ary
      component.collect do |x|
        self.__send__(x)
      end
    end

set_authority(user, password, host, port = nil) click to toggle source

Protected setter for the authority info (`user`, `password`, `host` and `port`). If `port` is `nil`, `default_port` will be set.

    # File lib/uri/generic.rb, line 627
              def set_authority(user, password, host, port = nil)
      @user, @password, @host, @port = user, password, host, port || self.default_port
    end

set_host(v) click to toggle source

Protected setter for the host component `v`.

See also `URI::Generic.host=`.

    # File lib/uri/generic.rb, line 619
    def set_host(v)
      @host = v
    end

set_opaque(v) click to toggle source

Protected setter for the opaque component `v`.

See also `URI::Generic.opaque=`.

    # File lib/uri/generic.rb, line 898
    def set_opaque(v)
      @opaque = v
    end

set_password(v) click to toggle source

Protected setter for the password component `v`.

See also `URI::Generic.password=`.

    # File lib/uri/generic.rb, line 534
    def set_password(v)
      @password = v
      # returns v
    end

set_path(v) click to toggle source

Protected setter for the path component `v`.

See also `URI::Generic.path=`.

    # File lib/uri/generic.rb, line 804
    def set_path(v)
      @path = v
    end

set_port(v) click to toggle source

Protected setter for the port component `v`.

See also `URI::Generic.port=`.

    # File lib/uri/generic.rb, line 716
    def set_port(v)
      v = v.empty? ? nil : v.to_i unless !v || v.kind_of?(Integer)
      @port = v
    end

set_scheme(v) click to toggle source

Protected setter for the scheme component `v`.

See also `URI::Generic.scheme=`.

    # File lib/uri/generic.rb, line 334
    def set_scheme(v)
      @scheme = v&.downcase
    end

set_user(v) click to toggle source

Protected setter for the user component `v`.

See also `URI::Generic.user=`.

    # File lib/uri/generic.rb, line 524
    def set_user(v)
      set_userinfo(v, nil)
      v
    end

set_userinfo(user, password = nil) click to toggle source

Protected setter for the `user` component, and `password` if available (with validation).

See also `URI::Generic.userinfo=`.

    # File lib/uri/generic.rb, line 509
    def set_userinfo(user, password = nil)
      unless password
        user, password = split_userinfo(user)
      end
      @user     = user
      @password = password

      [@user, @password]
    end

### Private Instance Methods

check_host(v) click to toggle source

Checks the host `v` component for RFC2396 compliance and against the `URI::Parser` `Regexp` for :HOST.

Can not have a registry or opaque component defined, with a host component defined.

    # File lib/uri/generic.rb, line 600
    def check_host(v)
      return v unless v

      if @opaque
        raise InvalidURIError,
          "can not set host with registry or opaque"
      elsif parser.regexp[:HOST] !~ v
        raise InvalidComponentError,
          "bad component(expected host component): #{v}"
      end

      return true
    end

check_opaque(v) click to toggle source

Checks the opaque `v` component for RFC2396 compliance and against the `URI::Parser` `Regexp` for :OPAQUE.

Can not have a host, port, user, or path component defined, with an opaque component defined.

    # File lib/uri/generic.rb, line 876
    def check_opaque(v)
      return v unless v

      # raise if both hier and opaque are not nil, because:
      # absoluteURI   = scheme ":" ( hier_part | opaque_part )
      # hier_part     = ( net_path | abs_path ) [ "?" query ]
      if @host || @port || @user || @path  # userinfo = @user + ':' + @password
        raise InvalidURIError,
          "can not set opaque with host, port, userinfo or path"
      elsif v && parser.regexp[:OPAQUE] !~ v
        raise InvalidComponentError,
          "bad component(expected opaque component): #{v}"
      end

      return true
    end

check_password(v, user = @user) click to toggle source

Checks the password `v` component for RFC2396 compliance and against the `URI::Parser` `Regexp` for :USERINFO.

Can not have a registry or opaque component defined, with a user component defined.

    # File lib/uri/generic.rb, line 417
    def check_password(v, user = @user)
      if @opaque
        raise InvalidURIError,
          "can not set password with opaque"
      end
      return v unless v

      if !user
        raise InvalidURIError,
          "password component depends user component"
      end

      if parser.regexp[:USERINFO] !~ v
        raise InvalidComponentError,
          "bad password component"
      end

      return true
    end

check_path(v) click to toggle source

Checks the path `v` component for RFC2396 compliance and against the `URI::Parser` `Regexp` for :ABS_PATH and :REL_PATH.

Can not have a opaque component defined, with a path component defined.

    # File lib/uri/generic.rb, line 772
    def check_path(v)
      # raise if both hier and opaque are not nil, because:
      # absoluteURI   = scheme ":" ( hier_part | opaque_part )
      # hier_part     = ( net_path | abs_path ) [ "?" query ]
      if v && @opaque
        raise InvalidURIError,
          "path conflicts with opaque"
      end

      # If scheme is ftp, path may be relative.
      # See RFC 1738 section 3.2.2, and RFC 2396.
      if @scheme && @scheme != "ftp"
        if v && v != '' && parser.regexp[:ABS_PATH] !~ v
          raise InvalidComponentError,
            "bad component(expected absolute path component): #{v}"
        end
      else
        if v && v != '' && parser.regexp[:ABS_PATH] !~ v &&
           parser.regexp[:REL_PATH] !~ v
          raise InvalidComponentError,
            "bad component(expected relative path component): #{v}"
        end
      end

      return true
    end

check_port(v) click to toggle source

Checks the port `v` component for RFC2396 compliance and against the `URI::Parser` `Regexp` for :PORT.

Can not have a registry or opaque component defined, with a port component defined.

    # File lib/uri/generic.rb, line 697
    def check_port(v)
      return v unless v

      if @opaque
        raise InvalidURIError,
          "can not set port with registry or opaque"
      elsif !v.kind_of?(Integer) && parser.regexp[:PORT] !~ v
        raise InvalidComponentError,
          "bad component(expected port component): #{v.inspect}"
      end

      return true
    end

check_scheme(v) click to toggle source

Checks the scheme `v` component against the `URI::Parser` `Regexp` for :SCHEME.

    # File lib/uri/generic.rb, line 320
    def check_scheme(v)
      if v && parser.regexp[:SCHEME] !~ v
        raise InvalidComponentError,
          "bad component(expected scheme component): #{v}"
      end

      return true
    end

check_user(v) click to toggle source

Checks the user `v` component for RFC2396 compliance and against the `URI::Parser` `Regexp` for :USERINFO.

Can not have a registry or opaque component defined, with a user component defined.

    # File lib/uri/generic.rb, line 393
    def check_user(v)
      if @opaque
        raise InvalidURIError,
          "can not set user with opaque"
      end

      return v unless v

      if parser.regexp[:USERINFO] !~ v
        raise InvalidComponentError,
          "bad component(expected userinfo component or user component): #{v}"
      end

      return true
    end

check_userinfo(user, password = nil) click to toggle source

Checks the `user` and `password`.

If `password` is not provided, then `user` is split, using `URI::Generic.split_userinfo`, to pull `user` and +password.

See also `URI::Generic.check_user`, `URI::Generic.check_password`.

    # File lib/uri/generic.rb, line 375
    def check_userinfo(user, password = nil)
      if !password
        user, password = split_userinfo(user)
      end
      check_user(user)
      check_password(password, user)

      return true
    end

escape_userpass(v) click to toggle source

Escapes ‘user:password’ `v` based on RFC 1738 section 3.1.

    # File lib/uri/generic.rb, line 551
    def escape_userpass(v)
      parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
    end

merge_path(base, rel) click to toggle source

Merges a base path `base`, with relative path `rel`, returns a modified base path.

    # File lib/uri/generic.rb, line 1015
    def merge_path(base, rel)

      # RFC2396, Section 5.2, 5)
      # RFC2396, Section 5.2, 6)
      base_path = split_path(base)
      rel_path  = split_path(rel)

      # RFC2396, Section 5.2, 6), a)
      base_path << '' if base_path.last == '..'
      while i = base_path.index('..')
        base_path.slice!(i - 1, 2)
      end

      if (first = rel_path.first) and first.empty?
        base_path.clear
        rel_path.shift
      end

      # RFC2396, Section 5.2, 6), c)
      # RFC2396, Section 5.2, 6), d)
      rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'
      rel_path.delete('.')

      # RFC2396, Section 5.2, 6), e)
      tmp = []
      rel_path.each do |x|
        if x == '..' &&
            !(tmp.empty? || tmp.last == '..')
          tmp.pop
        else
          tmp << x
        end
      end

      add_trailer_slash = !tmp.empty?
      if base_path.empty?
        base_path = [''] # keep '/' for root directory
      elsif add_trailer_slash
        base_path.pop
      end
      while x = tmp.shift
        if x == '..'
          # RFC2396, Section 4
          # a .. or . in an absolute path has no special meaning
          base_path.pop if base_path.size > 1
        else
          # if x == '..'
          #   valid absolute (but abnormal) path "/../..."
          # else
          #   valid absolute path
          # end
          base_path << x
          tmp.each {|t| base_path << t}
          add_trailer_slash = false
          break
        end
      end
      base_path.push('') if add_trailer_slash

      return base_path.join('/')
    end

replace!(oth) click to toggle source

Replaces self by other `URI` object.

    # File lib/uri/generic.rb, line 299
    def replace!(oth)
      if self.class != oth.class
        raise ArgumentError, "expected #{self.class} object"
      end

      component.each do |c|
        self.__send__("#{c}=", oth.__send__(c))
      end
    end

split_path(path) click to toggle source

Returns an `Array` of the path split on ‘/’.

    # File lib/uri/generic.rb, line 1006
    def split_path(path)
      path.split("/", -1)
    end

split_userinfo(ui) click to toggle source

Returns the userinfo `ui` as `[user, password]` if properly formatted as ‘user:password’.

    # File lib/uri/generic.rb, line 542
    def split_userinfo(ui)
      return nil, nil unless ui
      user, password = ui.split(':', 2)

      return user, password
    end