1require 'test/unit'
2require 'uri'
3
4class URI::TestGeneric < Test::Unit::TestCase
5  def setup
6    @url = 'http://a/b/c/d;p?q'
7    @base_url = URI.parse(@url)
8  end
9
10  def teardown
11  end
12
13  def uri_to_ary(uri)
14    uri.class.component.collect {|c| uri.send(c)}
15  end
16
17  def test_parse
18    # 0
19    assert_kind_of(URI::HTTP, @base_url)
20
21    exp = [
22      'http',
23      nil, 'a', URI::HTTP.default_port,
24      '/b/c/d;p',
25      'q',
26      nil
27    ]
28    ary = uri_to_ary(@base_url)
29    assert_equal(exp, ary)
30
31    # 1
32    url = URI.parse('ftp://ftp.is.co.za/rfc/rfc1808.txt')
33    assert_kind_of(URI::FTP, url)
34
35    exp = [
36      'ftp',
37      nil, 'ftp.is.co.za', URI::FTP.default_port,
38      'rfc/rfc1808.txt', nil,
39    ]
40    ary = uri_to_ary(url)
41    assert_equal(exp, ary)
42    # 1'
43    url = URI.parse('ftp://ftp.is.co.za/%2Frfc/rfc1808.txt')
44    assert_kind_of(URI::FTP, url)
45
46    exp = [
47      'ftp',
48      nil, 'ftp.is.co.za', URI::FTP.default_port,
49      '/rfc/rfc1808.txt', nil,
50    ]
51    ary = uri_to_ary(url)
52    assert_equal(exp, ary)
53
54    # 2
55    url = URI.parse('gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles')
56    assert_kind_of(URI::Generic, url)
57
58    exp = [
59      'gopher',
60      nil, 'spinaltap.micro.umn.edu', nil, nil,
61      '/00/Weather/California/Los%20Angeles', nil,
62      nil,
63      nil
64    ]
65    ary = uri_to_ary(url)
66    assert_equal(exp, ary)
67
68    # 3
69    url = URI.parse('http://www.math.uio.no/faq/compression-faq/part1.html')
70    assert_kind_of(URI::HTTP, url)
71
72    exp = [
73      'http',
74      nil, 'www.math.uio.no', URI::HTTP.default_port,
75      '/faq/compression-faq/part1.html',
76      nil,
77      nil
78    ]
79    ary = uri_to_ary(url)
80    assert_equal(exp, ary)
81
82    # 4
83    url = URI.parse('mailto:mduerst@ifi.unizh.ch')
84    assert_kind_of(URI::Generic, url)
85
86    exp = [
87      'mailto',
88      'mduerst@ifi.unizh.ch',
89      []
90    ]
91    ary = uri_to_ary(url)
92    assert_equal(exp, ary)
93
94    # 5
95    url = URI.parse('news:comp.infosystems.www.servers.unix')
96    assert_kind_of(URI::Generic, url)
97
98    exp = [
99      'news',
100      nil, nil, nil, nil,
101      nil, 'comp.infosystems.www.servers.unix',
102      nil,
103      nil
104    ]
105    ary = uri_to_ary(url)
106    assert_equal(exp, ary)
107
108    # 6
109    url = URI.parse('telnet://melvyl.ucop.edu/')
110    assert_kind_of(URI::Generic, url)
111
112    exp = [
113      'telnet',
114      nil, 'melvyl.ucop.edu', nil, nil,
115      '/', nil,
116      nil,
117      nil
118    ]
119    ary = uri_to_ary(url)
120    assert_equal(exp, ary)
121
122    # 7
123    # reported by Mr. Kubota <em6t-kbt@asahi-net.or.jp>
124    assert_raise(URI::InvalidURIError) { URI.parse('http://a_b:80/') }
125    assert_raise(URI::InvalidURIError) { URI.parse('http://a_b/') }
126
127    # 8
128    # reported by m_seki
129    uri = URI.parse('file:///foo/bar.txt')
130    assert_kind_of(URI::Generic, url)
131    uri = URI.parse('file:/foo/bar.txt')
132    assert_kind_of(URI::Generic, url)
133
134    # 9
135    url = URI.parse('ftp://:pass@localhost/')
136    assert_equal('', url.user, "[ruby-dev:25667]")
137    assert_equal('pass', url.password)
138    assert_equal(':pass', url.userinfo, "[ruby-dev:25667]")
139    url = URI.parse('ftp://user@localhost/')
140    assert_equal('user', url.user)
141    assert_equal(nil, url.password)
142    assert_equal('user', url.userinfo)
143    url = URI.parse('ftp://localhost/')
144    assert_equal(nil, url.user)
145    assert_equal(nil, url.password)
146    assert_equal(nil, url.userinfo)
147  end
148
149  def test_merge
150    u1 = URI.parse('http://foo')
151    u2 = URI.parse('http://foo/')
152    u3 = URI.parse('http://foo/bar')
153    u4 = URI.parse('http://foo/bar/')
154
155    assert_equal(URI.parse('http://foo/baz'), u1 + 'baz')
156    assert_equal(URI.parse('http://foo/baz'), u2 + 'baz')
157    assert_equal(URI.parse('http://foo/baz'), u3 + 'baz')
158    assert_equal(URI.parse('http://foo/bar/baz'), u4 + 'baz')
159
160    assert_equal(URI.parse('http://foo/baz'), u1 + '/baz')
161    assert_equal(URI.parse('http://foo/baz'), u2 + '/baz')
162    assert_equal(URI.parse('http://foo/baz'), u3 + '/baz')
163    assert_equal(URI.parse('http://foo/baz'), u4 + '/baz')
164
165    url = URI.parse('http://hoge/a.html') + 'b.html'
166    assert_equal('http://hoge/b.html', url.to_s, "[ruby-dev:11508]")
167
168    # reported by Mr. Kubota <em6t-kbt@asahi-net.or.jp>
169    url = URI.parse('http://a/b') + 'http://x/y'
170    assert_equal('http://x/y', url.to_s)
171    assert_equal(url, URI.parse('')                     + 'http://x/y')
172    assert_equal(url, URI.parse('').normalize           + 'http://x/y')
173    assert_equal(url, URI.parse('http://a/b').normalize + 'http://x/y')
174
175    u = URI.parse('http://foo/bar/baz')
176    assert_equal(nil, u.merge!(""))
177    assert_equal(nil, u.merge!(u))
178    assert(nil != u.merge!("."))
179    assert_equal('http://foo/bar/', u.to_s)
180    assert(nil != u.merge!("../baz"))
181    assert_equal('http://foo/baz', u.to_s)
182
183    u0 = URI.parse('mailto:foo@example.com')
184    u1 = URI.parse('mailto:foo@example.com#bar')
185    assert_equal(uri_to_ary(u0 + '#bar'), uri_to_ary(u1), "[ruby-dev:23628]")
186
187    u0 = URI.parse('http://www.example.com/')
188    u1 = URI.parse('http://www.example.com/foo/..') + './'
189    assert_equal(u0, u1, "[ruby-list:39838]")
190    u0 = URI.parse('http://www.example.com/foo/')
191    u1 = URI.parse('http://www.example.com/foo/bar/..') + './'
192    assert_equal(u0, u1)
193    u0 = URI.parse('http://www.example.com/foo/bar/')
194    u1 = URI.parse('http://www.example.com/foo/bar/baz/..') + './'
195    assert_equal(u0, u1)
196    u0 = URI.parse('http://www.example.com/')
197    u1 = URI.parse('http://www.example.com/foo/bar/../..') + './'
198    assert_equal(u0, u1)
199    u0 = URI.parse('http://www.example.com/foo/')
200    u1 = URI.parse('http://www.example.com/foo/bar/baz/../..') + './'
201    assert_equal(u0, u1)
202
203    u = URI.parse('http://www.example.com/')
204    u0 = u + './foo/'
205    u1 = u + './foo/bar/..'
206    assert_equal(u0, u1, "[ruby-list:39844]")
207    u = URI.parse('http://www.example.com/')
208    u0 = u + './'
209    u1 = u + './foo/bar/../..'
210    assert_equal(u0, u1)
211  end
212
213  def test_route
214    url = URI.parse('http://hoge/a.html').route_to('http://hoge/b.html')
215    assert_equal('b.html', url.to_s)
216
217    url = URI.parse('http://hoge/a/').route_to('http://hoge/b/')
218    assert_equal('../b/', url.to_s)
219    url = URI.parse('http://hoge/a/b').route_to('http://hoge/b/')
220    assert_equal('../b/', url.to_s)
221
222    url = URI.parse('http://hoge/a/b/').route_to('http://hoge/b/')
223    assert_equal('../../b/', url.to_s)
224
225    url = URI.parse('http://hoge/a/b/').route_to('http://HOGE/b/')
226    assert_equal('../../b/', url.to_s)
227
228    url = URI.parse('http://hoge/a/b/').route_to('http://MOGE/b/')
229    assert_equal('//MOGE/b/', url.to_s)
230
231    url = URI.parse('http://hoge/b').route_to('http://hoge/b/')
232    assert_equal('b/', url.to_s)
233    url = URI.parse('http://hoge/b/a').route_to('http://hoge/b/')
234    assert_equal('./', url.to_s)
235    url = URI.parse('http://hoge/b/').route_to('http://hoge/b')
236    assert_equal('../b', url.to_s)
237    url = URI.parse('http://hoge/b').route_to('http://hoge/b:c')
238    assert_equal('./b:c', url.to_s)
239
240    url = URI.parse('file:///a/b/').route_to('file:///a/b/')
241    assert_equal('', url.to_s)
242    url = URI.parse('file:///a/b/').route_to('file:///a/b')
243    assert_equal('../b', url.to_s)
244
245    url = URI.parse('mailto:foo@example.com').route_to('mailto:foo@example.com#bar')
246    assert_equal('#bar', url.to_s)
247
248    url = URI.parse('mailto:foo@example.com#bar').route_to('mailto:foo@example.com')
249    assert_equal('', url.to_s)
250
251    url = URI.parse('mailto:foo@example.com').route_to('mailto:foo@example.com')
252    assert_equal('', url.to_s)
253  end
254
255  def test_rfc3986_examples
256#  http://a/b/c/d;p?q
257#        g:h           =  g:h
258    url = @base_url.merge('g:h')
259    assert_kind_of(URI::Generic, url)
260    assert_equal('g:h', url.to_s)
261    url = @base_url.route_to('g:h')
262    assert_kind_of(URI::Generic, url)
263    assert_equal('g:h', url.to_s)
264
265#  http://a/b/c/d;p?q
266#        g             =  http://a/b/c/g
267    url = @base_url.merge('g')
268    assert_kind_of(URI::HTTP, url)
269    assert_equal('http://a/b/c/g', url.to_s)
270    url = @base_url.route_to('http://a/b/c/g')
271    assert_kind_of(URI::Generic, url)
272    assert_equal('g', url.to_s)
273
274#  http://a/b/c/d;p?q
275#        ./g           =  http://a/b/c/g
276    url = @base_url.merge('./g')
277    assert_kind_of(URI::HTTP, url)
278    assert_equal('http://a/b/c/g', url.to_s)
279    url = @base_url.route_to('http://a/b/c/g')
280    assert_kind_of(URI::Generic, url)
281    assert('./g' != url.to_s) # ok
282    assert_equal('g', url.to_s)
283
284#  http://a/b/c/d;p?q
285#        g/            =  http://a/b/c/g/
286    url = @base_url.merge('g/')
287    assert_kind_of(URI::HTTP, url)
288    assert_equal('http://a/b/c/g/', url.to_s)
289    url = @base_url.route_to('http://a/b/c/g/')
290    assert_kind_of(URI::Generic, url)
291    assert_equal('g/', url.to_s)
292
293#  http://a/b/c/d;p?q
294#        /g            =  http://a/g
295    url = @base_url.merge('/g')
296    assert_kind_of(URI::HTTP, url)
297    assert_equal('http://a/g', url.to_s)
298    url = @base_url.route_to('http://a/g')
299    assert_kind_of(URI::Generic, url)
300    assert('/g' != url.to_s) # ok
301    assert_equal('../../g', url.to_s)
302
303#  http://a/b/c/d;p?q
304#        //g           =  http://g
305    url = @base_url.merge('//g')
306    assert_kind_of(URI::HTTP, url)
307    assert_equal('http://g', url.to_s)
308    url = @base_url.route_to('http://g')
309    assert_kind_of(URI::Generic, url)
310    assert_equal('//g', url.to_s)
311
312#  http://a/b/c/d;p?q
313#        ?y            =  http://a/b/c/d;p?y
314    url = @base_url.merge('?y')
315    assert_kind_of(URI::HTTP, url)
316    assert_equal('http://a/b/c/d;p?y', url.to_s)
317    url = @base_url.route_to('http://a/b/c/d;p?y')
318    assert_kind_of(URI::Generic, url)
319    assert_equal('?y', url.to_s)
320
321#  http://a/b/c/d;p?q
322#        g?y           =  http://a/b/c/g?y
323    url = @base_url.merge('g?y')
324    assert_kind_of(URI::HTTP, url)
325    assert_equal('http://a/b/c/g?y', url.to_s)
326    url = @base_url.route_to('http://a/b/c/g?y')
327    assert_kind_of(URI::Generic, url)
328    assert_equal('g?y', url.to_s)
329
330#  http://a/b/c/d;p?q
331#        #s            =  http://a/b/c/d;p?q#s
332    url = @base_url.merge('#s')
333    assert_kind_of(URI::HTTP, url)
334    assert_equal('http://a/b/c/d;p?q#s', url.to_s)
335    url = @base_url.route_to('http://a/b/c/d;p?q#s')
336    assert_kind_of(URI::Generic, url)
337    assert_equal('#s', url.to_s)
338
339#  http://a/b/c/d;p?q
340#        g#s           =  http://a/b/c/g#s
341    url = @base_url.merge('g#s')
342    assert_kind_of(URI::HTTP, url)
343    assert_equal('http://a/b/c/g#s', url.to_s)
344    url = @base_url.route_to('http://a/b/c/g#s')
345    assert_kind_of(URI::Generic, url)
346    assert_equal('g#s', url.to_s)
347
348#  http://a/b/c/d;p?q
349#        g?y#s         =  http://a/b/c/g?y#s
350    url = @base_url.merge('g?y#s')
351    assert_kind_of(URI::HTTP, url)
352    assert_equal('http://a/b/c/g?y#s', url.to_s)
353    url = @base_url.route_to('http://a/b/c/g?y#s')
354    assert_kind_of(URI::Generic, url)
355    assert_equal('g?y#s', url.to_s)
356
357#  http://a/b/c/d;p?q
358#        ;x            =  http://a/b/c/;x
359    url = @base_url.merge(';x')
360    assert_kind_of(URI::HTTP, url)
361    assert_equal('http://a/b/c/;x', url.to_s)
362    url = @base_url.route_to('http://a/b/c/;x')
363    assert_kind_of(URI::Generic, url)
364    assert_equal(';x', url.to_s)
365
366#  http://a/b/c/d;p?q
367#        g;x           =  http://a/b/c/g;x
368    url = @base_url.merge('g;x')
369    assert_kind_of(URI::HTTP, url)
370    assert_equal('http://a/b/c/g;x', url.to_s)
371    url = @base_url.route_to('http://a/b/c/g;x')
372    assert_kind_of(URI::Generic, url)
373    assert_equal('g;x', url.to_s)
374
375#  http://a/b/c/d;p?q
376#        g;x?y#s       =  http://a/b/c/g;x?y#s
377    url = @base_url.merge('g;x?y#s')
378    assert_kind_of(URI::HTTP, url)
379    assert_equal('http://a/b/c/g;x?y#s', url.to_s)
380    url = @base_url.route_to('http://a/b/c/g;x?y#s')
381    assert_kind_of(URI::Generic, url)
382    assert_equal('g;x?y#s', url.to_s)
383
384#  http://a/b/c/d;p?q
385#        .             =  http://a/b/c/
386    url = @base_url.merge('.')
387    assert_kind_of(URI::HTTP, url)
388    assert_equal('http://a/b/c/', url.to_s)
389    url = @base_url.route_to('http://a/b/c/')
390    assert_kind_of(URI::Generic, url)
391    assert('.' != url.to_s) # ok
392    assert_equal('./', url.to_s)
393
394#  http://a/b/c/d;p?q
395#        ./            =  http://a/b/c/
396    url = @base_url.merge('./')
397    assert_kind_of(URI::HTTP, url)
398    assert_equal('http://a/b/c/', url.to_s)
399    url = @base_url.route_to('http://a/b/c/')
400    assert_kind_of(URI::Generic, url)
401    assert_equal('./', url.to_s)
402
403#  http://a/b/c/d;p?q
404#        ..            =  http://a/b/
405    url = @base_url.merge('..')
406    assert_kind_of(URI::HTTP, url)
407    assert_equal('http://a/b/', url.to_s)
408    url = @base_url.route_to('http://a/b/')
409    assert_kind_of(URI::Generic, url)
410    assert('..' != url.to_s) # ok
411    assert_equal('../', url.to_s)
412
413#  http://a/b/c/d;p?q
414#        ../           =  http://a/b/
415    url = @base_url.merge('../')
416    assert_kind_of(URI::HTTP, url)
417    assert_equal('http://a/b/', url.to_s)
418    url = @base_url.route_to('http://a/b/')
419    assert_kind_of(URI::Generic, url)
420    assert_equal('../', url.to_s)
421
422#  http://a/b/c/d;p?q
423#        ../g          =  http://a/b/g
424    url = @base_url.merge('../g')
425    assert_kind_of(URI::HTTP, url)
426    assert_equal('http://a/b/g', url.to_s)
427    url = @base_url.route_to('http://a/b/g')
428    assert_kind_of(URI::Generic, url)
429    assert_equal('../g', url.to_s)
430
431#  http://a/b/c/d;p?q
432#        ../..         =  http://a/
433    url = @base_url.merge('../..')
434    assert_kind_of(URI::HTTP, url)
435    assert_equal('http://a/', url.to_s)
436    url = @base_url.route_to('http://a/')
437    assert_kind_of(URI::Generic, url)
438    assert('../..' != url.to_s) # ok
439    assert_equal('../../', url.to_s)
440
441#  http://a/b/c/d;p?q
442#        ../../        =  http://a/
443    url = @base_url.merge('../../')
444    assert_kind_of(URI::HTTP, url)
445    assert_equal('http://a/', url.to_s)
446    url = @base_url.route_to('http://a/')
447    assert_kind_of(URI::Generic, url)
448    assert_equal('../../', url.to_s)
449
450#  http://a/b/c/d;p?q
451#        ../../g       =  http://a/g
452    url = @base_url.merge('../../g')
453    assert_kind_of(URI::HTTP, url)
454    assert_equal('http://a/g', url.to_s)
455    url = @base_url.route_to('http://a/g')
456    assert_kind_of(URI::Generic, url)
457    assert_equal('../../g', url.to_s)
458
459#  http://a/b/c/d;p?q
460#        <>            =  (current document)
461    url = @base_url.merge('')
462    assert_kind_of(URI::HTTP, url)
463    assert_equal('http://a/b/c/d;p?q', url.to_s)
464    url = @base_url.route_to('http://a/b/c/d;p?q')
465    assert_kind_of(URI::Generic, url)
466    assert_equal('', url.to_s)
467
468#  http://a/b/c/d;p?q
469#        /./g          =  http://a/g
470    url = @base_url.merge('/./g')
471    assert_kind_of(URI::HTTP, url)
472    assert_equal('http://a/g', url.to_s)
473#    url = @base_url.route_to('http://a/./g')
474#    assert_kind_of(URI::Generic, url)
475#    assert_equal('/./g', url.to_s)
476
477#  http://a/b/c/d;p?q
478#        /../g         =  http://a/g
479    url = @base_url.merge('/../g')
480    assert_kind_of(URI::HTTP, url)
481    assert_equal('http://a/g', url.to_s)
482#    url = @base_url.route_to('http://a/../g')
483#    assert_kind_of(URI::Generic, url)
484#    assert_equal('/../g', url.to_s)
485
486#  http://a/b/c/d;p?q
487#        g.            =  http://a/b/c/g.
488    url = @base_url.merge('g.')
489    assert_kind_of(URI::HTTP, url)
490    assert_equal('http://a/b/c/g.', url.to_s)
491    url = @base_url.route_to('http://a/b/c/g.')
492    assert_kind_of(URI::Generic, url)
493    assert_equal('g.', url.to_s)
494
495#  http://a/b/c/d;p?q
496#        .g            =  http://a/b/c/.g
497    url = @base_url.merge('.g')
498    assert_kind_of(URI::HTTP, url)
499    assert_equal('http://a/b/c/.g', url.to_s)
500    url = @base_url.route_to('http://a/b/c/.g')
501    assert_kind_of(URI::Generic, url)
502    assert_equal('.g', url.to_s)
503
504#  http://a/b/c/d;p?q
505#        g..           =  http://a/b/c/g..
506    url = @base_url.merge('g..')
507    assert_kind_of(URI::HTTP, url)
508    assert_equal('http://a/b/c/g..', url.to_s)
509    url = @base_url.route_to('http://a/b/c/g..')
510    assert_kind_of(URI::Generic, url)
511    assert_equal('g..', url.to_s)
512
513#  http://a/b/c/d;p?q
514#        ..g           =  http://a/b/c/..g
515    url = @base_url.merge('..g')
516    assert_kind_of(URI::HTTP, url)
517    assert_equal('http://a/b/c/..g', url.to_s)
518    url = @base_url.route_to('http://a/b/c/..g')
519    assert_kind_of(URI::Generic, url)
520    assert_equal('..g', url.to_s)
521
522#  http://a/b/c/d;p?q
523#        ../../../g    =  http://a/g
524    url = @base_url.merge('../../../g')
525    assert_kind_of(URI::HTTP, url)
526    assert_equal('http://a/g', url.to_s)
527    url = @base_url.route_to('http://a/g')
528    assert_kind_of(URI::Generic, url)
529    assert('../../../g' != url.to_s)  # ok? yes, it confuses you
530    assert_equal('../../g', url.to_s) # and it is clearly
531
532#  http://a/b/c/d;p?q
533#        ../../../../g =  http://a/g
534    url = @base_url.merge('../../../../g')
535    assert_kind_of(URI::HTTP, url)
536    assert_equal('http://a/g', url.to_s)
537    url = @base_url.route_to('http://a/g')
538    assert_kind_of(URI::Generic, url)
539    assert('../../../../g' != url.to_s) # ok? yes, it confuses you
540    assert_equal('../../g', url.to_s)   # and it is clearly
541
542#  http://a/b/c/d;p?q
543#        ./../g        =  http://a/b/g
544    url = @base_url.merge('./../g')
545    assert_kind_of(URI::HTTP, url)
546    assert_equal('http://a/b/g', url.to_s)
547    url = @base_url.route_to('http://a/b/g')
548    assert_kind_of(URI::Generic, url)
549    assert('./../g' != url.to_s) # ok
550    assert_equal('../g', url.to_s)
551
552#  http://a/b/c/d;p?q
553#        ./g/.         =  http://a/b/c/g/
554    url = @base_url.merge('./g/.')
555    assert_kind_of(URI::HTTP, url)
556    assert_equal('http://a/b/c/g/', url.to_s)
557    url = @base_url.route_to('http://a/b/c/g/')
558    assert_kind_of(URI::Generic, url)
559    assert('./g/.' != url.to_s) # ok
560    assert_equal('g/', url.to_s)
561
562#  http://a/b/c/d;p?q
563#        g/./h         =  http://a/b/c/g/h
564    url = @base_url.merge('g/./h')
565    assert_kind_of(URI::HTTP, url)
566    assert_equal('http://a/b/c/g/h', url.to_s)
567    url = @base_url.route_to('http://a/b/c/g/h')
568    assert_kind_of(URI::Generic, url)
569    assert('g/./h' != url.to_s) # ok
570    assert_equal('g/h', url.to_s)
571
572#  http://a/b/c/d;p?q
573#        g/../h        =  http://a/b/c/h
574    url = @base_url.merge('g/../h')
575    assert_kind_of(URI::HTTP, url)
576    assert_equal('http://a/b/c/h', url.to_s)
577    url = @base_url.route_to('http://a/b/c/h')
578    assert_kind_of(URI::Generic, url)
579    assert('g/../h' != url.to_s) # ok
580    assert_equal('h', url.to_s)
581
582#  http://a/b/c/d;p?q
583#        g;x=1/./y     =  http://a/b/c/g;x=1/y
584    url = @base_url.merge('g;x=1/./y')
585    assert_kind_of(URI::HTTP, url)
586    assert_equal('http://a/b/c/g;x=1/y', url.to_s)
587    url = @base_url.route_to('http://a/b/c/g;x=1/y')
588    assert_kind_of(URI::Generic, url)
589    assert('g;x=1/./y' != url.to_s) # ok
590    assert_equal('g;x=1/y', url.to_s)
591
592#  http://a/b/c/d;p?q
593#        g;x=1/../y    =  http://a/b/c/y
594    url = @base_url.merge('g;x=1/../y')
595    assert_kind_of(URI::HTTP, url)
596    assert_equal('http://a/b/c/y', url.to_s)
597    url = @base_url.route_to('http://a/b/c/y')
598    assert_kind_of(URI::Generic, url)
599    assert('g;x=1/../y' != url.to_s) # ok
600    assert_equal('y', url.to_s)
601
602#  http://a/b/c/d;p?q
603#        g?y/./x       =  http://a/b/c/g?y/./x
604    url = @base_url.merge('g?y/./x')
605    assert_kind_of(URI::HTTP, url)
606    assert_equal('http://a/b/c/g?y/./x', url.to_s)
607    url = @base_url.route_to('http://a/b/c/g?y/./x')
608    assert_kind_of(URI::Generic, url)
609    assert_equal('g?y/./x', url.to_s)
610
611#  http://a/b/c/d;p?q
612#        g?y/../x      =  http://a/b/c/g?y/../x
613    url = @base_url.merge('g?y/../x')
614    assert_kind_of(URI::HTTP, url)
615    assert_equal('http://a/b/c/g?y/../x', url.to_s)
616    url = @base_url.route_to('http://a/b/c/g?y/../x')
617    assert_kind_of(URI::Generic, url)
618    assert_equal('g?y/../x', url.to_s)
619
620#  http://a/b/c/d;p?q
621#        g#s/./x       =  http://a/b/c/g#s/./x
622    url = @base_url.merge('g#s/./x')
623    assert_kind_of(URI::HTTP, url)
624    assert_equal('http://a/b/c/g#s/./x', url.to_s)
625    url = @base_url.route_to('http://a/b/c/g#s/./x')
626    assert_kind_of(URI::Generic, url)
627    assert_equal('g#s/./x', url.to_s)
628
629#  http://a/b/c/d;p?q
630#        g#s/../x      =  http://a/b/c/g#s/../x
631    url = @base_url.merge('g#s/../x')
632    assert_kind_of(URI::HTTP, url)
633    assert_equal('http://a/b/c/g#s/../x', url.to_s)
634    url = @base_url.route_to('http://a/b/c/g#s/../x')
635    assert_kind_of(URI::Generic, url)
636    assert_equal('g#s/../x', url.to_s)
637
638#  http://a/b/c/d;p?q
639#        http:g        =  http:g           ; for validating parsers
640#                      |  http://a/b/c/g   ; for backwards compatibility
641    url = @base_url.merge('http:g')
642    assert_kind_of(URI::HTTP, url)
643    assert_equal('http:g', url.to_s)
644    url = @base_url.route_to('http:g')
645    assert_kind_of(URI::Generic, url)
646    assert_equal('http:g', url.to_s)
647  end
648
649  def test_join
650    assert_equal(URI.parse('http://foo/bar'), URI.join('http://foo/bar'))
651    assert_equal(URI.parse('http://foo/bar'), URI.join('http://foo', 'bar'))
652    assert_equal(URI.parse('http://foo/bar/'), URI.join('http://foo', 'bar/'))
653
654    assert_equal(URI.parse('http://foo/baz'), URI.join('http://foo', 'bar', 'baz'))
655    assert_equal(URI.parse('http://foo/baz'), URI.join('http://foo', 'bar', '/baz'))
656    assert_equal(URI.parse('http://foo/baz/'), URI.join('http://foo', 'bar', '/baz/'))
657    assert_equal(URI.parse('http://foo/bar/baz'), URI.join('http://foo', 'bar/', 'baz'))
658    assert_equal(URI.parse('http://foo/hoge'), URI.join('http://foo', 'bar', 'baz', 'hoge'))
659
660    assert_equal(URI.parse('http://foo/bar/baz'), URI.join('http://foo', 'bar/baz'))
661    assert_equal(URI.parse('http://foo/bar/hoge'), URI.join('http://foo', 'bar/baz', 'hoge'))
662    assert_equal(URI.parse('http://foo/bar/baz/hoge'), URI.join('http://foo', 'bar/baz/', 'hoge'))
663    assert_equal(URI.parse('http://foo/hoge'), URI.join('http://foo', 'bar/baz', '/hoge'))
664    assert_equal(URI.parse('http://foo/bar/hoge'), URI.join('http://foo', 'bar/baz', 'hoge'))
665    assert_equal(URI.parse('http://foo/bar/baz/hoge'), URI.join('http://foo', 'bar/baz/', 'hoge'))
666    assert_equal(URI.parse('http://foo/hoge'), URI.join('http://foo', 'bar/baz', '/hoge'))
667  end
668
669  # ruby-dev:16728
670  def test_set_component
671    uri = URI.parse('http://foo:bar@baz')
672    assert_equal('oof', uri.user = 'oof')
673    assert_equal('http://oof:bar@baz', uri.to_s)
674    assert_equal('rab', uri.password = 'rab')
675    assert_equal('http://oof:rab@baz', uri.to_s)
676    assert_equal('foo', uri.userinfo = 'foo')
677    assert_equal('http://foo:rab@baz', uri.to_s)
678    assert_equal(['foo', 'bar'], uri.userinfo = ['foo', 'bar'])
679    assert_equal('http://foo:bar@baz', uri.to_s)
680    assert_equal(['foo'], uri.userinfo = ['foo'])
681    assert_equal('http://foo:bar@baz', uri.to_s)
682    assert_equal('zab', uri.host = 'zab')
683    assert_equal('http://foo:bar@zab', uri.to_s)
684    assert_equal(8080, uri.port = 8080)
685    assert_equal('http://foo:bar@zab:8080', uri.to_s)
686    assert_equal('/', uri.path = '/')
687    assert_equal('http://foo:bar@zab:8080/', uri.to_s)
688    assert_equal('a=1', uri.query = 'a=1')
689    assert_equal('http://foo:bar@zab:8080/?a=1', uri.to_s)
690    assert_equal('b123', uri.fragment = 'b123')
691    assert_equal('http://foo:bar@zab:8080/?a=1#b123', uri.to_s)
692
693    uri = URI.parse('http://example.com')
694    assert_raise(URI::InvalidURIError) { uri.password = 'bar' }
695    assert_raise(URI::InvalidComponentError) { uri.query = "foo\nbar" }
696    uri.userinfo = 'foo:bar'
697    assert_equal('http://foo:bar@example.com', uri.to_s)
698    assert_raise(URI::InvalidURIError) { uri.registry = 'bar' }
699    assert_raise(URI::InvalidURIError) { uri.opaque = 'bar' }
700
701    uri = URI.parse('mailto:foo@example.com')
702    assert_raise(URI::InvalidURIError) { uri.user = 'bar' }
703    assert_raise(URI::InvalidURIError) { uri.password = 'bar' }
704    assert_raise(URI::InvalidURIError) { uri.userinfo = ['bar', 'baz'] }
705    assert_raise(URI::InvalidURIError) { uri.host = 'bar' }
706    assert_raise(URI::InvalidURIError) { uri.port = 'bar' }
707    assert_raise(URI::InvalidURIError) { uri.path = 'bar' }
708    assert_raise(URI::InvalidURIError) { uri.query = 'bar' }
709  end
710
711  def test_set_scheme
712    uri = URI.parse 'HTTP://example'
713
714    assert_equal 'http://example', uri.to_s
715  end
716
717  def test_ipv6
718    assert_equal("[::1]", URI("http://[::1]/bar/baz").host)
719    assert_equal("::1", URI("http://[::1]/bar/baz").hostname)
720
721    u = URI("http://foo/bar")
722    assert_equal("http://foo/bar", u.to_s)
723    u.hostname = "::1"
724    assert_equal("http://[::1]/bar", u.to_s)
725  end
726
727  def test_build
728    URI::Generic.build(['http', nil, 'example.com', 80, nil, '/foo', nil, nil, nil])
729  end
730
731  def test_build2
732    URI::Generic.build2(path: "/foo bar/baz")
733    URI::Generic.build2(['http', nil, 'example.com', 80, nil, '/foo bar' , nil, nil, nil])
734  end
735
736  # 192.0.2.0/24 is TEST-NET.  [RFC3330]
737
738  def test_find_proxy
739    assert_raise(URI::BadURIError){ URI("foo").find_proxy }
740    with_env({}) {
741      assert_nil(URI("http://192.0.2.1/").find_proxy)
742      assert_nil(URI("ftp://192.0.2.1/").find_proxy)
743    }
744    with_env('http_proxy'=>'http://127.0.0.1:8080') {
745      assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
746      assert_nil(URI("ftp://192.0.2.1/").find_proxy)
747    }
748    with_env('ftp_proxy'=>'http://127.0.0.1:8080') {
749      assert_nil(URI("http://192.0.2.1/").find_proxy)
750      assert_equal(URI('http://127.0.0.1:8080'), URI("ftp://192.0.2.1/").find_proxy)
751    }
752    with_env('REQUEST_METHOD'=>'GET') {
753      assert_nil(URI("http://192.0.2.1/").find_proxy)
754    }
755    with_env('CGI_HTTP_PROXY'=>'http://127.0.0.1:8080', 'REQUEST_METHOD'=>'GET') {
756      assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
757    }
758    with_env('http_proxy'=>'http://127.0.0.1:8080', 'no_proxy'=>'192.0.2.2') {
759      assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
760      assert_nil(URI("http://192.0.2.2/").find_proxy)
761    }
762    with_env('http_proxy'=>'') {
763      assert_nil(URI("http://192.0.2.1/").find_proxy)
764      assert_nil(URI("ftp://192.0.2.1/").find_proxy)
765    }
766    with_env('ftp_proxy'=>'') {
767      assert_nil(URI("http://192.0.2.1/").find_proxy)
768      assert_nil(URI("ftp://192.0.2.1/").find_proxy)
769    }
770  end
771
772  def test_find_proxy_case_sensitive_env
773    with_env('http_proxy'=>'http://127.0.0.1:8080', 'REQUEST_METHOD'=>'GET') {
774      assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
775    }
776    with_env('HTTP_PROXY'=>'http://127.0.0.1:8081', 'REQUEST_METHOD'=>'GET') {
777      assert_nil(nil, URI("http://192.0.2.1/").find_proxy)
778    }
779    with_env('http_proxy'=>'http://127.0.0.1:8080', 'HTTP_PROXY'=>'http://127.0.0.1:8081', 'REQUEST_METHOD'=>'GET') {
780      assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
781    }
782  end unless RUBY_PLATFORM =~ /mswin|mingw/
783
784  def with_env(h)
785    ['http', 'https', 'ftp'].each do |scheme|
786      name = "#{scheme}_proxy"
787      h[name] ||= nil
788      h["CGI_#{name.upcase}"] ||= nil
789    end
790    begin
791      old = {}
792      h.each_key {|k| old[k] = ENV[k] }
793      h.each {|k, v| ENV[k] = v }
794      yield
795    ensure
796      h.each_key {|k| ENV[k] = old[k] }
797    end
798  end
799
800end
801