rubysl-uri 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/lib/rubysl/uri.rb +1 -1
- data/lib/rubysl/uri/uri.rb +88 -6
- data/lib/rubysl/uri/version.rb +1 -1
- data/lib/uri/common.rb +621 -233
- data/lib/uri/ftp.rb +81 -22
- data/lib/uri/generic.rb +665 -115
- data/lib/uri/http.rb +25 -19
- data/lib/uri/https.rb +4 -2
- data/lib/uri/ldap.rb +75 -5
- data/lib/uri/ldaps.rb +8 -0
- data/lib/uri/mailto.rb +36 -22
- data/rubysl-uri.gemspec +2 -0
- metadata +4 -4
data/lib/uri/ftp.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
#
|
2
1
|
# = uri/ftp.rb
|
3
2
|
#
|
4
3
|
# Author:: Akira Yamada <akira@ruby-lang.org>
|
5
4
|
# License:: You can redistribute it and/or modify it under the same term as Ruby.
|
6
|
-
# Revision:: $Id
|
5
|
+
# Revision:: $Id$
|
6
|
+
#
|
7
|
+
# See URI for general documentation
|
7
8
|
#
|
8
9
|
|
9
10
|
require 'uri/generic'
|
@@ -13,26 +14,42 @@ module URI
|
|
13
14
|
#
|
14
15
|
# FTP URI syntax is defined by RFC1738 section 3.2.
|
15
16
|
#
|
17
|
+
# This class will be redesigned because of difference of implementations;
|
18
|
+
# the structure of its path. draft-hoffman-ftp-uri-04 is a draft but it
|
19
|
+
# is a good summary about the de facto spec.
|
20
|
+
# http://tools.ietf.org/html/draft-hoffman-ftp-uri-04
|
21
|
+
#
|
16
22
|
class FTP < Generic
|
23
|
+
# A Default port of 21 for URI::FTP
|
17
24
|
DEFAULT_PORT = 21
|
18
25
|
|
26
|
+
#
|
27
|
+
# An Array of the available components for URI::FTP
|
28
|
+
#
|
19
29
|
COMPONENT = [
|
20
|
-
:scheme,
|
30
|
+
:scheme,
|
21
31
|
:userinfo, :host, :port,
|
22
32
|
:path, :typecode
|
23
33
|
].freeze
|
34
|
+
|
24
35
|
#
|
25
|
-
# Typecode is "a", "i" or "d".
|
36
|
+
# Typecode is "a", "i" or "d".
|
26
37
|
#
|
27
38
|
# * "a" indicates a text file (the FTP command was ASCII)
|
28
39
|
# * "i" indicates a binary file (FTP command IMAGE)
|
29
40
|
# * "d" indicates the contents of a directory should be displayed
|
30
41
|
#
|
31
42
|
TYPECODE = ['a', 'i', 'd'].freeze
|
43
|
+
|
44
|
+
# Typecode prefix
|
45
|
+
# ';type='
|
32
46
|
TYPECODE_PREFIX = ';type='.freeze
|
33
47
|
|
34
|
-
def self.new2(user, password, host, port, path,
|
35
|
-
typecode = nil, arg_check = true)
|
48
|
+
def self.new2(user, password, host, port, path,
|
49
|
+
typecode = nil, arg_check = true) # :nodoc:
|
50
|
+
# Do not use this method! Not tested. [Bug #7301]
|
51
|
+
# This methods remains just for compatibility,
|
52
|
+
# Keep it undocumented until the active maintainer is assigned.
|
36
53
|
typecode = nil if typecode.size == 0
|
37
54
|
if typecode && !TYPECODE.include?(typecode)
|
38
55
|
raise ArgumentError,
|
@@ -42,22 +59,22 @@ module URI
|
|
42
59
|
# do escape
|
43
60
|
|
44
61
|
self.new('ftp',
|
45
|
-
[user, password],
|
46
|
-
host, port, nil,
|
47
|
-
typecode ? path + TYPECODE_PREFIX + typecode : path,
|
62
|
+
[user, password],
|
63
|
+
host, port, nil,
|
64
|
+
typecode ? path + TYPECODE_PREFIX + typecode : path,
|
48
65
|
nil, nil, nil, arg_check)
|
49
66
|
end
|
50
67
|
|
51
68
|
#
|
52
69
|
# == Description
|
53
70
|
#
|
54
|
-
# Creates a new URI::FTP object from components, with syntax checking.
|
71
|
+
# Creates a new URI::FTP object from components, with syntax checking.
|
55
72
|
#
|
56
|
-
# The components accepted are +userinfo+, +host+, +port+, +path+ and
|
73
|
+
# The components accepted are +userinfo+, +host+, +port+, +path+ and
|
57
74
|
# +typecode+.
|
58
75
|
#
|
59
|
-
# The components should be provided either as an Array, or as a Hash
|
60
|
-
# with keys formed by preceding the component names with a colon.
|
76
|
+
# The components should be provided either as an Array, or as a Hash
|
77
|
+
# with keys formed by preceding the component names with a colon.
|
61
78
|
#
|
62
79
|
# If an Array is used, the components must be passed in the order
|
63
80
|
# [userinfo, host, port, path, typecode]
|
@@ -67,11 +84,11 @@ module URI
|
|
67
84
|
#
|
68
85
|
# require 'uri'
|
69
86
|
#
|
70
|
-
# uri = URI::FTP.build(['user:password', 'ftp.example.com', nil,
|
87
|
+
# uri = URI::FTP.build(['user:password', 'ftp.example.com', nil,
|
71
88
|
# '/path/file.> zip', 'i'])
|
72
89
|
# puts uri.to_s -> ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=a
|
73
90
|
#
|
74
|
-
# uri2 = URI::FTP.build({:host => 'ftp.example.com',
|
91
|
+
# uri2 = URI::FTP.build({:host => 'ftp.example.com',
|
75
92
|
# :path => 'ruby/src'})
|
76
93
|
# puts uri2.to_s -> ftp://ftp.example.com/ruby/src
|
77
94
|
#
|
@@ -92,7 +109,7 @@ module URI
|
|
92
109
|
|
93
110
|
if tmp[:typecode]
|
94
111
|
if tmp[:typecode].size == 1
|
95
|
-
tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode]
|
112
|
+
tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode]
|
96
113
|
end
|
97
114
|
tmp[:path] << tmp[:typecode]
|
98
115
|
end
|
@@ -109,17 +126,19 @@ module URI
|
|
109
126
|
# Unlike build(), this method does not escape the path component as
|
110
127
|
# required by RFC1738; instead it is treated as per RFC2396.
|
111
128
|
#
|
112
|
-
# Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+,
|
129
|
+
# Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+,
|
113
130
|
# +opaque+, +query+ and +fragment+, in that order.
|
114
131
|
#
|
115
132
|
def initialize(*arg)
|
133
|
+
raise InvalidURIError unless arg[5]
|
134
|
+
arg[5] = arg[5].sub(/^\//,'').sub(/^%2F/,'/')
|
116
135
|
super(*arg)
|
117
136
|
@typecode = nil
|
118
137
|
tmp = @path.index(TYPECODE_PREFIX)
|
119
138
|
if tmp
|
120
139
|
typecode = @path[tmp + TYPECODE_PREFIX.size..-1]
|
121
|
-
|
122
|
-
|
140
|
+
@path = @path[0..tmp - 1]
|
141
|
+
|
123
142
|
if arg[-1]
|
124
143
|
self.typecode = typecode
|
125
144
|
else
|
@@ -127,8 +146,15 @@ module URI
|
|
127
146
|
end
|
128
147
|
end
|
129
148
|
end
|
149
|
+
|
150
|
+
# typecode accessor
|
151
|
+
#
|
152
|
+
# see URI::FTP::COMPONENT
|
130
153
|
attr_reader :typecode
|
131
154
|
|
155
|
+
# validates typecode +v+,
|
156
|
+
# returns a +true+ or +false+ boolean
|
157
|
+
#
|
132
158
|
def check_typecode(v)
|
133
159
|
if TYPECODE.include?(v)
|
134
160
|
return true
|
@@ -139,11 +165,39 @@ module URI
|
|
139
165
|
end
|
140
166
|
private :check_typecode
|
141
167
|
|
168
|
+
# private setter for the typecode +v+
|
169
|
+
#
|
170
|
+
# see also URI::FTP.typecode=
|
171
|
+
#
|
142
172
|
def set_typecode(v)
|
143
173
|
@typecode = v
|
144
174
|
end
|
145
175
|
protected :set_typecode
|
146
176
|
|
177
|
+
#
|
178
|
+
# == Args
|
179
|
+
#
|
180
|
+
# +v+::
|
181
|
+
# String
|
182
|
+
#
|
183
|
+
# == Description
|
184
|
+
#
|
185
|
+
# public setter for the typecode +v+.
|
186
|
+
# (with validation)
|
187
|
+
#
|
188
|
+
# see also URI::FTP.check_typecode
|
189
|
+
#
|
190
|
+
# == Usage
|
191
|
+
#
|
192
|
+
# require 'uri'
|
193
|
+
#
|
194
|
+
# uri = URI.parse("ftp://john@ftp.example.com/my_file.img")
|
195
|
+
# #=> #<URI::FTP:0x00000000923650 URL:ftp://john@ftp.example.com/my_file.img>
|
196
|
+
# uri.typecode = "i"
|
197
|
+
# # => "i"
|
198
|
+
# uri
|
199
|
+
# #=> #<URI::FTP:0x00000000923650 URL:ftp://john@ftp.example.com/my_file.img;type=i>
|
200
|
+
#
|
147
201
|
def typecode=(typecode)
|
148
202
|
check_typecode(typecode)
|
149
203
|
set_typecode(typecode)
|
@@ -164,9 +218,9 @@ module URI
|
|
164
218
|
# RFC 1738 specifically states that the path for an FTP URI does not
|
165
219
|
# include the / which separates the URI path from the URI host. Example:
|
166
220
|
#
|
167
|
-
# ftp://ftp.example.com/pub/ruby
|
221
|
+
# ftp://ftp.example.com/pub/ruby
|
168
222
|
#
|
169
|
-
# The above URI indicates that the client should connect to
|
223
|
+
# The above URI indicates that the client should connect to
|
170
224
|
# ftp.example.com then cd pub/ruby from the initial login directory.
|
171
225
|
#
|
172
226
|
# If you want to cd to an absolute directory, you must include an
|
@@ -177,8 +231,13 @@ module URI
|
|
177
231
|
# This method will then return "/pub/ruby"
|
178
232
|
#
|
179
233
|
def path
|
180
|
-
return @path.sub(/^\//,'').sub(/^%2F
|
234
|
+
return @path.sub(/^\//,'').sub(/^%2F/,'/')
|
235
|
+
end
|
236
|
+
|
237
|
+
def set_path(v)
|
238
|
+
super("/" + v.sub(/^\//, "%2F"))
|
181
239
|
end
|
240
|
+
protected :set_path
|
182
241
|
|
183
242
|
def to_s
|
184
243
|
save_path = nil
|
data/lib/uri/generic.rb
CHANGED
@@ -1,23 +1,26 @@
|
|
1
|
-
#
|
2
1
|
# = uri/generic.rb
|
3
2
|
#
|
4
3
|
# Author:: Akira Yamada <akira@ruby-lang.org>
|
5
4
|
# License:: You can redistribute it and/or modify it under the same term as Ruby.
|
6
|
-
# Revision:: $Id
|
5
|
+
# Revision:: $Id$
|
6
|
+
#
|
7
|
+
# See URI for general documentation
|
7
8
|
#
|
8
9
|
|
9
10
|
require 'uri/common'
|
10
11
|
|
11
12
|
module URI
|
12
|
-
|
13
|
+
|
13
14
|
#
|
14
15
|
# Base class for all URI classes.
|
15
16
|
# Implements generic URI syntax as per RFC 2396.
|
16
17
|
#
|
17
18
|
class Generic
|
18
19
|
include URI
|
19
|
-
include REGEXP
|
20
20
|
|
21
|
+
#
|
22
|
+
# A Default port of nil for URI::Generic
|
23
|
+
#
|
21
24
|
DEFAULT_PORT = nil
|
22
25
|
|
23
26
|
#
|
@@ -27,15 +30,21 @@ module URI
|
|
27
30
|
self::DEFAULT_PORT
|
28
31
|
end
|
29
32
|
|
33
|
+
#
|
34
|
+
# Returns default port
|
35
|
+
#
|
30
36
|
def default_port
|
31
37
|
self.class.default_port
|
32
38
|
end
|
33
39
|
|
40
|
+
#
|
41
|
+
# An Array of the available components for URI::Generic
|
42
|
+
#
|
34
43
|
COMPONENT = [
|
35
|
-
:scheme,
|
36
|
-
:userinfo, :host, :port, :registry,
|
37
|
-
:path, :opaque,
|
38
|
-
:query,
|
44
|
+
:scheme,
|
45
|
+
:userinfo, :host, :port, :registry,
|
46
|
+
:path, :opaque,
|
47
|
+
:query,
|
39
48
|
:fragment
|
40
49
|
].freeze
|
41
50
|
|
@@ -46,10 +55,14 @@ module URI
|
|
46
55
|
self::COMPONENT
|
47
56
|
end
|
48
57
|
|
58
|
+
#
|
59
|
+
# Default to not use the registry for a URI::Generic
|
60
|
+
#
|
49
61
|
USE_REGISTRY = false
|
50
62
|
|
51
63
|
#
|
52
|
-
#
|
64
|
+
# Returns whether a registry of naming
|
65
|
+
# authorities are being used.
|
53
66
|
#
|
54
67
|
def self.use_registry
|
55
68
|
self::USE_REGISTRY
|
@@ -63,7 +76,7 @@ module URI
|
|
63
76
|
# == Description
|
64
77
|
#
|
65
78
|
# At first, tries to create a new URI::Generic instance using
|
66
|
-
# URI::Generic::build. But, if exception URI::InvalidComponentError is raised,
|
79
|
+
# URI::Generic::build. But, if exception URI::InvalidComponentError is raised,
|
67
80
|
# then it URI::Escape.escape all URI components and tries again.
|
68
81
|
#
|
69
82
|
#
|
@@ -72,9 +85,9 @@ module URI
|
|
72
85
|
return self.build(args)
|
73
86
|
rescue InvalidComponentError
|
74
87
|
if args.kind_of?(Array)
|
75
|
-
return self.build(args.collect{|x|
|
76
|
-
if x
|
77
|
-
|
88
|
+
return self.build(args.collect{|x|
|
89
|
+
if x.is_a?(String)
|
90
|
+
DEFAULT_PARSER.escape(x)
|
78
91
|
else
|
79
92
|
x
|
80
93
|
end
|
@@ -83,7 +96,7 @@ module URI
|
|
83
96
|
tmp = {}
|
84
97
|
args.each do |key, value|
|
85
98
|
tmp[key] = if value
|
86
|
-
|
99
|
+
DEFAULT_PARSER.escape(value)
|
87
100
|
else
|
88
101
|
value
|
89
102
|
end
|
@@ -108,7 +121,7 @@ module URI
|
|
108
121
|
def self.build(args)
|
109
122
|
if args.kind_of?(Array) &&
|
110
123
|
args.size == ::URI::Generic::COMPONENT.size
|
111
|
-
tmp = args
|
124
|
+
tmp = args.dup
|
112
125
|
elsif args.kind_of?(Hash)
|
113
126
|
tmp = ::URI::Generic::COMPONENT.collect do |c|
|
114
127
|
if args.include?(c)
|
@@ -118,10 +131,12 @@ module URI
|
|
118
131
|
end
|
119
132
|
end
|
120
133
|
else
|
121
|
-
|
122
|
-
|
134
|
+
component = self.class.component rescue ::URI::Generic::COMPONENT
|
135
|
+
raise ArgumentError,
|
136
|
+
"expected Array of or Hash of components of #{self.class} (#{component.join(', ')})"
|
123
137
|
end
|
124
138
|
|
139
|
+
tmp << nil
|
125
140
|
tmp << true
|
126
141
|
return self.new(*tmp)
|
127
142
|
end
|
@@ -137,15 +152,17 @@ module URI
|
|
137
152
|
# +port+::
|
138
153
|
# Server port
|
139
154
|
# +registry+::
|
140
|
-
#
|
155
|
+
# Registry of naming authorities.
|
141
156
|
# +path+::
|
142
157
|
# Path on server
|
143
158
|
# +opaque+::
|
144
|
-
#
|
159
|
+
# Opaque part
|
145
160
|
# +query+::
|
146
161
|
# Query data
|
147
162
|
# +fragment+::
|
148
163
|
# A part of URI after '#' sign
|
164
|
+
# +parser+::
|
165
|
+
# Parser for internal use [URI::DEFAULT_PARSER by default]
|
149
166
|
# +arg_check+::
|
150
167
|
# Check arguments [false by default]
|
151
168
|
#
|
@@ -153,11 +170,12 @@ module URI
|
|
153
170
|
#
|
154
171
|
# Creates a new URI::Generic instance from ``generic'' components without check.
|
155
172
|
#
|
156
|
-
def initialize(scheme,
|
157
|
-
userinfo, host, port, registry,
|
158
|
-
path, opaque,
|
159
|
-
query,
|
173
|
+
def initialize(scheme,
|
174
|
+
userinfo, host, port, registry,
|
175
|
+
path, opaque,
|
176
|
+
query,
|
160
177
|
fragment,
|
178
|
+
parser = DEFAULT_PARSER,
|
161
179
|
arg_check = false)
|
162
180
|
@scheme = nil
|
163
181
|
@user = nil
|
@@ -169,6 +187,7 @@ module URI
|
|
169
187
|
@opaque = nil
|
170
188
|
@registry = nil
|
171
189
|
@fragment = nil
|
190
|
+
@parser = parser == DEFAULT_PARSER ? nil : parser
|
172
191
|
|
173
192
|
if arg_check
|
174
193
|
self.scheme = scheme
|
@@ -192,23 +211,98 @@ module URI
|
|
192
211
|
self.set_fragment(fragment)
|
193
212
|
end
|
194
213
|
if @registry && !self.class.use_registry
|
195
|
-
raise InvalidURIError,
|
214
|
+
raise InvalidURIError,
|
196
215
|
"the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)"
|
197
216
|
end
|
198
|
-
|
217
|
+
|
199
218
|
@scheme.freeze if @scheme
|
200
219
|
self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
|
201
220
|
self.set_port(self.default_port) if self.default_port && !@port
|
202
221
|
end
|
222
|
+
|
223
|
+
#
|
224
|
+
# returns the scheme component of the URI.
|
225
|
+
#
|
226
|
+
# URI("http://foo/bar/baz").scheme #=> "http"
|
227
|
+
#
|
203
228
|
attr_reader :scheme
|
229
|
+
|
230
|
+
# returns the host component of the URI.
|
231
|
+
#
|
232
|
+
# URI("http://foo/bar/baz").host #=> "foo"
|
233
|
+
#
|
234
|
+
# It returns nil if no host component.
|
235
|
+
#
|
236
|
+
# URI("mailto:foo@example.org").host #=> nil
|
237
|
+
#
|
238
|
+
# The component doesn't contains the port number.
|
239
|
+
#
|
240
|
+
# URI("http://foo:8080/bar/baz").host #=> "foo"
|
241
|
+
#
|
242
|
+
# Since IPv6 addresses are wrapped by brackets in URIs,
|
243
|
+
# this method returns IPv6 addresses wrapped by brackets.
|
244
|
+
# This form is not appropriate to pass socket methods such as TCPSocket.open.
|
245
|
+
# If unwrapped host names are required, use "hostname" method.
|
246
|
+
#
|
247
|
+
# URI("http://[::1]/bar/baz").host #=> "[::1]"
|
248
|
+
# URI("http://[::1]/bar/baz").hostname #=> "::1"
|
249
|
+
#
|
204
250
|
attr_reader :host
|
251
|
+
|
252
|
+
# returns the port component of the URI.
|
253
|
+
#
|
254
|
+
# URI("http://foo/bar/baz").port #=> "80"
|
255
|
+
#
|
256
|
+
# URI("http://foo:8080/bar/baz").port #=> "8080"
|
257
|
+
#
|
205
258
|
attr_reader :port
|
259
|
+
|
260
|
+
# returns the registry component of the URI.
|
261
|
+
#
|
262
|
+
# (see RFC2396 Section 3.2)
|
263
|
+
#
|
206
264
|
attr_reader :registry
|
265
|
+
|
266
|
+
# returns the path component of the URI.
|
267
|
+
#
|
268
|
+
# URI("http://foo/bar/baz").path #=> "/bar/baz"
|
269
|
+
#
|
207
270
|
attr_reader :path
|
271
|
+
|
272
|
+
# returns the query component of the URI.
|
273
|
+
#
|
274
|
+
# URI("http://foo/bar/baz?search=FooBar").query #=> "search=FooBar"
|
275
|
+
#
|
208
276
|
attr_reader :query
|
277
|
+
|
278
|
+
# returns the opaque part of the URI.
|
279
|
+
#
|
280
|
+
# URI("mailto:foo@example.org").opaque #=> "foo@example.org"
|
281
|
+
#
|
282
|
+
# Portion of the path that does make use of the slash '/'.
|
283
|
+
# The path typically refers to the absolute path and the opaque part.
|
284
|
+
# (see RFC2396 Section 3 and 5.2)
|
285
|
+
#
|
209
286
|
attr_reader :opaque
|
287
|
+
|
288
|
+
# returns the fragment component of the URI.
|
289
|
+
#
|
290
|
+
# URI("http://foo/bar/baz?search=FooBar#ponies").fragment #=> "ponies"
|
291
|
+
#
|
210
292
|
attr_reader :fragment
|
211
293
|
|
294
|
+
# returns the parser to be used.
|
295
|
+
#
|
296
|
+
# Unless a URI::Parser is defined, then DEFAULT_PARSER is used.
|
297
|
+
#
|
298
|
+
def parser
|
299
|
+
if !defined?(@parser) || !@parser
|
300
|
+
DEFAULT_PARSER
|
301
|
+
else
|
302
|
+
@parser || DEFAULT_PARSER
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
212
306
|
# replace self by other URI object
|
213
307
|
def replace!(oth)
|
214
308
|
if self.class != oth.class
|
@@ -221,12 +315,18 @@ module URI
|
|
221
315
|
end
|
222
316
|
private :replace!
|
223
317
|
|
318
|
+
#
|
319
|
+
# Components of the URI in the order.
|
320
|
+
#
|
224
321
|
def component
|
225
322
|
self.class.component
|
226
323
|
end
|
227
324
|
|
325
|
+
#
|
326
|
+
# check the scheme +v+ component against the URI::Parser Regexp for :SCHEME
|
327
|
+
#
|
228
328
|
def check_scheme(v)
|
229
|
-
if v && SCHEME !~ v
|
329
|
+
if v && parser.regexp[:SCHEME] !~ v
|
230
330
|
raise InvalidComponentError,
|
231
331
|
"bad component(expected scheme component): #{v}"
|
232
332
|
end
|
@@ -235,17 +335,53 @@ module URI
|
|
235
335
|
end
|
236
336
|
private :check_scheme
|
237
337
|
|
338
|
+
# protected setter for the scheme component +v+
|
339
|
+
#
|
340
|
+
# see also URI::Generic.scheme=
|
341
|
+
#
|
238
342
|
def set_scheme(v)
|
239
|
-
@scheme = v
|
343
|
+
@scheme = v ? v.downcase : v
|
240
344
|
end
|
241
345
|
protected :set_scheme
|
242
346
|
|
347
|
+
#
|
348
|
+
# == Args
|
349
|
+
#
|
350
|
+
# +v+::
|
351
|
+
# String
|
352
|
+
#
|
353
|
+
# == Description
|
354
|
+
#
|
355
|
+
# public setter for the scheme component +v+.
|
356
|
+
# (with validation)
|
357
|
+
#
|
358
|
+
# see also URI::Generic.check_scheme
|
359
|
+
#
|
360
|
+
# == Usage
|
361
|
+
#
|
362
|
+
# require 'uri'
|
363
|
+
#
|
364
|
+
# uri = URI.parse("http://my.example.com")
|
365
|
+
# uri.scheme = "https"
|
366
|
+
# # => "https"
|
367
|
+
# uri
|
368
|
+
# #=> #<URI::HTTP:0x000000008e89e8 URL:https://my.example.com>
|
369
|
+
#
|
243
370
|
def scheme=(v)
|
244
371
|
check_scheme(v)
|
245
372
|
set_scheme(v)
|
246
373
|
v
|
247
374
|
end
|
248
375
|
|
376
|
+
#
|
377
|
+
# check the +user+ and +password+.
|
378
|
+
#
|
379
|
+
# If +password+ is not provided, then +user+ is
|
380
|
+
# split, using URI::Generic.split_userinfo, to
|
381
|
+
# pull +user+ and +password.
|
382
|
+
#
|
383
|
+
# see also URI::Generic.check_user, URI::Generic.check_password
|
384
|
+
#
|
249
385
|
def check_userinfo(user, password = nil)
|
250
386
|
if !password
|
251
387
|
user, password = split_userinfo(user)
|
@@ -257,15 +393,22 @@ module URI
|
|
257
393
|
end
|
258
394
|
private :check_userinfo
|
259
395
|
|
396
|
+
#
|
397
|
+
# check the user +v+ component for RFC2396 compliance
|
398
|
+
# and against the URI::Parser Regexp for :USERINFO
|
399
|
+
#
|
400
|
+
# Can not have a registry or opaque component defined,
|
401
|
+
# with a user component defined.
|
402
|
+
#
|
260
403
|
def check_user(v)
|
261
404
|
if @registry || @opaque
|
262
|
-
raise InvalidURIError,
|
405
|
+
raise InvalidURIError,
|
263
406
|
"can not set user with registry or opaque"
|
264
407
|
end
|
265
408
|
|
266
409
|
return v unless v
|
267
410
|
|
268
|
-
if USERINFO !~ v
|
411
|
+
if parser.regexp[:USERINFO] !~ v
|
269
412
|
raise InvalidComponentError,
|
270
413
|
"bad component(expected userinfo component or user component): #{v}"
|
271
414
|
end
|
@@ -274,9 +417,16 @@ module URI
|
|
274
417
|
end
|
275
418
|
private :check_user
|
276
419
|
|
420
|
+
#
|
421
|
+
# check the password +v+ component for RFC2396 compliance
|
422
|
+
# and against the URI::Parser Regexp for :USERINFO
|
423
|
+
#
|
424
|
+
# Can not have a registry or opaque component defined,
|
425
|
+
# with a user component defined.
|
426
|
+
#
|
277
427
|
def check_password(v, user = @user)
|
278
428
|
if @registry || @opaque
|
279
|
-
raise InvalidURIError,
|
429
|
+
raise InvalidURIError,
|
280
430
|
"can not set password with registry or opaque"
|
281
431
|
end
|
282
432
|
return v unless v
|
@@ -286,7 +436,7 @@ module URI
|
|
286
436
|
"password component depends user component"
|
287
437
|
end
|
288
438
|
|
289
|
-
if USERINFO !~ v
|
439
|
+
if parser.regexp[:USERINFO] !~ v
|
290
440
|
raise InvalidComponentError,
|
291
441
|
"bad component(expected user component): #{v}"
|
292
442
|
end
|
@@ -307,20 +457,71 @@ module URI
|
|
307
457
|
# returns userinfo
|
308
458
|
end
|
309
459
|
|
460
|
+
#
|
461
|
+
# == Args
|
462
|
+
#
|
463
|
+
# +v+::
|
464
|
+
# String
|
465
|
+
#
|
466
|
+
# == Description
|
467
|
+
#
|
468
|
+
# public setter for the +user+ component.
|
469
|
+
# (with validation)
|
470
|
+
#
|
471
|
+
# see also URI::Generic.check_user
|
472
|
+
#
|
473
|
+
# == Usage
|
474
|
+
#
|
475
|
+
# require 'uri'
|
476
|
+
#
|
477
|
+
# uri = URI.parse("http://john:S3nsit1ve@my.example.com")
|
478
|
+
# uri.user = "sam"
|
479
|
+
# # => "sam"
|
480
|
+
# uri
|
481
|
+
# #=> #<URI::HTTP:0x00000000881d90 URL:http://sam:V3ry_S3nsit1ve@my.example.com>
|
482
|
+
#
|
310
483
|
def user=(user)
|
311
484
|
check_user(user)
|
312
485
|
set_user(user)
|
313
486
|
# returns user
|
314
487
|
end
|
315
|
-
|
488
|
+
|
489
|
+
#
|
490
|
+
# == Args
|
491
|
+
#
|
492
|
+
# +v+::
|
493
|
+
# String
|
494
|
+
#
|
495
|
+
# == Description
|
496
|
+
#
|
497
|
+
# public setter for the +password+ component.
|
498
|
+
# (with validation)
|
499
|
+
#
|
500
|
+
# see also URI::Generic.check_password
|
501
|
+
#
|
502
|
+
# == Usage
|
503
|
+
#
|
504
|
+
# require 'uri'
|
505
|
+
#
|
506
|
+
# uri = URI.parse("http://john:S3nsit1ve@my.example.com")
|
507
|
+
# uri.password = "V3ry_S3nsit1ve"
|
508
|
+
# # => "V3ry_S3nsit1ve"
|
509
|
+
# uri
|
510
|
+
# #=> #<URI::HTTP:0x00000000881d90 URL:http://john:V3ry_S3nsit1ve@my.example.com>
|
511
|
+
#
|
316
512
|
def password=(password)
|
317
513
|
check_password(password)
|
318
514
|
set_password(password)
|
319
515
|
# returns password
|
320
516
|
end
|
321
517
|
|
518
|
+
# protect setter for the +user+ component, and +password+ if available.
|
519
|
+
# (with validation)
|
520
|
+
#
|
521
|
+
# see also URI::Generic.userinfo=
|
522
|
+
#
|
322
523
|
def set_userinfo(user, password = nil)
|
323
|
-
unless password
|
524
|
+
unless password
|
324
525
|
user, password = split_userinfo(user)
|
325
526
|
end
|
326
527
|
@user = user
|
@@ -330,18 +531,28 @@ module URI
|
|
330
531
|
end
|
331
532
|
protected :set_userinfo
|
332
533
|
|
534
|
+
# protected setter for the user component +v+
|
535
|
+
#
|
536
|
+
# see also URI::Generic.user=
|
537
|
+
#
|
333
538
|
def set_user(v)
|
334
539
|
set_userinfo(v, @password)
|
335
540
|
v
|
336
541
|
end
|
337
542
|
protected :set_user
|
338
543
|
|
544
|
+
# protected setter for the password component +v+
|
545
|
+
#
|
546
|
+
# see also URI::Generic.password=
|
547
|
+
#
|
339
548
|
def set_password(v)
|
340
549
|
@password = v
|
341
550
|
# returns v
|
342
551
|
end
|
343
552
|
protected :set_password
|
344
553
|
|
554
|
+
# returns the userinfo +ui+ as user, password
|
555
|
+
# if properly formated as 'user:password'
|
345
556
|
def split_userinfo(ui)
|
346
557
|
return nil, nil unless ui
|
347
558
|
user, password = ui.split(/:/, 2)
|
@@ -350,11 +561,13 @@ module URI
|
|
350
561
|
end
|
351
562
|
private :split_userinfo
|
352
563
|
|
564
|
+
# escapes 'user:password' +v+ based on RFC 1738 section 3.1
|
353
565
|
def escape_userpass(v)
|
354
|
-
v =
|
566
|
+
v = parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
|
355
567
|
end
|
356
568
|
private :escape_userpass
|
357
569
|
|
570
|
+
# returns the userinfo, either as 'user' or 'user:password'
|
358
571
|
def userinfo
|
359
572
|
if @user.nil?
|
360
573
|
nil
|
@@ -365,21 +578,30 @@ module URI
|
|
365
578
|
end
|
366
579
|
end
|
367
580
|
|
581
|
+
# returns the user component
|
368
582
|
def user
|
369
583
|
@user
|
370
584
|
end
|
371
585
|
|
586
|
+
# returns the password component
|
372
587
|
def password
|
373
588
|
@password
|
374
589
|
end
|
375
590
|
|
591
|
+
#
|
592
|
+
# check the host +v+ component for RFC2396 compliance
|
593
|
+
# and against the URI::Parser Regexp for :HOST
|
594
|
+
#
|
595
|
+
# Can not have a registry or opaque component defined,
|
596
|
+
# with a host component defined.
|
597
|
+
#
|
376
598
|
def check_host(v)
|
377
599
|
return v unless v
|
378
600
|
|
379
601
|
if @registry || @opaque
|
380
|
-
raise InvalidURIError,
|
602
|
+
raise InvalidURIError,
|
381
603
|
"can not set host with registry or opaque"
|
382
|
-
elsif HOST !~ v
|
604
|
+
elsif parser.regexp[:HOST] !~ v
|
383
605
|
raise InvalidComponentError,
|
384
606
|
"bad component(expected host component): #{v}"
|
385
607
|
end
|
@@ -388,24 +610,90 @@ module URI
|
|
388
610
|
end
|
389
611
|
private :check_host
|
390
612
|
|
613
|
+
# protected setter for the host component +v+
|
614
|
+
#
|
615
|
+
# see also URI::Generic.host=
|
616
|
+
#
|
391
617
|
def set_host(v)
|
392
618
|
@host = v
|
393
619
|
end
|
394
620
|
protected :set_host
|
395
621
|
|
622
|
+
#
|
623
|
+
# == Args
|
624
|
+
#
|
625
|
+
# +v+::
|
626
|
+
# String
|
627
|
+
#
|
628
|
+
# == Description
|
629
|
+
#
|
630
|
+
# public setter for the host component +v+.
|
631
|
+
# (with validation)
|
632
|
+
#
|
633
|
+
# see also URI::Generic.check_host
|
634
|
+
#
|
635
|
+
# == Usage
|
636
|
+
#
|
637
|
+
# require 'uri'
|
638
|
+
#
|
639
|
+
# uri = URI.parse("http://my.example.com")
|
640
|
+
# uri.host = "foo.com"
|
641
|
+
# # => "foo.com"
|
642
|
+
# uri
|
643
|
+
# #=> #<URI::HTTP:0x000000008e89e8 URL:http://foo.com>
|
644
|
+
#
|
396
645
|
def host=(v)
|
397
646
|
check_host(v)
|
398
647
|
set_host(v)
|
399
648
|
v
|
400
649
|
end
|
401
650
|
|
651
|
+
# extract the host part of the URI and unwrap brackets for IPv6 addresses.
|
652
|
+
#
|
653
|
+
# This method is same as URI::Generic#host except
|
654
|
+
# brackets for IPv6 (andn future IP) addresses are removed.
|
655
|
+
#
|
656
|
+
# u = URI("http://[::1]/bar")
|
657
|
+
# p u.hostname #=> "::1"
|
658
|
+
# p u.host #=> "[::1]"
|
659
|
+
#
|
660
|
+
def hostname
|
661
|
+
v = self.host
|
662
|
+
/\A\[(.*)\]\z/ =~ v ? $1 : v
|
663
|
+
end
|
664
|
+
|
665
|
+
# set the host part of the URI as the argument with brackets for IPv6 addresses.
|
666
|
+
#
|
667
|
+
# This method is same as URI::Generic#host= except
|
668
|
+
# the argument can be bare IPv6 address.
|
669
|
+
#
|
670
|
+
# u = URI("http://foo/bar")
|
671
|
+
# p u.to_s #=> "http://foo/bar"
|
672
|
+
# u.hostname = "::1"
|
673
|
+
# p u.to_s #=> "http://[::1]/bar"
|
674
|
+
#
|
675
|
+
# If the arugument seems IPv6 address,
|
676
|
+
# it is wrapped by brackets.
|
677
|
+
#
|
678
|
+
def hostname=(v)
|
679
|
+
v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v
|
680
|
+
self.host = v
|
681
|
+
end
|
682
|
+
|
683
|
+
#
|
684
|
+
# check the port +v+ component for RFC2396 compliance
|
685
|
+
# and against the URI::Parser Regexp for :PORT
|
686
|
+
#
|
687
|
+
# Can not have a registry or opaque component defined,
|
688
|
+
# with a port component defined.
|
689
|
+
#
|
402
690
|
def check_port(v)
|
403
691
|
return v unless v
|
404
692
|
|
405
693
|
if @registry || @opaque
|
406
|
-
raise InvalidURIError,
|
694
|
+
raise InvalidURIError,
|
407
695
|
"can not set port with registry or opaque"
|
408
|
-
elsif !v.kind_of?(Fixnum) && PORT !~ v
|
696
|
+
elsif !v.kind_of?(Fixnum) && parser.regexp[:PORT] !~ v
|
409
697
|
raise InvalidComponentError,
|
410
698
|
"bad component(expected port component): #{v}"
|
411
699
|
end
|
@@ -414,6 +702,10 @@ module URI
|
|
414
702
|
end
|
415
703
|
private :check_port
|
416
704
|
|
705
|
+
# protected setter for the port component +v+
|
706
|
+
#
|
707
|
+
# see also URI::Generic.port=
|
708
|
+
#
|
417
709
|
def set_port(v)
|
418
710
|
unless !v || v.kind_of?(Fixnum)
|
419
711
|
if v.empty?
|
@@ -426,12 +718,42 @@ module URI
|
|
426
718
|
end
|
427
719
|
protected :set_port
|
428
720
|
|
721
|
+
#
|
722
|
+
# == Args
|
723
|
+
#
|
724
|
+
# +v+::
|
725
|
+
# String
|
726
|
+
#
|
727
|
+
# == Description
|
728
|
+
#
|
729
|
+
# public setter for the port component +v+.
|
730
|
+
# (with validation)
|
731
|
+
#
|
732
|
+
# see also URI::Generic.check_port
|
733
|
+
#
|
734
|
+
# == Usage
|
735
|
+
#
|
736
|
+
# require 'uri'
|
737
|
+
#
|
738
|
+
# uri = URI.parse("http://my.example.com")
|
739
|
+
# uri.port = 8080
|
740
|
+
# # => 8080
|
741
|
+
# uri
|
742
|
+
# #=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com:8080>
|
743
|
+
#
|
429
744
|
def port=(v)
|
430
745
|
check_port(v)
|
431
746
|
set_port(v)
|
432
747
|
port
|
433
748
|
end
|
434
749
|
|
750
|
+
#
|
751
|
+
# check the registry +v+ component for RFC2396 compliance
|
752
|
+
# and against the URI::Parser Regexp for :REGISTRY
|
753
|
+
#
|
754
|
+
# Can not have a host, port or user component defined,
|
755
|
+
# with a registry component defined.
|
756
|
+
#
|
435
757
|
def check_registry(v)
|
436
758
|
return v unless v
|
437
759
|
|
@@ -439,9 +761,9 @@ module URI
|
|
439
761
|
# authority = server | reg_name
|
440
762
|
# server = [ [ userinfo "@" ] hostport ]
|
441
763
|
if @host || @port || @user # userinfo = @user + ':' + @password
|
442
|
-
raise InvalidURIError,
|
764
|
+
raise InvalidURIError,
|
443
765
|
"can not set registry with host, port, or userinfo"
|
444
|
-
elsif v && REGISTRY !~ v
|
766
|
+
elsif v && parser.regexp[:REGISTRY] !~ v
|
445
767
|
raise InvalidComponentError,
|
446
768
|
"bad component(expected registry component): #{v}"
|
447
769
|
end
|
@@ -450,34 +772,61 @@ module URI
|
|
450
772
|
end
|
451
773
|
private :check_registry
|
452
774
|
|
775
|
+
# protected setter for the registry component +v+
|
776
|
+
#
|
777
|
+
# see also URI::Generic.registry=
|
778
|
+
#
|
453
779
|
def set_registry(v)
|
454
780
|
@registry = v
|
455
781
|
end
|
456
782
|
protected :set_registry
|
457
783
|
|
784
|
+
#
|
785
|
+
# == Args
|
786
|
+
#
|
787
|
+
# +v+::
|
788
|
+
# String
|
789
|
+
#
|
790
|
+
# == Description
|
791
|
+
#
|
792
|
+
# public setter for the registry component +v+.
|
793
|
+
# (with validation)
|
794
|
+
#
|
795
|
+
# see also URI::Generic.check_registry
|
796
|
+
#
|
458
797
|
def registry=(v)
|
459
798
|
check_registry(v)
|
460
799
|
set_registry(v)
|
461
800
|
v
|
462
801
|
end
|
463
802
|
|
803
|
+
#
|
804
|
+
# check the path +v+ component for RFC2396 compliance
|
805
|
+
# and against the URI::Parser Regexp
|
806
|
+
# for :ABS_PATH and :REL_PATH
|
807
|
+
#
|
808
|
+
# Can not have a opaque component defined,
|
809
|
+
# with a path component defined.
|
810
|
+
#
|
464
811
|
def check_path(v)
|
465
812
|
# raise if both hier and opaque are not nil, because:
|
466
813
|
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
467
814
|
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
468
815
|
if v && @opaque
|
469
|
-
raise InvalidURIError,
|
816
|
+
raise InvalidURIError,
|
470
817
|
"path conflicts with opaque"
|
471
818
|
end
|
472
819
|
|
473
|
-
|
474
|
-
|
475
|
-
|
820
|
+
# If scheme is ftp, path may be relative.
|
821
|
+
# See RFC 1738 section 3.2.2, and RFC 2396.
|
822
|
+
if @scheme && @scheme != "ftp"
|
823
|
+
if v && v != '' && parser.regexp[:ABS_PATH] !~ v
|
824
|
+
raise InvalidComponentError,
|
476
825
|
"bad component(expected absolute path component): #{v}"
|
477
826
|
end
|
478
827
|
else
|
479
|
-
if v && v != '' && ABS_PATH !~ v && REL_PATH !~ v
|
480
|
-
raise InvalidComponentError,
|
828
|
+
if v && v != '' && parser.regexp[:ABS_PATH] !~ v && parser.regexp[:REL_PATH] !~ v
|
829
|
+
raise InvalidComponentError,
|
481
830
|
"bad component(expected relative path component): #{v}"
|
482
831
|
end
|
483
832
|
end
|
@@ -486,17 +835,51 @@ module URI
|
|
486
835
|
end
|
487
836
|
private :check_path
|
488
837
|
|
838
|
+
# protected setter for the path component +v+
|
839
|
+
#
|
840
|
+
# see also URI::Generic.path=
|
841
|
+
#
|
489
842
|
def set_path(v)
|
490
843
|
@path = v
|
491
844
|
end
|
492
845
|
protected :set_path
|
493
846
|
|
847
|
+
#
|
848
|
+
# == Args
|
849
|
+
#
|
850
|
+
# +v+::
|
851
|
+
# String
|
852
|
+
#
|
853
|
+
# == Description
|
854
|
+
#
|
855
|
+
# public setter for the path component +v+.
|
856
|
+
# (with validation)
|
857
|
+
#
|
858
|
+
# see also URI::Generic.check_path
|
859
|
+
#
|
860
|
+
# == Usage
|
861
|
+
#
|
862
|
+
# require 'uri'
|
863
|
+
#
|
864
|
+
# uri = URI.parse("http://my.example.com/pub/files")
|
865
|
+
# uri.path = "/faq/"
|
866
|
+
# # => "/faq/"
|
867
|
+
# uri
|
868
|
+
# #=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/faq/>
|
869
|
+
#
|
494
870
|
def path=(v)
|
495
871
|
check_path(v)
|
496
872
|
set_path(v)
|
497
873
|
v
|
498
874
|
end
|
499
875
|
|
876
|
+
#
|
877
|
+
# check the query +v+ component for RFC2396 compliance
|
878
|
+
# and against the URI::Parser Regexp for :QUERY
|
879
|
+
#
|
880
|
+
# Can not have a opaque component defined,
|
881
|
+
# with a query component defined.
|
882
|
+
#
|
500
883
|
def check_query(v)
|
501
884
|
return v unless v
|
502
885
|
|
@@ -504,30 +887,64 @@ module URI
|
|
504
887
|
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
505
888
|
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
506
889
|
if @opaque
|
507
|
-
raise InvalidURIError,
|
890
|
+
raise InvalidURIError,
|
508
891
|
"query conflicts with opaque"
|
509
892
|
end
|
510
893
|
|
511
|
-
if v && v != '' && QUERY !~ v
|
512
|
-
raise InvalidComponentError,
|
894
|
+
if v && v != '' && parser.regexp[:QUERY] !~ v
|
895
|
+
raise InvalidComponentError,
|
513
896
|
"bad component(expected query component): #{v}"
|
514
|
-
|
897
|
+
end
|
515
898
|
|
516
899
|
return true
|
517
900
|
end
|
518
901
|
private :check_query
|
519
902
|
|
903
|
+
# protected setter for the query component +v+
|
904
|
+
#
|
905
|
+
# see also URI::Generic.query=
|
906
|
+
#
|
520
907
|
def set_query(v)
|
521
908
|
@query = v
|
522
909
|
end
|
523
910
|
protected :set_query
|
524
911
|
|
912
|
+
#
|
913
|
+
# == Args
|
914
|
+
#
|
915
|
+
# +v+::
|
916
|
+
# String
|
917
|
+
#
|
918
|
+
# == Description
|
919
|
+
#
|
920
|
+
# public setter for the query component +v+.
|
921
|
+
# (with validation)
|
922
|
+
#
|
923
|
+
# see also URI::Generic.check_query
|
924
|
+
#
|
925
|
+
# == Usage
|
926
|
+
#
|
927
|
+
# require 'uri'
|
928
|
+
#
|
929
|
+
# uri = URI.parse("http://my.example.com/?id=25")
|
930
|
+
# uri.query = "id=1"
|
931
|
+
# # => "id=1"
|
932
|
+
# uri
|
933
|
+
# #=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/?id=1>
|
934
|
+
#
|
525
935
|
def query=(v)
|
526
936
|
check_query(v)
|
527
937
|
set_query(v)
|
528
938
|
v
|
529
939
|
end
|
530
940
|
|
941
|
+
#
|
942
|
+
# check the opaque +v+ component for RFC2396 compliance and
|
943
|
+
# against the URI::Parser Regexp for :OPAQUE
|
944
|
+
#
|
945
|
+
# Can not have a host, port, user or path component defined,
|
946
|
+
# with an opaque component defined.
|
947
|
+
#
|
531
948
|
def check_opaque(v)
|
532
949
|
return v unless v
|
533
950
|
|
@@ -535,9 +952,9 @@ module URI
|
|
535
952
|
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
536
953
|
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
537
954
|
if @host || @port || @user || @path # userinfo = @user + ':' + @password
|
538
|
-
raise InvalidURIError,
|
955
|
+
raise InvalidURIError,
|
539
956
|
"can not set opaque with host, port, userinfo or path"
|
540
|
-
elsif v && OPAQUE !~ v
|
957
|
+
elsif v && parser.regexp[:OPAQUE] !~ v
|
541
958
|
raise InvalidComponentError,
|
542
959
|
"bad component(expected opaque component): #{v}"
|
543
960
|
end
|
@@ -546,22 +963,42 @@ module URI
|
|
546
963
|
end
|
547
964
|
private :check_opaque
|
548
965
|
|
966
|
+
# protected setter for the opaque component +v+
|
967
|
+
#
|
968
|
+
# see also URI::Generic.opaque=
|
969
|
+
#
|
549
970
|
def set_opaque(v)
|
550
971
|
@opaque = v
|
551
972
|
end
|
552
973
|
protected :set_opaque
|
553
974
|
|
975
|
+
#
|
976
|
+
# == Args
|
977
|
+
#
|
978
|
+
# +v+::
|
979
|
+
# String
|
980
|
+
#
|
981
|
+
# == Description
|
982
|
+
#
|
983
|
+
# public setter for the opaque component +v+.
|
984
|
+
# (with validation)
|
985
|
+
#
|
986
|
+
# see also URI::Generic.check_opaque
|
987
|
+
#
|
554
988
|
def opaque=(v)
|
555
989
|
check_opaque(v)
|
556
990
|
set_opaque(v)
|
557
991
|
v
|
558
992
|
end
|
559
993
|
|
994
|
+
#
|
995
|
+
# check the fragment +v+ component against the URI::Parser Regexp for :FRAGMENT
|
996
|
+
#
|
560
997
|
def check_fragment(v)
|
561
998
|
return v unless v
|
562
999
|
|
563
|
-
if v && v != '' && FRAGMENT !~ v
|
564
|
-
raise InvalidComponentError,
|
1000
|
+
if v && v != '' && parser.regexp[:FRAGMENT] !~ v
|
1001
|
+
raise InvalidComponentError,
|
565
1002
|
"bad component(expected fragment component): #{v}"
|
566
1003
|
end
|
567
1004
|
|
@@ -569,11 +1006,38 @@ module URI
|
|
569
1006
|
end
|
570
1007
|
private :check_fragment
|
571
1008
|
|
1009
|
+
# protected setter for the fragment component +v+
|
1010
|
+
#
|
1011
|
+
# see also URI::Generic.fragment=
|
1012
|
+
#
|
572
1013
|
def set_fragment(v)
|
573
1014
|
@fragment = v
|
574
1015
|
end
|
575
1016
|
protected :set_fragment
|
576
1017
|
|
1018
|
+
#
|
1019
|
+
# == Args
|
1020
|
+
#
|
1021
|
+
# +v+::
|
1022
|
+
# String
|
1023
|
+
#
|
1024
|
+
# == Description
|
1025
|
+
#
|
1026
|
+
# public setter for the fragment component +v+.
|
1027
|
+
# (with validation)
|
1028
|
+
#
|
1029
|
+
# see also URI::Generic.check_fragment
|
1030
|
+
#
|
1031
|
+
# == Usage
|
1032
|
+
#
|
1033
|
+
# require 'uri'
|
1034
|
+
#
|
1035
|
+
# uri = URI.parse("http://my.example.com/?id=25#time=1305212049")
|
1036
|
+
# uri.fragment = "time=1305212086"
|
1037
|
+
# # => "time=1305212086"
|
1038
|
+
# uri
|
1039
|
+
# #=> #<URI::HTTP:0x000000007a81f8 URL:http://my.example.com/?id=25#time=1305212086>
|
1040
|
+
#
|
577
1041
|
def fragment=(v)
|
578
1042
|
check_fragment(v)
|
579
1043
|
set_fragment(v)
|
@@ -610,11 +1074,18 @@ module URI
|
|
610
1074
|
!absolute?
|
611
1075
|
end
|
612
1076
|
|
1077
|
+
#
|
1078
|
+
# returns an Array of the path split on '/'
|
1079
|
+
#
|
613
1080
|
def split_path(path)
|
614
1081
|
path.split(%r{/+}, -1)
|
615
1082
|
end
|
616
1083
|
private :split_path
|
617
1084
|
|
1085
|
+
#
|
1086
|
+
# Merges a base path +base+, with relative path +rel+,
|
1087
|
+
# returns a modified base path.
|
1088
|
+
#
|
618
1089
|
def merge_path(base, rel)
|
619
1090
|
|
620
1091
|
# RFC2396, Section 5.2, 5)
|
@@ -769,22 +1240,15 @@ module URI
|
|
769
1240
|
# return base and rel.
|
770
1241
|
# you can modify `base', but can not `rel'.
|
771
1242
|
def merge0(oth)
|
772
|
-
|
773
|
-
when Generic
|
774
|
-
when String
|
775
|
-
oth = URI.parse(oth)
|
776
|
-
else
|
777
|
-
raise ArgumentError,
|
778
|
-
"bad argument(expected URI object or URI string)"
|
779
|
-
end
|
1243
|
+
oth = parser.send(:convert_to_uri, oth)
|
780
1244
|
|
781
1245
|
if self.relative? && oth.relative?
|
782
|
-
raise BadURIError,
|
1246
|
+
raise BadURIError,
|
783
1247
|
"both URI are relative"
|
784
1248
|
end
|
785
1249
|
|
786
1250
|
if self.absolute? && oth.absolute?
|
787
|
-
#raise BadURIError,
|
1251
|
+
#raise BadURIError,
|
788
1252
|
# "both URI are absolute"
|
789
1253
|
# hmm... should return oth for usability?
|
790
1254
|
return oth, oth
|
@@ -798,31 +1262,28 @@ module URI
|
|
798
1262
|
end
|
799
1263
|
private :merge0
|
800
1264
|
|
1265
|
+
# :stopdoc:
|
801
1266
|
def route_from_path(src, dst)
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
# like "/./", "/../", "/x/../", ...
|
810
|
-
if dst_path.include?('..') ||
|
811
|
-
dst_path.include?('.')
|
1267
|
+
case dst
|
1268
|
+
when src
|
1269
|
+
# RFC2396, Section 4.2
|
1270
|
+
return ''
|
1271
|
+
when %r{(?:\A|/)\.\.?(?:/|\z)}
|
1272
|
+
# dst has abnormal absolute path,
|
1273
|
+
# like "/./", "/../", "/x/../", ...
|
812
1274
|
return dst.dup
|
813
1275
|
end
|
814
1276
|
|
815
|
-
src_path.
|
1277
|
+
src_path = src.scan(%r{(?:\A|[^/]+)/})
|
1278
|
+
dst_path = dst.scan(%r{(?:\A|[^/]+)/?})
|
816
1279
|
|
817
1280
|
# discard same parts
|
818
|
-
while dst_path.first == src_path.first
|
819
|
-
break if dst_path.empty?
|
820
|
-
|
1281
|
+
while !dst_path.empty? && dst_path.first == src_path.first
|
821
1282
|
src_path.shift
|
822
1283
|
dst_path.shift
|
823
1284
|
end
|
824
1285
|
|
825
|
-
tmp = dst_path.join
|
1286
|
+
tmp = dst_path.join
|
826
1287
|
|
827
1288
|
# calculate
|
828
1289
|
if src_path.empty?
|
@@ -838,23 +1299,17 @@ module URI
|
|
838
1299
|
return '../' * src_path.size + tmp
|
839
1300
|
end
|
840
1301
|
private :route_from_path
|
1302
|
+
# :startdoc:
|
841
1303
|
|
1304
|
+
# :stopdoc:
|
842
1305
|
def route_from0(oth)
|
843
|
-
|
844
|
-
when Generic
|
845
|
-
when String
|
846
|
-
oth = URI.parse(oth)
|
847
|
-
else
|
848
|
-
raise ArgumentError,
|
849
|
-
"bad argument(expected URI object or URI string)"
|
850
|
-
end
|
851
|
-
|
1306
|
+
oth = parser.send(:convert_to_uri, oth)
|
852
1307
|
if self.relative?
|
853
|
-
raise BadURIError,
|
1308
|
+
raise BadURIError,
|
854
1309
|
"relative URI: #{self}"
|
855
1310
|
end
|
856
1311
|
if oth.relative?
|
857
|
-
raise BadURIError,
|
1312
|
+
raise BadURIError,
|
858
1313
|
"relative URI: #{oth}"
|
859
1314
|
end
|
860
1315
|
|
@@ -862,16 +1317,18 @@ module URI
|
|
862
1317
|
return self, self.dup
|
863
1318
|
end
|
864
1319
|
rel = URI::Generic.new(nil, # it is relative URI
|
865
|
-
self.userinfo, self.host, self.port,
|
1320
|
+
self.userinfo, self.host, self.port,
|
866
1321
|
self.registry, self.path, self.opaque,
|
867
|
-
self.query, self.fragment)
|
1322
|
+
self.query, self.fragment, parser)
|
868
1323
|
|
869
1324
|
if rel.userinfo != oth.userinfo ||
|
870
1325
|
rel.host.to_s.downcase != oth.host.to_s.downcase ||
|
871
1326
|
rel.port != oth.port
|
872
|
-
|
873
|
-
|
874
|
-
|
1327
|
+
|
1328
|
+
if self.userinfo.nil? && self.host.nil?
|
1329
|
+
return self, self.dup
|
1330
|
+
end
|
1331
|
+
|
875
1332
|
rel.set_port(nil) if rel.port == oth.default_port
|
876
1333
|
return rel, rel
|
877
1334
|
end
|
@@ -893,6 +1350,8 @@ module URI
|
|
893
1350
|
return oth, rel
|
894
1351
|
end
|
895
1352
|
private :route_from0
|
1353
|
+
# :startdoc:
|
1354
|
+
|
896
1355
|
#
|
897
1356
|
# == Args
|
898
1357
|
#
|
@@ -950,23 +1409,14 @@ module URI
|
|
950
1409
|
# uri = URI.parse('http://my.example.com')
|
951
1410
|
# p uri.route_to('http://my.example.com/main.rbx?page=1')
|
952
1411
|
# #=> #<URI::Generic:0x2020c2f6 URL:/main.rbx?page=1>
|
953
|
-
#
|
1412
|
+
#
|
954
1413
|
def route_to(oth)
|
955
|
-
|
956
|
-
when Generic
|
957
|
-
when String
|
958
|
-
oth = URI.parse(oth)
|
959
|
-
else
|
960
|
-
raise ArgumentError,
|
961
|
-
"bad argument(expected URI object or URI string)"
|
962
|
-
end
|
963
|
-
|
964
|
-
oth.route_from(self)
|
1414
|
+
parser.send(:convert_to_uri, oth).route_from(self)
|
965
1415
|
end
|
966
1416
|
|
967
1417
|
#
|
968
1418
|
# Returns normalized URI
|
969
|
-
#
|
1419
|
+
#
|
970
1420
|
def normalize
|
971
1421
|
uri = dup
|
972
1422
|
uri.normalize!
|
@@ -980,15 +1430,15 @@ module URI
|
|
980
1430
|
if path && path == ''
|
981
1431
|
set_path('/')
|
982
1432
|
end
|
983
|
-
if host && host != host.downcase
|
984
|
-
set_host(self.host.downcase)
|
985
|
-
end
|
986
|
-
|
987
1433
|
if scheme && scheme != scheme.downcase
|
988
1434
|
set_scheme(self.scheme.downcase)
|
989
1435
|
end
|
1436
|
+
if host && host != host.downcase
|
1437
|
+
set_host(self.host.downcase)
|
1438
|
+
end
|
990
1439
|
end
|
991
1440
|
|
1441
|
+
# returns the assemble String with path and query components
|
992
1442
|
def path_query
|
993
1443
|
str = @path
|
994
1444
|
if @query
|
@@ -1000,7 +1450,7 @@ module URI
|
|
1000
1450
|
|
1001
1451
|
#
|
1002
1452
|
# Constructs String from URI
|
1003
|
-
#
|
1453
|
+
#
|
1004
1454
|
def to_s
|
1005
1455
|
str = ''
|
1006
1456
|
if @scheme
|
@@ -1058,7 +1508,9 @@ module URI
|
|
1058
1508
|
end
|
1059
1509
|
|
1060
1510
|
def eql?(oth)
|
1061
|
-
|
1511
|
+
self.class == oth.class &&
|
1512
|
+
parser == oth.parser &&
|
1513
|
+
self.component_ary.eql?(oth.component_ary)
|
1062
1514
|
end
|
1063
1515
|
|
1064
1516
|
=begin
|
@@ -1072,6 +1524,9 @@ module URI
|
|
1072
1524
|
|
1073
1525
|
=begin
|
1074
1526
|
=end
|
1527
|
+
|
1528
|
+
|
1529
|
+
# returns an Array of the components defined from the COMPONENT Array
|
1075
1530
|
def component_ary
|
1076
1531
|
component.collect do |x|
|
1077
1532
|
self.send(x)
|
@@ -1101,7 +1556,7 @@ module URI
|
|
1101
1556
|
if component.include?(c)
|
1102
1557
|
self.send(c)
|
1103
1558
|
else
|
1104
|
-
raise ArgumentError,
|
1559
|
+
raise ArgumentError,
|
1105
1560
|
"expected of components of #{self.class} (#{self.class.component.join(', ')})"
|
1106
1561
|
end
|
1107
1562
|
end
|
@@ -1112,15 +1567,110 @@ module URI
|
|
1112
1567
|
@@to_s.bind(self).call.sub!(/>\z/) {" URL:#{self}>"}
|
1113
1568
|
end
|
1114
1569
|
|
1570
|
+
#
|
1571
|
+
# == Args
|
1572
|
+
#
|
1573
|
+
# +v+::
|
1574
|
+
# URI or String
|
1575
|
+
#
|
1576
|
+
# == Description
|
1577
|
+
#
|
1578
|
+
# attempt to parse other URI +oth+
|
1579
|
+
# return [parsed_oth, self]
|
1580
|
+
#
|
1581
|
+
# == Usage
|
1582
|
+
#
|
1583
|
+
# require 'uri'
|
1584
|
+
#
|
1585
|
+
# uri = URI.parse("http://my.example.com")
|
1586
|
+
# uri.coerce("http://foo.com")
|
1587
|
+
# #=> [#<URI::HTTP:0x00000000bcb028 URL:http://foo.com/>, #<URI::HTTP:0x00000000d92178 URL:http://my.example.com>]
|
1588
|
+
#
|
1115
1589
|
def coerce(oth)
|
1116
1590
|
case oth
|
1117
1591
|
when String
|
1118
|
-
oth =
|
1592
|
+
oth = parser.parse(oth)
|
1119
1593
|
else
|
1120
1594
|
super
|
1121
1595
|
end
|
1122
1596
|
|
1123
1597
|
return oth, self
|
1124
1598
|
end
|
1599
|
+
|
1600
|
+
# returns a proxy URI.
|
1601
|
+
# The proxy URI is obtained from environment variables such as http_proxy,
|
1602
|
+
# ftp_proxy, no_proxy, etc.
|
1603
|
+
# If there is no proper proxy, nil is returned.
|
1604
|
+
#
|
1605
|
+
# Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
|
1606
|
+
# are examined too.
|
1607
|
+
#
|
1608
|
+
# But http_proxy and HTTP_PROXY is treated specially under CGI environment.
|
1609
|
+
# It's because HTTP_PROXY may be set by Proxy: header.
|
1610
|
+
# So HTTP_PROXY is not used.
|
1611
|
+
# http_proxy is not used too if the variable is case insensitive.
|
1612
|
+
# CGI_HTTP_PROXY can be used instead.
|
1613
|
+
def find_proxy
|
1614
|
+
name = self.scheme.downcase + '_proxy'
|
1615
|
+
proxy_uri = nil
|
1616
|
+
if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
|
1617
|
+
# HTTP_PROXY conflicts with *_proxy for proxy settings and
|
1618
|
+
# HTTP_* for header information in CGI.
|
1619
|
+
# So it should be careful to use it.
|
1620
|
+
pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
|
1621
|
+
case pairs.length
|
1622
|
+
when 0 # no proxy setting anyway.
|
1623
|
+
proxy_uri = nil
|
1624
|
+
when 1
|
1625
|
+
k, _ = pairs.shift
|
1626
|
+
if k == 'http_proxy' && ENV[k.upcase] == nil
|
1627
|
+
# http_proxy is safe to use because ENV is case sensitive.
|
1628
|
+
proxy_uri = ENV[name]
|
1629
|
+
else
|
1630
|
+
proxy_uri = nil
|
1631
|
+
end
|
1632
|
+
else # http_proxy is safe to use because ENV is case sensitive.
|
1633
|
+
proxy_uri = ENV.to_hash[name]
|
1634
|
+
end
|
1635
|
+
if !proxy_uri
|
1636
|
+
# Use CGI_HTTP_PROXY. cf. libwww-perl.
|
1637
|
+
proxy_uri = ENV["CGI_#{name.upcase}"]
|
1638
|
+
end
|
1639
|
+
elsif name == 'http_proxy'
|
1640
|
+
unless proxy_uri = ENV[name]
|
1641
|
+
if proxy_uri = ENV[name.upcase]
|
1642
|
+
warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.'
|
1643
|
+
end
|
1644
|
+
end
|
1645
|
+
else
|
1646
|
+
proxy_uri = ENV[name] || ENV[name.upcase]
|
1647
|
+
end
|
1648
|
+
|
1649
|
+
if proxy_uri && self.hostname
|
1650
|
+
require 'socket'
|
1651
|
+
begin
|
1652
|
+
addr = IPSocket.getaddress(self.hostname)
|
1653
|
+
proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
|
1654
|
+
rescue SocketError
|
1655
|
+
end
|
1656
|
+
end
|
1657
|
+
|
1658
|
+
if proxy_uri
|
1659
|
+
proxy_uri = URI.parse(proxy_uri)
|
1660
|
+
name = 'no_proxy'
|
1661
|
+
if no_proxy = ENV[name] || ENV[name.upcase]
|
1662
|
+
no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
|
1663
|
+
if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host &&
|
1664
|
+
(!port || self.port == port.to_i)
|
1665
|
+
proxy_uri = nil
|
1666
|
+
break
|
1667
|
+
end
|
1668
|
+
}
|
1669
|
+
end
|
1670
|
+
proxy_uri
|
1671
|
+
else
|
1672
|
+
nil
|
1673
|
+
end
|
1674
|
+
end
|
1125
1675
|
end
|
1126
1676
|
end
|