URI::Generic
class 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 v
alidation)
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
检查v
RFC2396合规性的不透明组件,并针对: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
检查v
RFC2396合规性的密码组件,并针对: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
检查user
和password
。
如果password
未提供,则user
使用#split_user
info分割并提取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