uri-component 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/Rakefile +5 -0
- data/lib/uri/component/path.rb +122 -0
- data/lib/uri/component/query.rb +115 -0
- data/lib/uri/component/userinfo.rb +156 -0
- data/lib/uri/component/version.rb +6 -0
- data/test/test_component_path.rb +174 -0
- data/test/test_component_query.rb +179 -0
- data/test/test_component_userinfo.rb +158 -0
- data/uri-compoment.gemspec +21 -0
- metadata +58 -0
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
## Ruby URI::Component::Path: Class to handle a path component in an URI
|
2
|
+
##
|
3
|
+
## Author:: SATOH Fumiyasu
|
4
|
+
## Copyright:: (c) 2007-2011 SATOH Fumiyasu @ OSS Technology, Corp.
|
5
|
+
## License:: You can redistribute it and/or modify it under the same term as Ruby.
|
6
|
+
##
|
7
|
+
|
8
|
+
require 'uri'
|
9
|
+
|
10
|
+
module URI
|
11
|
+
module Component
|
12
|
+
## Handle a path component in an URI as an object
|
13
|
+
class Path
|
14
|
+
#:stopdoc:
|
15
|
+
## Same as URI::UNSAFE, plus ';' (separator for path nodes)
|
16
|
+
## and '?' (separator for path and query)
|
17
|
+
RE_UNSAFE = /
|
18
|
+
[^#{URI::REGEXP::PATTERN::UNRESERVED}#{URI::REGEXP::PATTERN::RESERVED}]|
|
19
|
+
[\/?]
|
20
|
+
/x
|
21
|
+
RE_COMPONENT = /^(?:#{URI::REGEXP::PATTERN::ABS_PATH})?$/
|
22
|
+
#:startdoc:
|
23
|
+
|
24
|
+
def self.mixin(klass) #:nodoc:
|
25
|
+
PathMixin.__send__(:append_features, klass)
|
26
|
+
PathMixin.__send__(:included, klass)
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(path_str='')
|
30
|
+
unless path_str =~ RE_COMPONENT
|
31
|
+
raise InvalidURIError, "bad Path component for URI: #{path_str}"
|
32
|
+
end
|
33
|
+
|
34
|
+
if path_str
|
35
|
+
@nodes = path_str.split('/', -1).map do |node|
|
36
|
+
URI.unescape(node)
|
37
|
+
end
|
38
|
+
@nodes.shift
|
39
|
+
else
|
40
|
+
@nodes = []
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_uri
|
45
|
+
return '' if @nodes.empty?
|
46
|
+
return '/' + @nodes.map do |node|
|
47
|
+
URI.escape(node, RE_UNSAFE)
|
48
|
+
end.join('/')
|
49
|
+
end
|
50
|
+
alias to_s to_uri
|
51
|
+
|
52
|
+
def nodes
|
53
|
+
return @nodes
|
54
|
+
end
|
55
|
+
|
56
|
+
def nodes=(v)
|
57
|
+
@nodes = v
|
58
|
+
end
|
59
|
+
|
60
|
+
def normalize!
|
61
|
+
nodes = []
|
62
|
+
@nodes.each do |node|
|
63
|
+
case node
|
64
|
+
when ''
|
65
|
+
next
|
66
|
+
when '.'
|
67
|
+
next
|
68
|
+
when '..'
|
69
|
+
nodes.pop
|
70
|
+
next
|
71
|
+
end
|
72
|
+
nodes << node
|
73
|
+
end
|
74
|
+
|
75
|
+
@nodes = nodes
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
module PathMixin
|
80
|
+
def initialize_copy(uri)
|
81
|
+
if (path = uri.instance_variable_get('@path_component'))
|
82
|
+
@path_component = path.dup
|
83
|
+
end
|
84
|
+
|
85
|
+
super(uri)
|
86
|
+
end
|
87
|
+
|
88
|
+
def path
|
89
|
+
return @path_component ? @path_component.to_uri : @path
|
90
|
+
end
|
91
|
+
|
92
|
+
def path=(path_str)
|
93
|
+
super(path_str)
|
94
|
+
|
95
|
+
parse_path!
|
96
|
+
return self.path
|
97
|
+
end
|
98
|
+
|
99
|
+
def path_component
|
100
|
+
parse_path! unless @path_component
|
101
|
+
return @path_component
|
102
|
+
end
|
103
|
+
alias path_c path_component
|
104
|
+
|
105
|
+
def path_query
|
106
|
+
str = self.path
|
107
|
+
if query = self.query
|
108
|
+
str += '?' + query
|
109
|
+
end
|
110
|
+
return str
|
111
|
+
end
|
112
|
+
private :path_query
|
113
|
+
|
114
|
+
protected
|
115
|
+
|
116
|
+
def parse_path!
|
117
|
+
@path_component = URI::Component::Path.new(@path)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
@@ -0,0 +1,115 @@
|
|
1
|
+
## Ruby URI::Component::Query: Class to handle a query component in an URI
|
2
|
+
##
|
3
|
+
## Author:: SATOH Fumiyasu
|
4
|
+
## Copyright:: (c) 2007-2011 SATOH Fumiyasu @ OSS Technology, Corp.
|
5
|
+
## License:: You can redistribute it and/or modify it under the same term as Ruby.
|
6
|
+
##
|
7
|
+
|
8
|
+
require 'uri'
|
9
|
+
require 'cgi'
|
10
|
+
|
11
|
+
module URI
|
12
|
+
module Component
|
13
|
+
## Handle a query component in an URI as an object
|
14
|
+
class Query
|
15
|
+
#:stopdoc:
|
16
|
+
RE_COMPONENT = /^#{URI::REGEXP::PATTERN::QUERY}?$/
|
17
|
+
#:startdoc:
|
18
|
+
|
19
|
+
def self.mixin(klass) #:nodoc:
|
20
|
+
QueryMixin.__send__(:append_features, klass)
|
21
|
+
QueryMixin.__send__(:included, klass)
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(query_str='')
|
25
|
+
unless query_str =~ RE_COMPONENT
|
26
|
+
raise InvalidURIError, "bad Query component for URI: #{query_str}"
|
27
|
+
end
|
28
|
+
|
29
|
+
@params = {}
|
30
|
+
@params.default_proc = Proc.new {|hash, key|
|
31
|
+
hash[key] = [] unless hash.key?(key)
|
32
|
+
}
|
33
|
+
@param_separator = '&'
|
34
|
+
|
35
|
+
query_str.split(/[&;]/).each do |param|
|
36
|
+
next if param.empty?
|
37
|
+
name, value = param.split('=', 2).map do |v|
|
38
|
+
CGI.unescape(v)
|
39
|
+
end
|
40
|
+
@params[name] ||= []
|
41
|
+
@params[name] << value ? value : nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def params
|
46
|
+
return @params
|
47
|
+
end
|
48
|
+
|
49
|
+
def param_separator
|
50
|
+
return @param_separator
|
51
|
+
end
|
52
|
+
|
53
|
+
def param_separator=(v)
|
54
|
+
@param_separator = v
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_uri(separator=@param_separator)
|
58
|
+
query = []
|
59
|
+
|
60
|
+
@params.each do |name, values|
|
61
|
+
name = CGI.escape(name)
|
62
|
+
values.each do |value|
|
63
|
+
query << "#{name}#{'=' + CGI.escape(value.to_s) if value}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
return query.join(separator)
|
68
|
+
end
|
69
|
+
alias to_s to_uri
|
70
|
+
end
|
71
|
+
|
72
|
+
module QueryMixin
|
73
|
+
def initialize_copy(uri)
|
74
|
+
if (query = uri.instance_variable_get('@query_component'))
|
75
|
+
@query_component = query.dup
|
76
|
+
end
|
77
|
+
|
78
|
+
super(uri)
|
79
|
+
end
|
80
|
+
|
81
|
+
def query
|
82
|
+
return @query_component ? @query_component.to_uri : @query
|
83
|
+
end
|
84
|
+
|
85
|
+
def query=(query_str)
|
86
|
+
super(query_str)
|
87
|
+
|
88
|
+
parse_query!
|
89
|
+
return self.query
|
90
|
+
end
|
91
|
+
|
92
|
+
def query_component
|
93
|
+
parse_query! unless @query_component
|
94
|
+
return @query_component
|
95
|
+
end
|
96
|
+
alias query_c query_component
|
97
|
+
|
98
|
+
def path_query
|
99
|
+
str = self.path
|
100
|
+
if query = self.query
|
101
|
+
str += '?' + query
|
102
|
+
end
|
103
|
+
return str
|
104
|
+
end
|
105
|
+
private :path_query
|
106
|
+
|
107
|
+
protected
|
108
|
+
|
109
|
+
def parse_query!
|
110
|
+
@query_component = URI::Component::Query.new(@query)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
@@ -0,0 +1,156 @@
|
|
1
|
+
## Ruby URI::Component::UserInfo: Class to handle an userinfo component in an URI
|
2
|
+
##
|
3
|
+
## Author:: SATOH Fumiyasu
|
4
|
+
## Copyright:: (c) 2007-2011 SATOH Fumiyasu @ OSS Technology, Corp.
|
5
|
+
## License:: You can redistribute it and/or modify it under the same term as Ruby.
|
6
|
+
##
|
7
|
+
|
8
|
+
require 'uri'
|
9
|
+
|
10
|
+
module URI
|
11
|
+
module Component
|
12
|
+
## Handle an userinfo component in an URI as an object
|
13
|
+
class UserInfo
|
14
|
+
#:stopdoc:
|
15
|
+
RE_UNSAFE = /[^#{URI::REGEXP::PATTERN::UNRESERVED}]/
|
16
|
+
## Same as URI::USERINFO, except ';' and ':'
|
17
|
+
RE_PART = /(?:
|
18
|
+
[#{URI::REGEXP::PATTERN::UNRESERVED}&=+$,]|
|
19
|
+
#{URI::REGEXP::PATTERN::ESCAPED})*
|
20
|
+
/x
|
21
|
+
RE_COMPONENT = /^(?:(#{RE_PART});)?(#{RE_PART})(?::(#{RE_PART}))?$/
|
22
|
+
#:startdoc:
|
23
|
+
|
24
|
+
def self.mixin(klass) #:nodoc:
|
25
|
+
UserInfoMixin.__send__(:append_features, klass)
|
26
|
+
UserInfoMixin.__send__(:included, klass)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.escape(v)
|
30
|
+
return URI.escape(v, RE_UNSAFE)
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(info_str=nil)
|
34
|
+
if info_str
|
35
|
+
unless m = info_str.match(RE_COMPONENT)
|
36
|
+
raise InvalidURIError, "bad UserInfo component for URI: #{info_str}"
|
37
|
+
end
|
38
|
+
@domain = m[1] ? URI.unescape(m[1]) : nil
|
39
|
+
@user = URI.unescape(m[2])
|
40
|
+
@password = m[3] ? URI.unescape(m[3]) : nil
|
41
|
+
else
|
42
|
+
@domain = @user = @password = nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def domain
|
47
|
+
return @domain
|
48
|
+
end
|
49
|
+
|
50
|
+
def domain=(v)
|
51
|
+
if v && !@user
|
52
|
+
raise InvalidURIError, "domain component depends user component"
|
53
|
+
end
|
54
|
+
@domain = v
|
55
|
+
end
|
56
|
+
|
57
|
+
def user
|
58
|
+
return @user
|
59
|
+
end
|
60
|
+
|
61
|
+
def user=(v)
|
62
|
+
if !v
|
63
|
+
@domain = @password = nil
|
64
|
+
end
|
65
|
+
@user = v
|
66
|
+
end
|
67
|
+
|
68
|
+
def password
|
69
|
+
return @password
|
70
|
+
end
|
71
|
+
|
72
|
+
def password=(v)
|
73
|
+
if v && !@user
|
74
|
+
raise InvalidURIError, "password component depends user component"
|
75
|
+
end
|
76
|
+
@password = v
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_uri
|
80
|
+
return nil unless @user
|
81
|
+
|
82
|
+
info_str = ''
|
83
|
+
info_str += self.class.escape(@domain) + ';' if @domain
|
84
|
+
info_str += @user ? self.class.escape(@user) : '';
|
85
|
+
info_str += ':' + self.class.escape(@password) if @password
|
86
|
+
return info_str
|
87
|
+
end
|
88
|
+
alias to_s to_uri
|
89
|
+
end
|
90
|
+
|
91
|
+
module UserInfoMixin
|
92
|
+
def initialize_copy(uri)
|
93
|
+
if (userinfo = uri.instance_variable_get('@userinfo_component'))
|
94
|
+
@userinfo_component = userinfo.dup
|
95
|
+
end
|
96
|
+
|
97
|
+
super(uri)
|
98
|
+
end
|
99
|
+
|
100
|
+
def userinfo
|
101
|
+
@userinfo_component.to_uri
|
102
|
+
end
|
103
|
+
|
104
|
+
def userinfo=(info_str)
|
105
|
+
super(info_str)
|
106
|
+
|
107
|
+
parse_userinfo!
|
108
|
+
return self.userinfo
|
109
|
+
end
|
110
|
+
|
111
|
+
def user
|
112
|
+
user = @userinfo_component.user
|
113
|
+
return nil unless user
|
114
|
+
|
115
|
+
domain = @userinfo_component.domain
|
116
|
+
user_uri = domain ? URI::Component::UserInfo.escape(domain) + ';' : ''
|
117
|
+
user_uri += URI::Component::UserInfo.escape(user)
|
118
|
+
return user_uri
|
119
|
+
end
|
120
|
+
|
121
|
+
def user=(user_uri)
|
122
|
+
if user_uri
|
123
|
+
m = user_uri.match(/^(?:(.*);)?(.*)$/)
|
124
|
+
@userinfo_component.domain = m[1] ? URI.unescape(m[1]) : nil
|
125
|
+
@userinfo_component.user = URI.unescape(m[2])
|
126
|
+
else
|
127
|
+
@userinfo_component.user = nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def password
|
132
|
+
pass = @userinfo_component.password
|
133
|
+
return pass ? URI::Component::UserInfo.escape(pass) : nil
|
134
|
+
end
|
135
|
+
|
136
|
+
def password=(pass_uri)
|
137
|
+
@userinfo_component.password = pass_uri ? URI.unescape(pass_uri) : nil
|
138
|
+
end
|
139
|
+
|
140
|
+
def userinfo_component
|
141
|
+
parse_userinfo! unless @userinfo_component
|
142
|
+
return @userinfo_component
|
143
|
+
end
|
144
|
+
alias userinfo_c userinfo_component
|
145
|
+
|
146
|
+
protected
|
147
|
+
|
148
|
+
def parse_userinfo!
|
149
|
+
info_str = @user
|
150
|
+
info_str += ':' + @password if @password
|
151
|
+
@userinfo_component = URI::Component::UserInfo.new(info_str)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'uri/component/path'
|
3
|
+
|
4
|
+
UCP = URI::Component::Path
|
5
|
+
|
6
|
+
module URI
|
7
|
+
module Component
|
8
|
+
|
9
|
+
class TestPathClass < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_parse
|
17
|
+
p_uri = ''
|
18
|
+
p = UCP.new(p_uri)
|
19
|
+
assert_equal(p_uri, p.to_uri)
|
20
|
+
assert_empty(p.nodes)
|
21
|
+
|
22
|
+
p_uri = '/'
|
23
|
+
p = UCP.new(p_uri)
|
24
|
+
assert_equal(p_uri, p.to_uri)
|
25
|
+
assert_equal(1, p.nodes.size)
|
26
|
+
assert_equal('', p.nodes[0])
|
27
|
+
|
28
|
+
p_uri = '/foo'
|
29
|
+
p = UCP.new(p_uri)
|
30
|
+
assert_equal(p_uri, p.to_uri)
|
31
|
+
assert_equal(1, p.nodes.size)
|
32
|
+
assert_equal('foo', p.nodes[0])
|
33
|
+
|
34
|
+
p_uri = '/foo/'
|
35
|
+
p = UCP.new(p_uri)
|
36
|
+
assert_equal(p_uri, p.to_uri)
|
37
|
+
assert_equal(2, p.nodes.size)
|
38
|
+
assert_equal('foo', p.nodes[0])
|
39
|
+
|
40
|
+
p_uri = '/123%20abc'
|
41
|
+
p = UCP.new(p_uri)
|
42
|
+
assert_equal('/123%20abc', p.to_uri)
|
43
|
+
assert_equal(1, p.nodes.size)
|
44
|
+
assert_equal('123 abc', p.nodes[0])
|
45
|
+
|
46
|
+
p_uri = '/123+abc%2BABC'
|
47
|
+
p = UCP.new(p_uri)
|
48
|
+
assert_equal('/123+abc+ABC', p.to_uri)
|
49
|
+
assert_equal(1, p.nodes.size)
|
50
|
+
assert_equal('123+abc+ABC', p.nodes[0])
|
51
|
+
|
52
|
+
p_uri = '/foo-1/bar-abc%40xyz/baz-123%20%00%2B789%25ff'
|
53
|
+
p = UCP.new(p_uri)
|
54
|
+
assert_equal('/foo-1/bar-abc@xyz/baz-123%20%00+789%25ff', p.to_uri)
|
55
|
+
assert_equal(3, p.nodes.size)
|
56
|
+
assert_equal('foo-1', p.nodes[0])
|
57
|
+
assert_equal('bar-abc@xyz', p.nodes[1])
|
58
|
+
assert_equal("baz-123 \x00+789%ff", p.nodes[2])
|
59
|
+
|
60
|
+
p_uri = '/foo//bar'
|
61
|
+
p = UCP.new(p_uri)
|
62
|
+
assert_equal(p_uri, p.to_uri)
|
63
|
+
assert_equal(3, p.nodes.size)
|
64
|
+
assert_equal('foo', p.nodes[0])
|
65
|
+
assert_equal('', p.nodes[1])
|
66
|
+
assert_equal('bar', p.nodes[2])
|
67
|
+
|
68
|
+
%w(foo1 /foo?bar2 /foo\bar3).concat(['/foo bar4']).each do |path_str|
|
69
|
+
assert_raise(URI::InvalidURIError) do
|
70
|
+
UCP.new(path_str)
|
71
|
+
raise path_str
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_set
|
77
|
+
p = UCP.new('')
|
78
|
+
assert_equal('', p.to_uri)
|
79
|
+
|
80
|
+
p = UCP.new('')
|
81
|
+
p.nodes << 'foo'
|
82
|
+
assert_equal('/foo', p.to_uri)
|
83
|
+
|
84
|
+
p = UCP.new('')
|
85
|
+
p.nodes << 'foo?bar'
|
86
|
+
assert_equal('/foo%3Fbar', p.to_uri)
|
87
|
+
|
88
|
+
p = UCP.new('')
|
89
|
+
p.nodes << 'foo/bar'
|
90
|
+
assert_equal('/foo%2Fbar', p.to_uri)
|
91
|
+
|
92
|
+
p = UCP.new('')
|
93
|
+
p.nodes << '123 abc'
|
94
|
+
assert_equal('/123%20abc', p.to_uri)
|
95
|
+
|
96
|
+
p = UCP.new('')
|
97
|
+
p.nodes << '123+abc'
|
98
|
+
assert_equal('/123+abc', p.to_uri)
|
99
|
+
|
100
|
+
p = UCP.new('')
|
101
|
+
p.nodes << 'abc@xyz'
|
102
|
+
p.nodes << "123 \x00+789%ff"
|
103
|
+
assert_equal('/abc@xyz/123%20%00+789%25ff', p.to_uri)
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_normalize
|
107
|
+
p = UCP.new('/foo/')
|
108
|
+
p.normalize!
|
109
|
+
assert_equal('/foo', p.to_uri)
|
110
|
+
|
111
|
+
p = UCP.new('/foo/./bar')
|
112
|
+
p.normalize!
|
113
|
+
assert_equal('/foo/bar', p.to_uri)
|
114
|
+
|
115
|
+
p = UCP.new('/foo/./bar/baz/.')
|
116
|
+
p.normalize!
|
117
|
+
assert_equal('/foo/bar/baz', p.to_uri)
|
118
|
+
|
119
|
+
p = UCP.new('/foo/../bar')
|
120
|
+
p.normalize!
|
121
|
+
assert_equal('/bar', p.to_uri)
|
122
|
+
|
123
|
+
p = UCP.new('/foo/../../../bar')
|
124
|
+
p.normalize!
|
125
|
+
assert_equal('/bar', p.to_uri)
|
126
|
+
|
127
|
+
p = UCP.new('/foo/./../bar')
|
128
|
+
p.normalize!
|
129
|
+
assert_equal('/bar', p.to_uri)
|
130
|
+
|
131
|
+
p = UCP.new('/foo//bar')
|
132
|
+
p.normalize!
|
133
|
+
assert_equal('/foo/bar', p.to_uri)
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_mixin
|
137
|
+
UCP.mixin(URI::HTTPS)
|
138
|
+
|
139
|
+
u_uri = 'https://example.jp/abc%40xyz/123+%00%2B789%25ff'
|
140
|
+
u_uri_x = u_uri.gsub('%40','@').gsub('%2B', '+')
|
141
|
+
u = URI.parse(u_uri)
|
142
|
+
p = u.path_component
|
143
|
+
assert_kind_of(URI::HTTPS, u)
|
144
|
+
assert_kind_of(UCP, p)
|
145
|
+
assert_equal(u_uri_x, u.to_s)
|
146
|
+
assert_equal('/abc@xyz/123+%00+789%25ff', u.path)
|
147
|
+
assert_equal('/abc@xyz/123+%00+789%25ff', p.to_s)
|
148
|
+
|
149
|
+
p.nodes << 'xxx'
|
150
|
+
assert_equal(u_uri_x + '/xxx', u.to_s)
|
151
|
+
assert_equal('/abc@xyz/123+%00+789%25ff/xxx', u.path)
|
152
|
+
assert_equal('/abc@xyz/123+%00+789%25ff/xxx', p.to_s)
|
153
|
+
|
154
|
+
u_uri.sub!(/^https:/, 'http:')
|
155
|
+
u_uri_x = u_uri.gsub('%40','@').gsub('%2B', '+')
|
156
|
+
u = URI.parse(u_uri)
|
157
|
+
assert_raise(NoMethodError) do
|
158
|
+
u.path_component
|
159
|
+
end
|
160
|
+
|
161
|
+
UCP.mixin(URI::HTTP)
|
162
|
+
u = URI.parse(u_uri)
|
163
|
+
p = u.path_component
|
164
|
+
assert_kind_of(URI::HTTP, u)
|
165
|
+
assert_kind_of(UCP, u.path_component)
|
166
|
+
assert_equal(u_uri_x, u.to_s)
|
167
|
+
assert_equal('/abc@xyz/123+%00+789%25ff', u.path)
|
168
|
+
assert_equal('/abc@xyz/123+%00+789%25ff', p.to_s)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'uri/component/query'
|
3
|
+
|
4
|
+
UCQ = URI::Component::Query
|
5
|
+
|
6
|
+
module URI
|
7
|
+
module Component
|
8
|
+
|
9
|
+
class TestQueryClass < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_parse
|
17
|
+
q_uri = ''
|
18
|
+
q = UCQ.new(q_uri)
|
19
|
+
assert_equal(q_uri, q.to_uri)
|
20
|
+
assert_empty(q.params)
|
21
|
+
|
22
|
+
q_uri = 'foo=1'
|
23
|
+
q = UCQ.new(q_uri)
|
24
|
+
assert_equal(q_uri, q.to_uri)
|
25
|
+
assert_equal(1, q.params.size)
|
26
|
+
assert_equal(1, q.params['foo'].size)
|
27
|
+
assert_equal('1', q.params['foo'][0])
|
28
|
+
|
29
|
+
q_uri = 'foo'
|
30
|
+
q = UCQ.new(q_uri)
|
31
|
+
assert_equal(q_uri, q.to_uri)
|
32
|
+
assert_equal(1, q.params.size)
|
33
|
+
assert_equal(1, q.params['foo'].size)
|
34
|
+
assert_nil(q.params['foo'][0])
|
35
|
+
|
36
|
+
q_uri = 'foo=123%20abc'
|
37
|
+
q = UCQ.new(q_uri)
|
38
|
+
assert_equal(q_uri.gsub('%20', '+'), q.to_uri)
|
39
|
+
assert_equal(1, q.params.size)
|
40
|
+
assert_equal(1, q.params['foo'].size)
|
41
|
+
assert_equal('123 abc', q.params['foo'][0])
|
42
|
+
|
43
|
+
q_uri = 'foo=123+abc%2BABC'
|
44
|
+
q = UCQ.new(q_uri)
|
45
|
+
assert_equal(q_uri, q.to_uri)
|
46
|
+
assert_equal(1, q.params.size)
|
47
|
+
assert_equal(1, q.params['foo'].size)
|
48
|
+
assert_equal('123 abc+ABC', q.params['foo'][0])
|
49
|
+
|
50
|
+
q_uri = 'foo=1&bar=abc%40xyz&baz=123%20%00%2B789'
|
51
|
+
q = UCQ.new(q_uri)
|
52
|
+
assert_equal(q_uri.gsub('%20', '+'), q.to_uri)
|
53
|
+
assert_equal(3, q.params.size)
|
54
|
+
assert_equal(1, q.params['foo'].size)
|
55
|
+
assert_equal('1', q.params['foo'][0])
|
56
|
+
assert_equal(1, q.params['bar'].size)
|
57
|
+
assert_equal('abc@xyz', q.params['bar'][0])
|
58
|
+
assert_equal(1, q.params['baz'].size)
|
59
|
+
assert_equal("123 \x00+789", q.params['baz'][0])
|
60
|
+
|
61
|
+
q_uri = 'foo=1&bar=a&foo=2&bar=bb&bar=ccc'
|
62
|
+
q = UCQ.new(q_uri)
|
63
|
+
assert_equal('foo=1&foo=2&bar=a&bar=bb&bar=ccc', q.to_uri)
|
64
|
+
assert_equal(2, q.params.size)
|
65
|
+
assert_equal(2, q.params['foo'].size)
|
66
|
+
assert_equal('1', q.params['foo'][0])
|
67
|
+
assert_equal('2', q.params['foo'][1])
|
68
|
+
assert_equal(3, q.params['bar'].size)
|
69
|
+
assert_equal('a', q.params['bar'][0])
|
70
|
+
assert_equal('bb', q.params['bar'][1])
|
71
|
+
assert_equal('ccc', q.params['bar'][2])
|
72
|
+
|
73
|
+
q_uri = 'foo=1&foo&bar&baz=a'
|
74
|
+
q = UCQ.new(q_uri)
|
75
|
+
assert_equal(q_uri, q.to_uri)
|
76
|
+
assert_equal(3, q.params.size)
|
77
|
+
assert_equal(2, q.params['foo'].size)
|
78
|
+
assert_equal('1', q.params['foo'][0])
|
79
|
+
assert_nil(q.params['foo'][1])
|
80
|
+
assert_equal(1, q.params['bar'].size)
|
81
|
+
assert_nil(q.params['bar'][0])
|
82
|
+
assert_equal(1, q.params['baz'].size)
|
83
|
+
assert_equal('a', q.params['baz'][0])
|
84
|
+
|
85
|
+
q_uri = 'foo=1;bar=abc;baz=ABC'
|
86
|
+
q = UCQ.new(q_uri)
|
87
|
+
assert_equal(q_uri.gsub(';', '&'), q.to_uri)
|
88
|
+
assert_equal(q_uri, q.to_uri(';'))
|
89
|
+
assert_equal(3, q.params.size)
|
90
|
+
assert_equal(1, q.params['foo'].size)
|
91
|
+
assert_equal('1', q.params['foo'][0])
|
92
|
+
assert_equal(1, q.params['bar'].size)
|
93
|
+
assert_equal('abc', q.params['bar'][0])
|
94
|
+
assert_equal(1, q.params['baz'].size)
|
95
|
+
assert_equal('ABC', q.params['baz'][0])
|
96
|
+
|
97
|
+
assert_raise(URI::InvalidURIError) do
|
98
|
+
UCQ.new('foo bar')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_set
|
103
|
+
q = UCQ.new('')
|
104
|
+
q.params['foo'] = [1]
|
105
|
+
assert_equal('foo=1', q.to_uri)
|
106
|
+
|
107
|
+
q = UCQ.new('')
|
108
|
+
q.params['foo'] = [nil]
|
109
|
+
assert_equal('foo', q.to_uri)
|
110
|
+
|
111
|
+
q = UCQ.new('')
|
112
|
+
q.params['foo'] = ['123 abc']
|
113
|
+
assert_equal('foo=123+abc', q.to_uri)
|
114
|
+
|
115
|
+
q = UCQ.new('')
|
116
|
+
q.params['foo'] = ['123+abc']
|
117
|
+
assert_equal('foo=123%2Babc', q.to_uri)
|
118
|
+
|
119
|
+
q = UCQ.new('')
|
120
|
+
q.params['foo'] = [1]
|
121
|
+
q.params['bar'] = ['abc@xyz']
|
122
|
+
q.params['baz'] = ["123 \x00+789"]
|
123
|
+
assert_equal('foo=1&bar=abc%40xyz&baz=123+%00%2B789', q.to_uri)
|
124
|
+
|
125
|
+
q = UCQ.new('')
|
126
|
+
q.params['foo'] = [1, 2]
|
127
|
+
q.params['bar'] = ['a', 'bb', 'ccc']
|
128
|
+
assert_equal('foo=1&foo=2&bar=a&bar=bb&bar=ccc', q.to_uri)
|
129
|
+
|
130
|
+
q = UCQ.new('')
|
131
|
+
q.params['foo'] = [1, nil]
|
132
|
+
q.params['bar'] = [nil]
|
133
|
+
q.params['baz'] = ['a']
|
134
|
+
assert_equal('foo=1&foo&bar&baz=a', q.to_uri)
|
135
|
+
|
136
|
+
q = UCQ.new('')
|
137
|
+
q.params['foo'] = [1]
|
138
|
+
q.params['bar'] = ['abc']
|
139
|
+
q.params['baz'] = ['ABC']
|
140
|
+
assert_equal('foo=1;bar=abc;baz=ABC', q.to_uri(';'))
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_mixin
|
144
|
+
UCQ.mixin(URI::HTTPS)
|
145
|
+
|
146
|
+
u_uri = 'https://example.jp/?foo=123%40example&bar=abc%20xyz'
|
147
|
+
u_uri_x = u_uri.gsub('+', '%2B').gsub('%20', '+')
|
148
|
+
u = URI.parse(u_uri)
|
149
|
+
q = u.query_component
|
150
|
+
assert_kind_of(UCQ, q)
|
151
|
+
assert_equal(u_uri_x, u.to_s)
|
152
|
+
assert_equal('foo=123%40example&bar=abc+xyz', u.query)
|
153
|
+
assert_equal('foo=123%40example&bar=abc+xyz', q.to_s)
|
154
|
+
|
155
|
+
q.params['baz'] = ['xxx']
|
156
|
+
assert_equal(u_uri_x + '&baz=xxx', u.to_s)
|
157
|
+
assert_equal('foo=123%40example&bar=abc+xyz&baz=xxx', u.query)
|
158
|
+
assert_equal('foo=123%40example&bar=abc+xyz&baz=xxx', q.to_s)
|
159
|
+
|
160
|
+
u_uri.sub!(/^https:/, 'http:')
|
161
|
+
u_uri_x = u_uri.gsub('+', '%2B').gsub('%20', '+')
|
162
|
+
u = URI.parse(u_uri)
|
163
|
+
assert_raise(NoMethodError) do
|
164
|
+
u.query_component
|
165
|
+
end
|
166
|
+
|
167
|
+
UCQ.mixin(URI::HTTP)
|
168
|
+
u = URI.parse(u_uri)
|
169
|
+
q = u.query_component
|
170
|
+
assert_kind_of(UCQ, q)
|
171
|
+
assert_equal(u_uri_x, u.to_s)
|
172
|
+
assert_equal('foo=123%40example&bar=abc+xyz', u.query)
|
173
|
+
assert_equal('foo=123%40example&bar=abc+xyz', q.to_s)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'uri/component/userinfo'
|
3
|
+
|
4
|
+
UCUI = URI::Component::UserInfo
|
5
|
+
|
6
|
+
module URI
|
7
|
+
module Component
|
8
|
+
|
9
|
+
class TestUserInfoClass < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_parse
|
17
|
+
i = UCUI.new()
|
18
|
+
assert_nil(i.to_uri)
|
19
|
+
assert_nil(i.domain)
|
20
|
+
assert_nil(i.user)
|
21
|
+
assert_nil(i.password)
|
22
|
+
|
23
|
+
i_uri = 'user%20name'
|
24
|
+
i = UCUI.new(i_uri)
|
25
|
+
assert_equal(i_uri, i.to_uri)
|
26
|
+
assert_nil(i.domain)
|
27
|
+
assert_equal('user name', i.user)
|
28
|
+
assert_nil(i.password)
|
29
|
+
|
30
|
+
i_uri = 'user%20name:p%40ssword'
|
31
|
+
i = UCUI.new(i_uri)
|
32
|
+
assert_equal(i_uri, i.to_uri)
|
33
|
+
assert_nil(i.domain)
|
34
|
+
assert_equal('user name', i.user)
|
35
|
+
assert_equal('p@ssword', i.password)
|
36
|
+
|
37
|
+
i_uri = 'domain%20name;user%20name'
|
38
|
+
i = UCUI.new(i_uri)
|
39
|
+
assert_equal(i_uri, i.to_uri)
|
40
|
+
assert_equal('domain name', i.domain)
|
41
|
+
assert_equal('user name', i.user)
|
42
|
+
assert_nil(i.password)
|
43
|
+
|
44
|
+
i_uri = 'domain%20name;user%20name:p%40ssword'
|
45
|
+
i = UCUI.new(i_uri)
|
46
|
+
assert_equal(i_uri, i.to_uri)
|
47
|
+
assert_equal('domain name', i.domain)
|
48
|
+
assert_equal('user name', i.user)
|
49
|
+
assert_equal('p@ssword', i.password)
|
50
|
+
|
51
|
+
%w(foo/bar1 foo@bar2 foo?bar3 foo:bar:baz4 foo;bar;baz5).each do |info_str|
|
52
|
+
assert_raise(URI::InvalidURIError) do
|
53
|
+
UCUI.new(info_str)
|
54
|
+
raise info_str
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_modify
|
60
|
+
i = UCUI.new('domain%5Fname;user%20name:p%40ssword')
|
61
|
+
|
62
|
+
i.domain = 'domain2'
|
63
|
+
assert_equal('domain2', i.domain)
|
64
|
+
assert_equal('domain2;user%20name:p%40ssword', i.to_uri)
|
65
|
+
i.domain = nil
|
66
|
+
assert_nil(i.domain)
|
67
|
+
assert_equal('user%20name:p%40ssword', i.to_uri)
|
68
|
+
|
69
|
+
i.password = 'password2'
|
70
|
+
assert_equal('password2', i.password)
|
71
|
+
assert_equal('user%20name:password2', i.to_uri)
|
72
|
+
i.password = nil
|
73
|
+
assert_nil(i.password)
|
74
|
+
assert_equal('user%20name', i.to_uri)
|
75
|
+
|
76
|
+
i.domain = 'domain %20_3'
|
77
|
+
assert_equal('domain %20_3', i.domain)
|
78
|
+
assert_equal('domain%20%2520_3;user%20name', i.to_uri)
|
79
|
+
|
80
|
+
i.password = 'password %20_3'
|
81
|
+
assert_equal('password %20_3', i.password)
|
82
|
+
assert_equal('domain%20%2520_3;user%20name:password%20%2520_3', i.to_uri)
|
83
|
+
|
84
|
+
i.user = 'user2'
|
85
|
+
assert_equal('user2', i.user)
|
86
|
+
assert_equal('domain%20%2520_3;user2:password%20%2520_3', i.to_uri)
|
87
|
+
i.user = nil
|
88
|
+
assert_nil(i.user)
|
89
|
+
assert_nil(i.to_uri)
|
90
|
+
|
91
|
+
assert_raise(URI::InvalidURIError) do
|
92
|
+
i.domain = 'domain4'
|
93
|
+
end
|
94
|
+
assert_raise(URI::InvalidURIError) do
|
95
|
+
i.password = 'password4'
|
96
|
+
end
|
97
|
+
|
98
|
+
i.user = 'user %20_3'
|
99
|
+
assert_equal('user %20_3', i.user)
|
100
|
+
assert_equal('user%20%2520_3', i.to_uri)
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_mixin
|
104
|
+
UCUI.mixin(URI::HTTPS)
|
105
|
+
|
106
|
+
u_uri = 'https://user%20name:p%40ssword@example.jp/'
|
107
|
+
u = URI.parse(u_uri)
|
108
|
+
i = u.userinfo_component
|
109
|
+
assert_kind_of(UCUI, i)
|
110
|
+
assert_equal('user%20name:p%40ssword', u.userinfo)
|
111
|
+
assert_equal('user%20name', u.user)
|
112
|
+
assert_equal('user name', i.user)
|
113
|
+
assert_equal('p%40ssword', u.password)
|
114
|
+
assert_equal('p@ssword', i.password)
|
115
|
+
assert_nil(i.domain)
|
116
|
+
|
117
|
+
u.user = 'user%2Fname'
|
118
|
+
assert_equal('user%2Fname:p%40ssword', u.userinfo)
|
119
|
+
assert_equal('user%2Fname', u.user)
|
120
|
+
assert_equal('user/name', i.user)
|
121
|
+
assert_nil(i.domain)
|
122
|
+
|
123
|
+
u.password = 'pass%2Fword'
|
124
|
+
assert_equal('user%2Fname:pass%2Fword', u.userinfo)
|
125
|
+
assert_equal('pass%2Fword', u.password)
|
126
|
+
assert_equal('pass/word', i.password)
|
127
|
+
assert_nil(i.domain)
|
128
|
+
|
129
|
+
u.user = 'domain;user%3Bname'
|
130
|
+
assert_equal('domain;user%3Bname:pass%2Fword', u.userinfo)
|
131
|
+
assert_equal('domain;user%3Bname', u.user)
|
132
|
+
assert_equal('domain', i.domain)
|
133
|
+
assert_equal('user;name', i.user)
|
134
|
+
|
135
|
+
assert_equal('https://domain;user%3Bname:pass%2Fword@example.jp/', u.to_s)
|
136
|
+
|
137
|
+
u_uri.sub!(/^https:/, 'http:')
|
138
|
+
u = URI.parse(u_uri)
|
139
|
+
assert_raise(NoMethodError) do
|
140
|
+
u.userinfo_component
|
141
|
+
end
|
142
|
+
|
143
|
+
UCUI.mixin(URI::HTTP)
|
144
|
+
u = URI.parse(u_uri)
|
145
|
+
i = u.userinfo_component
|
146
|
+
assert_kind_of(UCUI, i)
|
147
|
+
assert_equal('user%20name:p%40ssword', u.userinfo)
|
148
|
+
assert_equal('user%20name', u.user)
|
149
|
+
assert_equal('user name', i.user)
|
150
|
+
assert_equal('p%40ssword', u.password)
|
151
|
+
assert_equal('p@ssword', i.password)
|
152
|
+
assert_nil(i.domain)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "uri/component/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "uri-component"
|
7
|
+
s.version = URI::Component::VERSION
|
8
|
+
s.authors = ["SATOH Fumiyasu"]
|
9
|
+
s.email = ["fumiyas@osstech.co.jp"]
|
10
|
+
s.homepage = "https://github.com/fumiyas/ruby-uri-component"
|
11
|
+
s.summary = %q{URI::Component::* classes}
|
12
|
+
s.description = %q{Handle URI components as an object}
|
13
|
+
|
14
|
+
s.rubyforge_project = "uri-component"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
end
|
21
|
+
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: uri-component
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- SATOH Fumiyasu
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-11-04 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Handle URI components as an object
|
15
|
+
email:
|
16
|
+
- fumiyas@osstech.co.jp
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- Gemfile
|
22
|
+
- Rakefile
|
23
|
+
- lib/uri/component/path.rb
|
24
|
+
- lib/uri/component/query.rb
|
25
|
+
- lib/uri/component/userinfo.rb
|
26
|
+
- lib/uri/component/version.rb
|
27
|
+
- test/test_component_path.rb
|
28
|
+
- test/test_component_query.rb
|
29
|
+
- test/test_component_userinfo.rb
|
30
|
+
- uri-compoment.gemspec
|
31
|
+
homepage: https://github.com/fumiyas/ruby-uri-component
|
32
|
+
licenses: []
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
requirements: []
|
50
|
+
rubyforge_project: uri-component
|
51
|
+
rubygems_version: 1.8.11
|
52
|
+
signing_key:
|
53
|
+
specification_version: 3
|
54
|
+
summary: URI::Component::* classes
|
55
|
+
test_files:
|
56
|
+
- test/test_component_path.rb
|
57
|
+
- test/test_component_query.rb
|
58
|
+
- test/test_component_userinfo.rb
|