ruby-web 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. data/ChangeLog +474 -0
  2. data/INSTALL.txt +9 -0
  3. data/InstalledFiles +180 -0
  4. data/LICENSE.txt +74 -0
  5. data/Rakefile +529 -0
  6. data/TODO +65 -0
  7. data/doc/additional.xml +149 -0
  8. data/doc/core.xml +652 -0
  9. data/doc/credits/index.xml +52 -0
  10. data/doc/credits/php.contributors.xml +118 -0
  11. data/doc/credits/php.language-snippets.ent +622 -0
  12. data/doc/install/index.xml +136 -0
  13. data/doc/install/mac/index.xml +21 -0
  14. data/doc/install/ruby-web.install.rb.instructions.xml +7 -0
  15. data/doc/install/unix/index.xml +46 -0
  16. data/doc/install/win/apache1.xml +166 -0
  17. data/doc/install/win/apache2.xml +141 -0
  18. data/doc/install/win/iis.xml +162 -0
  19. data/doc/install/win/index.xml +24 -0
  20. data/doc/install/win/installer.xml +31 -0
  21. data/doc/install/win/manual.xml +43 -0
  22. data/doc/manual.xml +69 -0
  23. data/doc/old/apache_cgi.txt +23 -0
  24. data/doc/old/fastcgi.txt +23 -0
  25. data/doc/old/mod_ruby.txt +21 -0
  26. data/doc/old/snippets.rdoc +183 -0
  27. data/doc/old/webrick.txt +23 -0
  28. data/doc/old/windows_cgi.txt +9 -0
  29. data/doc/tutorial.xml +14 -0
  30. data/doc/xsl/manual-multi.xsl +10 -0
  31. data/doc/xsl/manual-pdf.xsl +6 -0
  32. data/doc/xsl/manual-single.xsl +6 -0
  33. data/doc/xsl/manual.css +22 -0
  34. data/install.rb +1022 -0
  35. data/lib/formatter.rb +314 -0
  36. data/lib/html-parser.rb +429 -0
  37. data/lib/htmlrepair.rb +113 -0
  38. data/lib/htmlsplit.rb +842 -0
  39. data/lib/sgml-parser.rb +332 -0
  40. data/lib/web.rb +68 -0
  41. data/lib/web/assertinclude.rb +129 -0
  42. data/lib/web/config.rb +50 -0
  43. data/lib/web/connection.rb +1070 -0
  44. data/lib/web/convenience.rb +154 -0
  45. data/lib/web/formreader.rb +318 -0
  46. data/lib/web/htmlparser/html-parser.rb +429 -0
  47. data/lib/web/htmlparser/sgml-parser.rb +332 -0
  48. data/lib/web/htmltools/element.rb +296 -0
  49. data/lib/web/htmltools/stparser.rb +276 -0
  50. data/lib/web/htmltools/tags.rb +286 -0
  51. data/lib/web/htmltools/tree.rb +139 -0
  52. data/lib/web/htmltools/xmltree.rb +160 -0
  53. data/lib/web/htmltools/xpath.rb +71 -0
  54. data/lib/web/info.rb +63 -0
  55. data/lib/web/load.rb +210 -0
  56. data/lib/web/mime.rb +87 -0
  57. data/lib/web/phprb.rb +340 -0
  58. data/lib/web/resources/test/cookie.rb +33 -0
  59. data/lib/web/resources/test/counter.rb +20 -0
  60. data/lib/web/resources/test/multipart.rb +14 -0
  61. data/lib/web/resources/test/redirect.rb +8 -0
  62. data/lib/web/resources/test/stock.rb +33 -0
  63. data/lib/web/sapi/apache.rb +129 -0
  64. data/lib/web/sapi/fastcgi.rb +22 -0
  65. data/lib/web/sapi/install/apache.rb +180 -0
  66. data/lib/web/sapi/install/iis.rb +93 -0
  67. data/lib/web/sapi/install/macosx.rb +90 -0
  68. data/lib/web/sapi/webrick.rb +86 -0
  69. data/lib/web/session.rb +83 -0
  70. data/lib/web/shim/cgi.rb +129 -0
  71. data/lib/web/shim/rails.rb +175 -0
  72. data/lib/web/stringio.rb +78 -0
  73. data/lib/web/strscanparser.rb +24 -0
  74. data/lib/web/tagparser.rb +96 -0
  75. data/lib/web/testing.rb +666 -0
  76. data/lib/web/traceoutput.rb +75 -0
  77. data/lib/web/unit.rb +56 -0
  78. data/lib/web/upload.rb +59 -0
  79. data/lib/web/validate.rb +52 -0
  80. data/lib/web/wiki.rb +557 -0
  81. data/lib/web/wiki/linker.rb +72 -0
  82. data/lib/web/wiki/page.rb +201 -0
  83. data/lib/webunit.rb +27 -0
  84. data/lib/webunit/assert.rb +152 -0
  85. data/lib/webunit/converter.rb +154 -0
  86. data/lib/webunit/cookie.rb +118 -0
  87. data/lib/webunit/domwalker.rb +185 -0
  88. data/lib/webunit/exception.rb +14 -0
  89. data/lib/webunit/form.rb +116 -0
  90. data/lib/webunit/frame.rb +37 -0
  91. data/lib/webunit/htmlelem.rb +122 -0
  92. data/lib/webunit/image.rb +26 -0
  93. data/lib/webunit/jscript.rb +31 -0
  94. data/lib/webunit/link.rb +33 -0
  95. data/lib/webunit/params.rb +321 -0
  96. data/lib/webunit/parser.rb +229 -0
  97. data/lib/webunit/response.rb +464 -0
  98. data/lib/webunit/runtest.rb +41 -0
  99. data/lib/webunit/table.rb +148 -0
  100. data/lib/webunit/testcase.rb +45 -0
  101. data/lib/webunit/ui/cui/testrunner.rb +50 -0
  102. data/lib/webunit/utils.rb +68 -0
  103. data/lib/webunit/webunit.rb +28 -0
  104. data/test/dev/action.rb +83 -0
  105. data/test/dev/forms.rb +104 -0
  106. data/test/dev/forms2.rb +104 -0
  107. data/test/dev/parser.rb +17 -0
  108. data/test/dev/scripts/dump.rb +24 -0
  109. data/test/dev/scripts/makedist.rb +62 -0
  110. data/test/dev/scripts/uri.rb +41 -0
  111. data/test/dev/scripts/uri/common.rb +432 -0
  112. data/test/dev/scripts/uri/ftp.rb +149 -0
  113. data/test/dev/scripts/uri/generic.rb +1106 -0
  114. data/test/dev/scripts/uri/http.rb +76 -0
  115. data/test/dev/scripts/uri/https.rb +26 -0
  116. data/test/dev/scripts/uri/ldap.rb +238 -0
  117. data/test/dev/scripts/uri/mailto.rb +260 -0
  118. data/test/dev/scripts/urireg.rb +174 -0
  119. data/test/dev/simpledispatcher.rb +156 -0
  120. data/test/dev/test.action.rb +146 -0
  121. data/test/dev/test.formreader.rb +463 -0
  122. data/test/dev/test.simpledispatcher.rb +186 -0
  123. data/test/dev/webunit/conv/digit-0.rb +21 -0
  124. data/test/dev/webunit/conv/digit-1.rb +17 -0
  125. data/test/dev/webunit/conv/digit.rb +23 -0
  126. data/test/dev/webunit/conv/test_digit-0.rb +16 -0
  127. data/test/dev/webunit/conv/test_digit-1.rb +19 -0
  128. data/test/dev/webunit/conv/test_digit.rb +26 -0
  129. data/test/dev/webunit/conv/test_digit_view-0.rb +76 -0
  130. data/test/dev/webunit/conv/test_digit_view-1.rb +102 -0
  131. data/test/dev/webunit/conv/test_digit_view.rb +134 -0
  132. data/test/installation/htdocs/cgi_test.rb +296 -0
  133. data/test/installation/htdocs/test_install.rb +4 -0
  134. data/test/installation/runwebtest.rb +5 -0
  135. data/test/installation/test_cookie.rb +128 -0
  136. data/test/installation/test_form.rb +47 -0
  137. data/test/installation/test_multipart.rb +51 -0
  138. data/test/installation/test_request.rb +24 -0
  139. data/test/installation/test_response.rb +35 -0
  140. data/test/unit/htdocs/cookie.rb +32 -0
  141. data/test/unit/htdocs/multipart.rb +28 -0
  142. data/test/unit/htdocs/redirect.rb +12 -0
  143. data/test/unit/htdocs/simple.rb +13 -0
  144. data/test/unit/htdocs/stock.rb +33 -0
  145. data/test/unit/test_assert.rb +162 -0
  146. data/test/unit/test_cookie.rb +114 -0
  147. data/test/unit/test_domwalker.rb +77 -0
  148. data/test/unit/test_form.rb +42 -0
  149. data/test/unit/test_frame.rb +40 -0
  150. data/test/unit/test_htmlelem.rb +74 -0
  151. data/test/unit/test_image.rb +45 -0
  152. data/test/unit/test_jscript.rb +57 -0
  153. data/test/unit/test_link.rb +85 -0
  154. data/test/unit/test_multipart.rb +51 -0
  155. data/test/unit/test_params.rb +210 -0
  156. data/test/unit/test_parser.rb +53 -0
  157. data/test/unit/test_response.rb +150 -0
  158. data/test/unit/test_table.rb +70 -0
  159. data/test/unit/test_utils.rb +106 -0
  160. data/test/unit/test_webunit.rb +28 -0
  161. data/test/web/mod_ruby_stub.rb +39 -0
  162. data/test/web/test.assertinclude.rb +109 -0
  163. data/test/web/test.buffer.rb +182 -0
  164. data/test/web/test.code.loader.rb +78 -0
  165. data/test/web/test.config.rb +31 -0
  166. data/test/web/test.error.handling.rb +91 -0
  167. data/test/web/test.formreader-2.0.rb +352 -0
  168. data/test/web/test.load.rb +125 -0
  169. data/test/web/test.mime-type.rb +23 -0
  170. data/test/web/test.narf.cgi.rb +106 -0
  171. data/test/web/test.phprb.rb +239 -0
  172. data/test/web/test.request.rb +368 -0
  173. data/test/web/test.response.rb +637 -0
  174. data/test/web/test.ruby-web.rb +10 -0
  175. data/test/web/test.session.rb +50 -0
  176. data/test/web/test.shim.cgi.rb +96 -0
  177. data/test/web/test.tagparser.rb +65 -0
  178. data/test/web/test.template2.rb +297 -0
  179. data/test/web/test.testing2.rb +318 -0
  180. data/test/web/test.upload.rb +45 -0
  181. data/test/web/test.validate.rb +46 -0
  182. data/test/web/test.web.test.rb +495 -0
  183. data/test/wiki/test.history.rb +297 -0
  184. data/test/wiki/test.illustration_page.rb +287 -0
  185. data/test/wiki/test.linker.rb +197 -0
  186. data/test/wiki/test.tarpit.rb +56 -0
  187. data/test/wiki/test.wiki.rb +300 -0
  188. data/test/wikitestroot/admin.rb +7 -0
  189. data/test/wikitestroot/wiki.rb +6 -0
  190. metadata +234 -0
@@ -0,0 +1,149 @@
1
+ #
2
+ # $Id: ftp.rb,v 1.1.1.1 2002/11/29 04:34:25 patsplat Exp $
3
+ #
4
+ # Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
5
+ # You can redistribute it and/or modify it under the same term as Ruby.
6
+ #
7
+
8
+ require 'uri/generic'
9
+
10
+ module URI
11
+
12
+ =begin
13
+
14
+ == URI::FTP
15
+
16
+ === Super Class
17
+
18
+ ((<URI::Generic>))
19
+
20
+ =end
21
+
22
+ # RFC1738 section 3.2.
23
+ class FTP < Generic
24
+ DEFAULT_PORT = 21
25
+
26
+ COMPONENT = [
27
+ :scheme,
28
+ :userinfo, :host, :port,
29
+ :path, :typecode
30
+ ].freeze
31
+
32
+ TYPECODE = ['a', 'i', 'd'].freeze
33
+ TYPECODE_PREFIX = ';type='.freeze
34
+
35
+ =begin
36
+
37
+ === Class Methods
38
+
39
+ --- URI::FTP::build
40
+ Create a new URI::FTP object from components of URI::FTP with
41
+ check. It is scheme, userinfo, host, port, path and typecode. It
42
+ provided by an Array or a Hash. typecode is "a", "i" or "d".
43
+
44
+ --- URI::FTP::new
45
+ Create a new URI::FTP object from ``generic'' components with no
46
+ check.
47
+
48
+ =end
49
+
50
+ def self.new2(user, password, host, port, path,
51
+ typecode = nil, arg_check = true)
52
+ typecode = nil if typecode.size == 0
53
+ if typecode && !TYPECODE.include?(typecode)
54
+ raise ArgumentError,
55
+ "bad typecode is specified: #{typecode}"
56
+ end
57
+
58
+ # do escape
59
+
60
+ self.new('ftp',
61
+ [user, password],
62
+ host, port, nil,
63
+ typecode ? path + TYPECODE_PREFIX + typecode : path,
64
+ nil, nil, nil, arg_check)
65
+ end
66
+
67
+ def self.build(args)
68
+ tmp = Util::make_components_hash(self, args)
69
+
70
+ if tmp[:typecode]
71
+ if tmp[:typecode].size == 1
72
+ tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode]
73
+ end
74
+ tmp[:path] << tmp[:typecode]
75
+ end
76
+
77
+ return super(tmp)
78
+ end
79
+
80
+ def initialize(*arg)
81
+ super(*arg)
82
+ @typecode = nil
83
+ tmp = @path.index(TYPECODE_PREFIX)
84
+ if tmp
85
+ typecode = @path[tmp + TYPECODE_PREFIX.size..-1]
86
+ self.set_path(@path[0..tmp - 1])
87
+
88
+ if arg[-1]
89
+ self.typecode = typecode
90
+ else
91
+ self.set_typecode(typecode)
92
+ end
93
+ end
94
+ end
95
+ attr_reader :typecode
96
+
97
+ #
98
+ # methods for typecode
99
+ #
100
+
101
+ def check_typecode(v)
102
+ if TYPECODE.include?(v)
103
+ return true
104
+ else
105
+ raise InvalidComponentError,
106
+ "bad typecode(expected #{TYPECODE.join(', ')}): #{v}"
107
+ end
108
+ end
109
+ private :check_typecode
110
+
111
+ def set_typecode(v)
112
+ @typecode = v
113
+ end
114
+ protected :set_typecode
115
+
116
+ def typecode=(typecode)
117
+ check_typecode(typecode)
118
+ set_typecode(typecode)
119
+ end
120
+
121
+ =begin
122
+ =end
123
+ def merge(oth)
124
+ tmp = super(oth)
125
+ if self != tmp
126
+ tmp.set_typecode(oth.typecode)
127
+ end
128
+
129
+ return tmp
130
+ end
131
+
132
+ =begin
133
+ =end
134
+ def to_str
135
+ save_path = nil
136
+ if @typecode
137
+ save_path = @path
138
+ @path = @path + TYPECODE_PREFIX + @typecode
139
+ end
140
+ str = super
141
+ if @typecode
142
+ @path = save_path
143
+ end
144
+
145
+ return str
146
+ end
147
+ end # FTP
148
+ @@schemes['FTP'] = FTP
149
+ end # URI
@@ -0,0 +1,1106 @@
1
+ #
2
+ # $Id: generic.rb,v 1.1.1.1 2002/11/29 04:34:25 patsplat Exp $
3
+ #
4
+ # Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
5
+ # You can redistribute it and/or modify it under the same term as Ruby.
6
+ #
7
+
8
+ require 'uri/common'
9
+
10
+ module URI
11
+
12
+ =begin
13
+
14
+ == URI::Generic
15
+
16
+ === Super Class
17
+
18
+ Object
19
+
20
+ =end
21
+
22
+ class Generic
23
+ include REGEXP
24
+
25
+ =begin
26
+
27
+ === Class Methods
28
+
29
+ --- URI::Generic::default_port
30
+
31
+ =end
32
+ DEFAULT_PORT = nil
33
+
34
+ def self.default_port
35
+ self::DEFAULT_PORT
36
+ end
37
+
38
+ def default_port
39
+ self.type.default_port
40
+ end
41
+
42
+ =begin
43
+ --- URI::Generic::component
44
+ =end
45
+ COMPONENT = [
46
+ :scheme,
47
+ :userinfo, :host, :port, :registry,
48
+ :path, :opaque,
49
+ :query,
50
+ :fragment
51
+ ].freeze
52
+
53
+ def self.component
54
+ self::COMPONENT
55
+ end
56
+
57
+ =begin
58
+ --- URI::Generic::use_registry
59
+ =end
60
+ USE_REGISTRY = false
61
+
62
+ def self.use_registry
63
+ self::USE_REGISTRY
64
+ end
65
+
66
+ =begin
67
+
68
+ --- URI::Generic::build2
69
+ At first, try to create a new URI::Generic object using
70
+ URI::Generic::build. But, if you get a exception
71
+ URI::InvalidComponentError, then re-try to create an object with
72
+ escaped components.
73
+
74
+ --- URI::Generic::build
75
+ Create a new URI::Generic object from components of URI::Generic
76
+ with check. It is scheme, userinfo, host, port, registry, path,
77
+ opaque, query and fragment. It provided by an Array of a Hash.
78
+
79
+ --- URI::Generic::new
80
+ Create new URI::Generic object from ``generic'' components with no
81
+ check.
82
+
83
+ =end
84
+ def self.build2(args)
85
+ begin
86
+ return self.build(args)
87
+ rescue InvalidComponentError
88
+ if args.kind_of?(Array)
89
+ return self.build(args.collect{|x|
90
+ if x
91
+ URI.escape(x)
92
+ else
93
+ x
94
+ end
95
+ })
96
+ elsif args.kind_of?(Hash)
97
+ tmp = {}
98
+ args.each do |key, value|
99
+ tmp[key] = if value
100
+ URI.escape(value)
101
+ else
102
+ value
103
+ end
104
+ end
105
+ return self.build(tmp)
106
+ end
107
+ end
108
+ end
109
+
110
+ def self.build(args)
111
+ if args.kind_of?(Array) &&
112
+ args.size == ::URI::Generic::COMPONENT.size
113
+ tmp = args
114
+ elsif args.kind_of?(Hash)
115
+ tmp = ::URI::Generic::COMPONENT.collect do |c|
116
+ if args.include?(c)
117
+ args[c]
118
+ else
119
+ nil
120
+ end
121
+ end
122
+ else
123
+ raise ArgumentError,
124
+ "expected Array of or Hash of components of #{self.type} (#{self.type.component.join(', ')})"
125
+ end
126
+
127
+ tmp << true
128
+ return self.new(*tmp)
129
+ end
130
+
131
+ def initialize(scheme,
132
+ userinfo, host, port, registry,
133
+ path, opaque,
134
+ query,
135
+ fragment,
136
+ arg_check = false)
137
+ @scheme = nil
138
+ @user = nil
139
+ @password = nil
140
+ @host = nil
141
+ @port = nil
142
+ @path = nil
143
+ @query = nil
144
+ @opaque = nil
145
+ @registry = nil
146
+ @fragment = nil
147
+
148
+ if arg_check
149
+ self.scheme = scheme
150
+ self.userinfo = userinfo
151
+ self.host = host
152
+ self.port = port
153
+ self.path = path
154
+ self.query = query
155
+ self.opaque = opaque
156
+ self.registry = registry
157
+ self.fragment = fragment
158
+ else
159
+ self.set_scheme(scheme)
160
+ self.set_userinfo(userinfo)
161
+ self.set_host(host)
162
+ self.set_port(port)
163
+ self.set_path(path)
164
+ self.set_query(query)
165
+ self.set_opaque(opaque)
166
+ self.set_registry(registry)
167
+ self.set_fragment(fragment)
168
+ end
169
+ if @registry && !self.class.use_registry
170
+ raise InvalidURIError, "the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)"
171
+ end
172
+
173
+ @scheme.freeze if @scheme
174
+ self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
175
+ self.set_port(self.default_port) if self.default_port && !@port
176
+ end
177
+ attr_reader :scheme
178
+ attr_reader :host
179
+ attr_reader :port
180
+ attr_reader :registry
181
+ attr_reader :path
182
+ attr_reader :query
183
+ attr_reader :opaque
184
+ attr_reader :fragment
185
+
186
+ =begin
187
+
188
+ === Instance Methods
189
+
190
+ =end
191
+
192
+ =begin
193
+
194
+ --- URI::Generic#component
195
+
196
+ =end
197
+ def component
198
+ self.type.component
199
+ end
200
+
201
+ # set_XXX method sets value to @XXX instance variable with no check,
202
+ # so be careful if you use these methods. or, you use these method
203
+ # with check_XXX method, or you use XXX= methods.
204
+
205
+ =begin
206
+
207
+ --- URI::Generic#scheme
208
+
209
+ --- URI::Generic#scheme=(v)
210
+
211
+ =end
212
+ #
213
+ # methods for scheme
214
+ #
215
+ def check_scheme(v)
216
+ if v && SCHEME !~ v
217
+ raise InvalidComponentError,
218
+ "bad component(expected scheme component): #{v}"
219
+ end
220
+
221
+ return true
222
+ end
223
+ private :check_scheme
224
+
225
+ def set_scheme(v)
226
+ @scheme = v
227
+ end
228
+ protected :set_scheme
229
+
230
+ def scheme=(v)
231
+ check_scheme(v)
232
+ set_scheme(v)
233
+ end
234
+
235
+ =begin
236
+
237
+ --- URI::Generic#userinfo
238
+
239
+ --- URI::Generic#userinfo=(v)
240
+
241
+ --- URI::Generic#user
242
+
243
+ --- URI::Generic#user=(v)
244
+
245
+ --- URI::Generic#password
246
+
247
+ --- URI::Generic#password=(v)
248
+
249
+ =end
250
+ #
251
+ # methods for userinfo
252
+ #
253
+ def check_userinfo(user, password = nil)
254
+ if (user || password) &&
255
+ (@registry || @opaque)
256
+ raise InvalidURIError,
257
+ "can not set userinfo with registry or opaque"
258
+ end
259
+
260
+ if !password
261
+ user, password = split_userinfo(user)
262
+ end
263
+ check_user(user)
264
+ check_password(password)
265
+
266
+ return true
267
+ end
268
+ private :check_userinfo
269
+
270
+ def check_user(v)
271
+ return v unless v
272
+
273
+ if USERINFO !~ v
274
+ raise InvalidComponentError,
275
+ "bad component(expected userinfo component or user component): #{v}"
276
+ end
277
+
278
+ return true
279
+ end
280
+ private :check_user
281
+
282
+ def check_password(v)
283
+ return v unless v
284
+
285
+ if !@password
286
+ raise InvalidURIError,
287
+ "password component depends user component"
288
+ end
289
+
290
+ if USERINFO !~ v
291
+ raise InvalidComponentError,
292
+ "bad component(expected user component): #{v}"
293
+ end
294
+
295
+ return true
296
+ end
297
+ private :check_password
298
+
299
+ def userinfo=(userinfo)
300
+ if userinfo.nil?
301
+ return nil
302
+ end
303
+ check_userinfo(*userinfo)
304
+ set_userinfo(*userinfo)
305
+ end
306
+
307
+ def user=(user)
308
+ check_user(user)
309
+ set_user(user)
310
+ end
311
+
312
+ def password=(password)
313
+ check_password(password)
314
+ set_password(password)
315
+ end
316
+
317
+ def set_userinfo(user, password = nil)
318
+ unless password
319
+ user, password = split_userinfo(user)
320
+ end
321
+ @user = user
322
+ @password = password if password
323
+
324
+ [@user, @password]
325
+ end
326
+ protected :set_userinfo
327
+
328
+ def set_user(v)
329
+ set_userinfo(v, @password)
330
+ v
331
+ end
332
+ protected :set_user
333
+
334
+ def set_password(v)
335
+ set_userinfo(@user, v)
336
+ v
337
+ end
338
+ protected :set_password
339
+
340
+ def split_userinfo(ui)
341
+ return nil, nil unless ui
342
+ tmp = ui.index(':')
343
+ if tmp
344
+ user = ui[0..tmp - 1]
345
+ password = ui[tmp + 1..-1]
346
+ else
347
+ user = ui
348
+ password = nil
349
+ end
350
+
351
+ return user, password
352
+ end
353
+ private :split_userinfo
354
+
355
+ def escape_userpass(v)
356
+ v = URI.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
357
+ end
358
+ private :escape_userpass
359
+
360
+ def userinfo
361
+ if !@password
362
+ @user
363
+ else
364
+ @user + ':' + @password
365
+ end
366
+ end
367
+
368
+ def user
369
+ @user
370
+ end
371
+
372
+ def password
373
+ @password
374
+ end
375
+
376
+ =begin
377
+
378
+ --- URI::Generic#host
379
+
380
+ --- URI::Generic#host=(v)
381
+
382
+ =end
383
+ #
384
+ # methods for host
385
+ #
386
+
387
+ def check_host(v)
388
+ return v unless v
389
+
390
+ if @registry || @opaque
391
+ raise InvalidURIError,
392
+ "can not set host with registry or opaque"
393
+ elsif HOST !~ v
394
+ raise InvalidComponentError,
395
+ "bad component(expected host component): #{v}"
396
+ end
397
+
398
+ return true
399
+ end
400
+ private :check_host
401
+
402
+ def set_host(v)
403
+ @host = v
404
+ end
405
+ protected :set_host
406
+
407
+ def host=(v)
408
+ check_host(v)
409
+ set_host(v)
410
+ end
411
+
412
+ =begin
413
+
414
+ --- URI::Generic#port
415
+
416
+ --- URI::Generic#port=(v)
417
+
418
+ =end
419
+ #
420
+ # methods for port
421
+ #
422
+
423
+ def check_port(v)
424
+ return v unless v
425
+
426
+ if @registry || @opaque
427
+ raise InvalidURIError,
428
+ "can not set port with registry or opaque"
429
+ elsif !v.kind_of?(Fixnum) && PORT !~ v
430
+ raise InvalidComponentError,
431
+ "bad component(expected port component): #{v}"
432
+ end
433
+
434
+ return true
435
+ end
436
+ private :check_port
437
+
438
+ def set_port(v)
439
+ v = v.to_i if v && !v.kind_of?(Fixnum)
440
+ @port = v
441
+ end
442
+ protected :set_port
443
+
444
+ def port=(v)
445
+ check_port(v)
446
+ set_port(v)
447
+ end
448
+
449
+ =begin
450
+
451
+ --- URI::Generic#registry
452
+
453
+ --- URI::Generic#registry=(v)
454
+
455
+ =end
456
+ #
457
+ # methods for registry
458
+ #
459
+
460
+ def check_registry(v)
461
+ return v unless v
462
+
463
+ # raise if both server and registry are not nil, because:
464
+ # authority = server | reg_name
465
+ # server = [ [ userinfo "@" ] hostport ]
466
+ if @host || @port || @user # userinfo = @user + ':' + @password
467
+ raise InvalidURIError,
468
+ "can not set registry with host, port, or userinfo"
469
+ elsif v && REGISTRY !~ v
470
+ raise InvalidComponentError,
471
+ "bad component(expected registry component): #{v}"
472
+ end
473
+
474
+ return true
475
+ end
476
+ private :check_registry
477
+
478
+ def set_registry(v)
479
+ @registry = v
480
+ end
481
+ protected :set_registry
482
+
483
+ def registry=(v)
484
+ check_registry(v)
485
+ set_registry(v)
486
+ end
487
+
488
+ =begin
489
+
490
+ --- URI::Generic#path
491
+
492
+ --- URI::Generic#path=(v)
493
+
494
+ =end
495
+ #
496
+ # methods for path
497
+ #
498
+
499
+ def check_path(v)
500
+ # raise if both hier and opaque are not nil, because:
501
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
502
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
503
+ if v && @opaque
504
+ raise InvalidURIError,
505
+ "path conflicts with opaque"
506
+ end
507
+
508
+ if @scheme
509
+ if v && v != '' && ABS_PATH !~ v
510
+ raise InvalidComponentError,
511
+ "bad component(expected absolute path component): #{v}"
512
+ end
513
+ else
514
+ if v && v != '' && ABS_PATH !~ v && REL_PATH !~ v
515
+ raise InvalidComponentError,
516
+ "bad component(expected relative path component): #{v}"
517
+ end
518
+ end
519
+
520
+ return true
521
+ end
522
+ private :check_path
523
+
524
+ def set_path(v)
525
+ @path = v
526
+ end
527
+ protected :set_path
528
+
529
+ def path=(v)
530
+ check_path(v)
531
+ set_path(v)
532
+ end
533
+
534
+ =begin
535
+
536
+ --- URI::Generic#query
537
+
538
+ --- URI::Generic#query=(v)
539
+
540
+ =end
541
+ #
542
+ # methods for query
543
+ #
544
+
545
+ def check_query(v)
546
+ return v unless v
547
+
548
+ # raise if both hier and opaque are not nil, because:
549
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
550
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
551
+ if @opaque
552
+ raise InvalidURIError,
553
+ "query conflicts with opaque"
554
+ end
555
+
556
+ if v && v != '' && QUERY !~ v
557
+ raise InvalidComponentError,
558
+ "bad component(expected query component): #{v}"
559
+ end
560
+
561
+ return true
562
+ end
563
+ private :check_query
564
+
565
+ def set_query(v)
566
+ @query = v
567
+ end
568
+ protected :set_query
569
+
570
+ def query=(v)
571
+ check_query(v)
572
+ set_query(v)
573
+ end
574
+
575
+ =begin
576
+
577
+ --- URI::Generic#opaque
578
+
579
+ --- URI::Generic#opaque=(v)
580
+
581
+ =end
582
+ #
583
+ # methods for opaque
584
+ #
585
+
586
+ def check_opaque(v)
587
+ return v unless v
588
+
589
+ # raise if both hier and opaque are not nil, because:
590
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
591
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
592
+ if @host || @port || @usr || @path # userinfo = @user + ':' + @password
593
+ raise InvalidURIError,
594
+ "can not set opaque with host, port, userinfo or path"
595
+ elsif v && OPAQUE !~ v
596
+ raise InvalidComponentError,
597
+ "bad component(expected opaque component): #{v}"
598
+ end
599
+
600
+ return true
601
+ end
602
+ private :check_opaque
603
+
604
+ def set_opaque(v)
605
+ @opaque = v
606
+ end
607
+ protected :set_opaque
608
+
609
+ def opaque=(v)
610
+ check_opaque(v)
611
+ set_opaque(v)
612
+ end
613
+
614
+ =begin
615
+
616
+ --- URI::Generic#fragment
617
+
618
+ --- URI::Generic#fragment=(v)
619
+
620
+ =end
621
+ #
622
+ # methods for fragment
623
+ #
624
+
625
+ def check_fragment(v)
626
+ return v unless v
627
+
628
+ if v && v != '' && FRAGMENT !~ v
629
+ raise InvalidComponentError,
630
+ "bad component(expected fragment component): #{v}"
631
+ end
632
+
633
+ return true
634
+ end
635
+ private :check_fragment
636
+
637
+ def set_fragment(v)
638
+ @fragment = v
639
+ end
640
+ protected :set_fragment
641
+
642
+ def fragment=(v)
643
+ check_fragment(v)
644
+ set_fragment(v)
645
+ end
646
+
647
+ =begin
648
+
649
+ --- URI::Generic#hierarchical?
650
+
651
+ =end
652
+ def hierarchical?
653
+ if @path
654
+ true
655
+ else
656
+ false
657
+ end
658
+ end
659
+
660
+ =begin
661
+
662
+ --- URI::Generic#absolute?
663
+
664
+ =end
665
+ def absolute?
666
+ if @scheme
667
+ true
668
+ else
669
+ false
670
+ end
671
+ end
672
+ alias absolute absolute?
673
+
674
+ =begin
675
+
676
+ --- URI::Generic#relative?
677
+
678
+ =end
679
+ def relative?
680
+ !absolute?
681
+ end
682
+
683
+ =begin
684
+
685
+ --- URI::Generic#merge(rel)
686
+ --- URI::Generic#+(rel)
687
+
688
+ =end
689
+ def split_path(path)
690
+ path.split(%r{/+}, -1)
691
+ end
692
+ private :split_path
693
+
694
+ def merge_path(base, rel)
695
+ # RFC2396, Section 5.2, 5)
696
+ if rel[0] == ?/ #/
697
+ # RFC2396, Section 5.2, 5)
698
+ return rel
699
+
700
+ else
701
+ # RFC2396, Section 5.2, 6)
702
+ base_path = split_path(base)
703
+ rel_path = split_path(rel)
704
+
705
+ if base_path.empty?
706
+ base_path = [''] # XXX
707
+ end
708
+
709
+ # RFC2396, Section 5.2, 6), a)
710
+ base_path.pop unless base_path.size == 1
711
+
712
+ # RFC2396, Section 5.2, 6), c)
713
+ # RFC2396, Section 5.2, 6), d)
714
+ rel_path.push('') if rel_path.last == '.'
715
+ rel_path.delete('.')
716
+
717
+ # RFC2396, Section 5.2, 6), e)
718
+ tmp = []
719
+ rel_path.each do |x|
720
+ if x == '..' &&
721
+ !(tmp.empty? || tmp.last == '..')
722
+ tmp.pop
723
+ else
724
+ tmp << x
725
+ end
726
+ end
727
+
728
+ add_trailer_slash = true
729
+ while x = tmp.shift
730
+ if x == '..' && base_path.size > 1
731
+ # RFC2396, Section 4
732
+ # a .. or . in an absolute path has no special meaning
733
+ base_path.pop
734
+ else
735
+ # if x == '..'
736
+ # valid absolute (but abnormal) path "/../..."
737
+ # else
738
+ # valid absolute path
739
+ # end
740
+ base_path << x
741
+ tmp.each {|t| base_path << t}
742
+ add_trailer_slash = false
743
+ break
744
+ end
745
+ end
746
+ base_path.push('') if add_trailer_slash
747
+
748
+ return base_path.join('/')
749
+ end
750
+ end
751
+ private :merge_path
752
+
753
+ # abs(self) + rel(oth) => abs(new)
754
+ def merge(oth)
755
+ base, rel = merge0(oth)
756
+ if base == rel
757
+ return base
758
+ end
759
+
760
+ authority = rel.userinfo || rel.host || rel.port
761
+
762
+ # RFC2396, Section 5.2, 2)
763
+ if rel.path.empty? && !authority && !rel.query
764
+ base.set_fragment(rel.fragment) if rel.fragment
765
+ return base
766
+ end
767
+
768
+ base.set_query(nil)
769
+ base.set_fragment(nil)
770
+
771
+ # RFC2396, Section 5.2, 4)
772
+ if !authority
773
+ base.set_path(merge_path(base.path, rel.path))
774
+ else
775
+ # RFC2396, Section 5.2, 4)
776
+ base.set_path(rel.path)
777
+ end
778
+
779
+ # RFC2396, Section 5.2, 7)
780
+ base.set_userinfo(rel.userinfo) if rel.userinfo
781
+ base.set_host(rel.host) if rel.host
782
+ base.set_port(rel.port) if rel.port
783
+ base.set_query(rel.query) if rel.query
784
+ base.set_fragment(rel.fragment) if rel.fragment
785
+
786
+ return base
787
+ end # merge
788
+ alias + merge
789
+
790
+ # return base and rel.
791
+ # you can modify `base', but can not `rel'.
792
+ def merge0(oth)
793
+ case oth
794
+ when Generic
795
+ when String
796
+ oth = URI.parse(oth)
797
+ else
798
+ raise ArgumentError,
799
+ "bad argument(expected URI object or URI string)"
800
+ end
801
+
802
+ if self.relative? && oth.relative?
803
+ raise BadURIError,
804
+ "both URI are relative"
805
+ end
806
+
807
+ if self.absolute? && oth.absolute?
808
+ #raise BadURIError,
809
+ # "both URI are absolute"
810
+ # hmm... should return oth for usability?
811
+ return oth, oth
812
+ end
813
+
814
+ if !self.hierarchical?
815
+ raise BadURIError,
816
+ "not hierarchical URI: #{self}"
817
+ elsif !oth.hierarchical?
818
+ raise BadURIError,
819
+ "not hierarchical URI: #{oth}"
820
+ end
821
+
822
+ if self.absolute?
823
+ return self.dup, oth
824
+ else
825
+ return oth, oth
826
+ end
827
+ end
828
+ private :merge0
829
+
830
+ =begin
831
+
832
+ --- URI::Generic#route_from(src)
833
+ --- URI::Generic#-(src)
834
+
835
+ =end
836
+ def route_from_path(src, dst)
837
+ # RFC2396, Section 4.2
838
+ return '' if src == dst
839
+
840
+ src_path = split_path(src)
841
+ dst_path = split_path(dst)
842
+
843
+ # hmm... dst has abnormal absolute path,
844
+ # like "/./", "/../", "/x/../", ...
845
+ if dst_path.include?('..') ||
846
+ dst_path.include?('.')
847
+ return dst.dup
848
+ end
849
+
850
+ src_path.pop
851
+
852
+ # discard same parts
853
+ while dst_path.first == src_path.first
854
+ break if dst_path.empty?
855
+
856
+ src_path.shift
857
+ dst_path.shift
858
+ end
859
+
860
+ tmp = dst_path.join('/')
861
+
862
+ # calculate
863
+ if src_path.empty?
864
+ if tmp.empty?
865
+ return './'
866
+ elsif dst_path.first.include?(':') # (see RFC2396 Section 5)
867
+ return './' + tmp
868
+ else
869
+ return tmp
870
+ end
871
+ end
872
+
873
+ return '../' * src_path.size + tmp
874
+ end
875
+ private :route_from_path
876
+
877
+ def route_from0(oth)
878
+ case oth
879
+ when Generic
880
+ when String
881
+ oth = URI.parse(oth)
882
+ else
883
+ raise ArgumentError,
884
+ "bad argument(expected URI object or URI string)"
885
+ end
886
+
887
+ if self.relative?
888
+ raise BadURIError,
889
+ "relative URI: #{self}"
890
+ end
891
+ if oth.relative?
892
+ raise BadURIError,
893
+ "relative URI: #{oth}"
894
+ end
895
+
896
+ if !self.hierarchical? || !oth.hierarchical?
897
+ return self, self.dup
898
+ end
899
+
900
+ if self.scheme != oth.scheme
901
+ return oth, oth.dup
902
+ end
903
+ rel = URI::Generic.new(nil, # it is relative URI
904
+ self.userinfo, self.host, self.port,
905
+ self.registry, self.path, self.opaque,
906
+ self.query, self.fragment)
907
+
908
+ if rel.userinfo != oth.userinfo ||
909
+ rel.host != oth.host ||
910
+ rel.port != oth.port
911
+ rel.set_port(nil) if rel.port == oth.default_port
912
+ return rel, rel
913
+ end
914
+ rel.set_userinfo(nil)
915
+ rel.set_host(nil)
916
+ rel.set_port(nil)
917
+
918
+ if rel.path == oth.path
919
+ rel.set_path('')
920
+ rel.set_query(nil) if rel.query == oth.query
921
+ return rel, rel
922
+ end
923
+
924
+ # you can modify `rel', but can not `oth'.
925
+ return oth, rel
926
+ end
927
+ private :route_from0
928
+
929
+ # calculate relative path from oth to self
930
+ def route_from(oth)
931
+ # you can modify `rel', but can not `oth'.
932
+ oth, rel = route_from0(oth)
933
+ if oth == rel
934
+ return rel
935
+ end
936
+
937
+ rel.set_path(route_from_path(oth.path, self.path))
938
+ if rel.path == './' && self.query
939
+ # "./?foo" -> "?foo"
940
+ rel.set_path('')
941
+ end
942
+
943
+ return rel
944
+ end
945
+ # abs1 - abs2 => relative_path_to_abs1_from_abs2
946
+ # (see http://www.nikonet.or.jp/spring/what_v/what_v_4.htm :-)
947
+ alias - route_from
948
+
949
+ =begin
950
+
951
+ --- URI::Generic#route_to(dst)
952
+
953
+ =end
954
+ # calculate relative path to oth from self
955
+ def route_to(oth)
956
+ case oth
957
+ when Generic
958
+ when String
959
+ oth = URI.parse(oth)
960
+ else
961
+ raise ArgumentError,
962
+ "bad argument(expected URI object or URI string)"
963
+ end
964
+
965
+ oth.route_from(self)
966
+ end
967
+
968
+ =begin
969
+
970
+ --- URI::Generic#normalize
971
+ --- URI::Generic#normalize!
972
+
973
+ =end
974
+ def normalize
975
+ uri = dup
976
+ uri.normalize!
977
+ uri
978
+ end
979
+
980
+ def normalize!
981
+ if path && path == ''
982
+ set_path('/')
983
+ end
984
+ if host && host != host.downcase
985
+ set_host(self.host.downcase)
986
+ end
987
+ end
988
+
989
+ =begin
990
+
991
+ --- URI::Generic#to_s
992
+
993
+ =end
994
+ def path_query
995
+ str = @path
996
+ if @query
997
+ str += '?' + @query
998
+ end
999
+ str
1000
+ end
1001
+ private :path_query
1002
+
1003
+ def to_str
1004
+ str = ''
1005
+ if @scheme
1006
+ str << @scheme
1007
+ str << ':'
1008
+ end
1009
+
1010
+ if @opaque
1011
+ str << @opaque
1012
+
1013
+ else
1014
+ if @registry
1015
+ str << @registry
1016
+ else
1017
+ if @host
1018
+ str << '//'
1019
+ end
1020
+ if self.userinfo
1021
+ str << self.userinfo
1022
+ str << '@'
1023
+ end
1024
+ if @host
1025
+ str << @host
1026
+ end
1027
+ if @port && @port != self.default_port
1028
+ str << ':'
1029
+ str << @port.to_s
1030
+ end
1031
+ end
1032
+
1033
+ str << path_query
1034
+ end
1035
+
1036
+ if @fragment
1037
+ str << '#'
1038
+ str << @fragment
1039
+ end
1040
+
1041
+ str
1042
+ end
1043
+
1044
+ def to_s
1045
+ to_str
1046
+ end
1047
+
1048
+ =begin
1049
+
1050
+ --- URI::Generic#==(oth)
1051
+
1052
+ =end
1053
+ def ==(oth)
1054
+ if oth.kind_of?(String)
1055
+ oth = URI.parse(oth)
1056
+ end
1057
+
1058
+ if self.class == oth.class
1059
+ self.normalize.to_ary == oth.normalize.to_ary
1060
+ else
1061
+ false
1062
+ end
1063
+ end
1064
+
1065
+ =begin
1066
+
1067
+ --- URI::Generic#===(oth)
1068
+
1069
+ =end
1070
+ # def ===(oth)
1071
+ # raise NotImplementedError
1072
+ # end
1073
+
1074
+ =begin
1075
+ --- URI::Generic#to_a
1076
+ =end
1077
+ def to_ary
1078
+ component.collect do |x|
1079
+ self.send(x)
1080
+ end
1081
+ end
1082
+
1083
+ def to_a
1084
+ to_ary
1085
+ end
1086
+
1087
+ =begin
1088
+ =end
1089
+ def inspect
1090
+ sprintf("#<%s:0x%x URL:%s>", self.type.to_s, self.id, self.to_s)
1091
+ end
1092
+
1093
+ =begin
1094
+ =end
1095
+ def coerce(oth)
1096
+ case oth
1097
+ when String
1098
+ oth = URI.parse(oth)
1099
+ else
1100
+ super
1101
+ end
1102
+
1103
+ return oth, self
1104
+ end
1105
+ end # Generic
1106
+ end # URI