非常教程

Ruby 2.4参考手册

URI

URI::Generic

Parent:ObjectIncluded modules:URI

所有URI类的基类。根据RFC 2396实现通用URI语法。

常量

COMPONENT

URI::Generic的可用组件的数组

DEFAULT_PORT

URI::Generic的默认端口为nil

属性

fragmentR

返回URI的片段组件。

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

hostR

返回URI的host组件。

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

如果没有主机组件,返回nil。

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

该组件不包含端口号。

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

由于IPv6地址由URI中的方括号包裹,因此此方法返回由方括号包装的IPv6地址。这种形式不适合传递IO.open等套接字方法。如果需要展开主机名称,请使用“hostname”方法。

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

opaqueR

返回URI的不透明部分。

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

使用斜杠'/'的路径的一部分。路径通常指绝对路径和不透明部分。

(see RFC2396 Section 3 and 5.2)

pathR

返回URI的路径组件。

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

portR

返回URI的端口组件。

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

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

queryR

返回URI的查询组件。

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

schemeR

返回URI的方案组件。

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

Public Class Methods

build(args) Show source

概要

See new

描述

从URI::Generic的组件创建一个新的URI::Generic实例,并带有检查。组件是:计划,用户信息,主机,端口,注册表,路径,不透明,查询和片段。您可以通过Array或Hash提供参数。查看要使用的散列键的新值或数组项的排序。

# File lib/uri/generic.rb, line 115
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) Show source

概要

See new

描述

首先,尝试使用:: build创建一个新的URI::Generic实例。但是,如果引发异常URI::InvalidComponentError,那么它将URI::Escape#转义所有URI组件并再次尝试。

# File lib/uri/generic.rb, line 77
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() Show source

order中的URI组件。

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

default_port() Show source

返回默认端口

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

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

Args

scheme

协议方案,即'http','ftp','mailto'等。

userinfo

用户名和密码,即'sdmitry:bla'

host

服务器主机名称

port

服务器端口

registry

命名机构的注册局。

path

服务器上的路径

opaque

不透明的部分

query

查询数据

fragment

'#'符号后的一部分URI

parser

解析器默认为内部使用URI::DEFAULT_PARSER

arg_check

默认情况下检查参数为false

描述

从“generic”组件中创建一个新的URI :: Generic实例,无需检查。

# File lib/uri/generic.rb, line 167
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.userinfo = userinfo
    self.hostname = host
    self.port = port
    self.path = path
    self.query = query
    self.opaque = opaque
    self.fragment = fragment
  else
    self.set_scheme(scheme)
    self.set_userinfo(userinfo)
    self.set_host(host)
    self.set_port(port)
    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)

别名为:merge

-(oth)

别名为:route_from

==(oth) Show source

与URI的比较

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

absolute()

别名为:absolute?

absolute?() Show source

检查URI是否是绝对的

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

另外别名为:absolute

coerce(oth) Show source

Args

v

URI或字符串

描述

attempt to parse other URI +oth+
return [parsed_oth, self]

用法

require 'uri'

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

调用超类方法

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

  return oth, self
end

component() Show source

订单中的URI组件。

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

default_port() Show source

返回默认端口

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

eql?(oth) Show source

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

find_proxy(env=ENV) Show source

返回一个代理URI。代理URI是从诸如http_proxy,ftp_proxy,no_proxy等环境变量中获得的。如果没有正确的代理,则返回nil。

如果指定了可选参数,则使用它来代替ENV,env

请注意,大写变量(HTTP_PROXY,FTP_PROXY,NO_PROXY等)也会被检查。

但是在CGI环境下专门处理http_proxy和HTTP_PROXY。这是因为HTTP_PROXY可能由Proxy:header设置。所以不使用HTTP_PROXY。如果变量不区分大小写,http_proxy也不会被使用。CGI_HTTP_PROXY可以用来代替。

# File lib/uri/generic.rb, line 1477
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'
    unless proxy_uri = env[name]
      if proxy_uri = env[name.upcase]
        warn 'The environment variable HTTP_PROXY is discouraged.  Use http_proxy.'
      end
    end
  else
    proxy_uri = env[name] || env[name.upcase]
  end

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

  if self.hostname
    require 'socket'
    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]
    no_proxy.scan(/(?!\.)([^:,\s]+)(?::(\d+))?/) {|host, port|
      if (!port || self.port == port.to_i)
        if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host
          return nil
        else
          require 'ipaddr'
          return nil if
            begin
              IPAddr.new(host)
            rescue IPAddr::InvalidAddressError
              next
            end.include?(self.host)
        end
      end
    }
  end
  URI.parse(proxy_uri)
end

fragment=(v) Show source

根据URI::Parser Regexp 检查片段组件:FRAGMENTv

Args

v

String

描述

碎片组件的公共setter v.(有验证)

用法

require 'uri'

uri = URI.parse("http://my.example.com/?id=25#time=1305212049")
uri.fragment = "time=1305212086"
# =>  "time=1305212086"
uri
#=> #<URI::HTTP:0x000000007a81f8 URL:http://my.example.com/?id=25#time=1305212086>
# File lib/uri/generic.rb, line 932
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() Show source

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

hierarchical?() Show source

检查URI是否有路径

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

host=(v) Show source

Args

v

String

描述

主机组件的公共setter v.(有验证)

see also #check_host

用法

require 'uri'

uri = URI.parse("http://my.example.com")
uri.host = "foo.com"
# =>  "foo.com"
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:http://foo.com>
# File lib/uri/generic.rb, line 634
def host=(v)
  check_host(v)
  set_host(v)
  v
end

hostname() Show source

提取URI的主机部分并解开IPv6地址的括号。

此方法与#host相同,不同之处在于删除了IPv6(和将来的IP)地址的括号。

u = URI(“http://[::1]/bar”) p u.hostname #=> “::1” p u.host #=> “::1”

# File lib/uri/generic.rb, line 649
def hostname
  v = self.host
  /\A\[(.*)\]\z/ =~ v ? $1 : v
end

hostname=(v) Show source

将URI的主机部分设置为包含IPv6地址括号的参数。

此方法与#host =相同,但参数可以是裸IPv6地址。

u = URI(“foo/bar”) p u.to_s #=> “foo/bar” u.hostname = “::1” p u.to_s #=> “[::1]/bar”

如果参数看起来是IPv6地址,则它被括号括起来。

# File lib/uri/generic.rb, line 667
def hostname=(v)
  v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v
  self.host = v
end

inspect() Show source

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

merge(oth) Show source

Args

oth

URI or String

描述

合并两个URI。

用法

require 'uri'

uri = URI.parse("http://my.example.com")
p uri.merge("/main.rbx?page=1")
# =>  #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>
# File lib/uri/generic.rb, line 1097
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.userinfo || rel.host || rel.port

  # 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_path(merge_path(base.path, rel.path)) if base.path && rel.path
  else
    # RFC2396, Section 5.2, 4)
    base.set_path(rel.path) if rel.path
  end

  # RFC2396, Section 5.2, 7)
  base.set_userinfo(rel.userinfo) if rel.userinfo
  base.set_host(rel.host)         if rel.host
  base.set_port(rel.port)         if rel.port
  base.query = rel.query       if rel.query
  base.fragment=(rel.fragment) if rel.fragment

  return base
end

另外别名为:+

merge!(oth) Show source

Args

oth

URI或字符串

描述

破坏性的合并形式

用法

require 'uri'

uri = URI.parse("http://my.example.com")
uri.merge!("/main.rbx?page=1")
p uri
# =>  #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>
# File lib/uri/generic.rb, line 1069
def merge!(oth)
  t = merge(oth)
  if self == t
    nil
  else
    replace!(t)
    self
  end
end

normalize() Show source

返回规范化的URI

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

normalize!() Show source

正常化的破坏性版本

# File lib/uri/generic.rb, line 1306
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) Show source

Args

v

字符串

描述

公共设置不透明组件v.(有验证)

see also #check_opaque

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

parser() Show source

返回要使用的解析器。

除非定义了URI::Parser,否则使用DEFAULT_PARSER。

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

password() Show source

返回密码组件

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

password=(password) Show source

Args

v

String

描述

组件的公共setter(有验证)password

see also #check_password

用法

require 'uri'

uri = URI.parse("http://john:S3nsit1ve@my.example.com")
uri.password = "V3ry_S3nsit1ve"
# =>  "V3ry_S3nsit1ve"
uri
#=> #<URI::HTTP:0x00000000881d90 URL:http://john:V3ry_S3nsit1ve@my.example.com>
# File lib/uri/generic.rb, line 501
def password=(password)
  check_password(password)
  set_password(password)
  # returns password
end

path=(v) Show source

Args

v

String

描述

路径组件的公共setter v.(有验证)

see also #check_path

用法

require 'uri'

uri = URI.parse("http://my.example.com/pub/files")
uri.path = "/faq/"
# =>  "/faq/"
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/faq/>
# File lib/uri/generic.rb, line 815
def path=(v)
  check_path(v)
  set_path(v)
  v
end

port=(v) Show source

Args

v

String

描述

端口组件的公共setter v.(有验证)

see also #check_port

用法

require 'uri'

uri = URI.parse("http://my.example.com")
uri.port = 8080
# =>  8080
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com:8080>
# File lib/uri/generic.rb, line 727
def port=(v)
  check_port(v)
  set_port(v)
  port
end

query=(v) Show source

Args

v

String

描述

查询组件的公共setter .v

用法

require 'uri'

uri = URI.parse("http://my.example.com/?id=25")
uri.query = "id=1"
# =>  "id=1"
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/?id=1>
# File lib/uri/generic.rb, line 841
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)
  v.gsub!(/(?!%\h\h|[!$-&(-;=?-_a-~])./n.freeze){'%%%02X' % $&.ord}
  v.force_encoding(Encoding::US_ASCII)
  @query = v
end

registry=(v) Show source

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

relative?() Show source

检查URI是否相对

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

route_from(oth) Show source

Args

oth

URI or String

描述

计算从heoth到self的相对路径

用法

require 'uri'

uri = URI.parse('http://my.example.com/main.rbx?page=1')
p uri.route_from('http://my.example.com')
#=> #<URI::Generic:0x20218858 URL:/main.rbx?page=1>
# File lib/uri/generic.rb, line 1250
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) Show source

Args

oth

URI或字符串

描述

计算从自己到另一个人的相对路径

用法

require 'uri'

uri = URI.parse('http://my.example.com')
p uri.route_to('http://my.example.com/main.rbx?page=1')
#=> #<URI::Generic:0x2020c2f6 URL:/main.rbx?page=1>
# File lib/uri/generic.rb, line 1290
def route_to(oth)
  parser.send(:convert_to_uri, oth).route_from(self)
end

scheme=(v) Show source

Args

v

String

描述

public setter for the scheme component v. (with validation)

see also #check_scheme

用法

require 'uri'

uri = URI.parse("http://my.example.com")
uri.scheme = "https"
# =>  "https"
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:https://my.example.com>
# File lib/uri/generic.rb, line 359
def scheme=(v)
  check_scheme(v)
  set_scheme(v)
  v
end

select(*components) Show source

Args

components

Multiple Symbol arguments defined in URI::HTTP

描述

从URI中选择指定的组件

用法

require 'uri'

uri = URI.parse('http://myuser:mypass@my.example.com/test.rbx')
p uri.select(:userinfo, :host, :path)
# => ["myuser:mypass", "my.example.com", "/test.rbx"]
# File lib/uri/generic.rb, line 1417
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() Show source

从URI构造字符串

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

  if @opaque
    str << @opaque
  else
    if @host
      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

user() Show source

返回用户组件

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

user=(user) Show source

Args

v

String

描述

user组件的公共setter.(有验证)

see also #check_user

用法

require 'uri'

uri = URI.parse("http://john:S3nsit1ve@my.example.com")
uri.user = "sam"
# =>  "sam"
uri
#=> #<URI::HTTP:0x00000000881d90 URL:http://sam:V3ry_S3nsit1ve@my.example.com>
# File lib/uri/generic.rb, line 472
def user=(user)
  check_user(user)
  set_user(user)
  # returns user
end

userinfo() Show source

返回用户信息,无论是'user'还是'user:password'

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

userinfo=(userinfo) Show source

设置userinfo,参数是字符串,如'name:pass'

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

受保护的实例方法

component_ary() Show source

返回从COMPONENT数组定义的组件的数组

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

set_host(v) Show source

受保护的主机组件的setter v

see also #host=

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

set_opaque(v) Show source

用于不透明组件的受保护的setter v

see also #opaque=

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

set_password(v) Show source

受保护的setter用于密码组件 v

see also #password=

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

set_path(v) Show source

受保护的setter用于路径组件 v

see also #path=

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

set_port(v) Show source

受保护的端口组件的setter v

see also #port=

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

set_scheme(v) Show source

受保护的计划组件的setter v

see also #scheme=

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

set_user(v) Show source

用户组件的受保护setter v

see also #user=

# File lib/uri/generic.rb, line 527
def set_user(v)
  set_userinfo(v, @password)
  v
end

set_userinfo(user, password = nil) Show source

保护user组件的setter ,password如果有的话。(有验证)

see also #userinfo=

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

  [@user, @password]
end

私有实例方法

check_host(v) Show source

检查主机HOSTv的组件是否符合RFC2396,并针对:URI::Parser Regexp

在定义主机组件的情况下,不能定义注册表或不透明组件。

# File lib/uri/generic.rb, line 587
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) Show source

检查vRFC2396合规性的不透明组件,并针对:OPAQUE 检查URI::Parser Regexp

无法定义主机,端口,用户或路径组件,并定义了不透明的组件。

# File lib/uri/generic.rb, line 862
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) Show source

检查vRFC2396合规性的密码组件,并针对:USERINFO的URI::Parser Regexp

在定义用户组件的情况下,不能定义注册表或不透明组件。

# File lib/uri/generic.rb, line 416
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) Show source

请检查RFC2396合规性的路径组件,并针对URI::Parser Regexp检查:ABS_PATH和:REL_PATHv

不能定义一个不透明的组件,并定义一个路径组件。

# File lib/uri/generic.rb, line 755
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) Show source

检查端口v组件是否符合RFC2396标准,并针对:PORT的URI::Parser Regexp

无法定义注册表或不透明组件,并定义了端口组件。

# File lib/uri/generic.rb, line 679
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) Show source

根据URI::Parser Regexp 检查scheme 组件:SCHEMEv

# File lib/uri/generic.rb, line 317
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) Show source

检查用户v组件是否符合RFC2396,并针对USERINFO的URI::Parser Regexp

在定义用户组件的情况下,不能定义注册表或不透明组件。

# File lib/uri/generic.rb, line 392
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) Show source

检查userpassword

如果password未提供,则user使用#split_userinfo分割并提取user密码。

see also #check_user, #check_password

# File lib/uri/generic.rb, line 374
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) Show source

根据RFC 1738第3.1节v转义'user:password'

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

merge_path(base, rel) Show source

合并base具有相对路径的基本路径,rel返回修改的基本路径。

# File lib/uri/generic.rb, line 987
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) Show source

用其他URI对象替换自己

# File lib/uri/generic.rb, line 296
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) Show source

返回'/'分隔的路径数组

# File lib/uri/generic.rb, line 978
def split_path(path)
  path.split(%r{/+}, -1)
end

split_userinfo(ui) Show source

返回userinfo ui作为用户,密码如果格式为'user:password'

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

  return user, password
end
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct