http-cookie 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,988 +0,0 @@
1
- require File.expand_path('helper', File.dirname(__FILE__))
2
- require 'tmpdir'
3
-
4
- module TestHTTPCookieJar
5
- class TestAutoloading < Test::Unit::TestCase
6
- def test_nonexistent_store
7
- assert_raises(NameError) {
8
- HTTP::CookieJar::NonexistentStore
9
- }
10
- end
11
-
12
- def test_erroneous_store
13
- Dir.mktmpdir { |dir|
14
- Dir.mkdir(File.join(dir, 'http'))
15
- Dir.mkdir(File.join(dir, 'http', 'cookie_jar'))
16
- rb = File.join(dir, 'http', 'cookie_jar', 'erroneous_store.rb')
17
- File.open(rb, 'w').close
18
- $LOAD_PATH.unshift(dir)
19
-
20
- assert_raises(NameError) {
21
- HTTP::CookieJar::ErroneousStore
22
- }
23
- assert($LOADED_FEATURES.any? { |file| FileTest.identical?(file, rb) })
24
- }
25
- end
26
-
27
- def test_nonexistent_saver
28
- assert_raises(NameError) {
29
- HTTP::CookieJar::NonexistentSaver
30
- }
31
- end
32
-
33
- def test_erroneous_saver
34
- Dir.mktmpdir { |dir|
35
- Dir.mkdir(File.join(dir, 'http'))
36
- Dir.mkdir(File.join(dir, 'http', 'cookie_jar'))
37
- rb = File.join(dir, 'http', 'cookie_jar', 'erroneous_saver.rb')
38
- File.open(rb, 'w').close
39
- $LOAD_PATH.unshift(dir)
40
-
41
- assert_raises(NameError) {
42
- HTTP::CookieJar::ErroneousSaver
43
- }
44
- assert($LOADED_FEATURES.any? { |file| FileTest.identical?(file, rb) })
45
- }
46
- end
47
- end
48
-
49
- module CommonTests
50
- def setup(options = nil, options2 = nil)
51
- default_options = {
52
- :store => :hash,
53
- :gc_threshold => 1500, # increased by 10 for shorter test time
54
- }
55
- new_options = default_options.merge(options || {})
56
- new_options2 = new_options.merge(options2 || {})
57
- @store_type = new_options[:store]
58
- @gc_threshold = new_options[:gc_threshold]
59
- @jar = HTTP::CookieJar.new(new_options)
60
- @jar2 = HTTP::CookieJar.new(new_options2)
61
- end
62
-
63
- #def hash_store?
64
- # @store_type == :hash
65
- #end
66
-
67
- def mozilla_store?
68
- @store_type == :mozilla
69
- end
70
-
71
- def cookie_values(options = {})
72
- {
73
- :name => 'Foo',
74
- :value => 'Bar',
75
- :path => '/',
76
- :expires => Time.at(Time.now.to_i + 10 * 86400), # to_i is important here
77
- :for_domain => true,
78
- :domain => 'rubyforge.org',
79
- :origin => 'http://rubyforge.org/'
80
- }.merge(options)
81
- end
82
-
83
- def test_empty?
84
- assert_equal true, @jar.empty?
85
- cookie = HTTP::Cookie.new(cookie_values)
86
- @jar.add(cookie)
87
- assert_equal false, @jar.empty?
88
- assert_equal false, @jar.empty?('http://rubyforge.org/')
89
- assert_equal true, @jar.empty?('http://example.local/')
90
- end
91
-
92
- def test_two_cookies_same_domain_and_name_different_paths
93
- url = URI 'http://rubyforge.org/'
94
-
95
- cookie = HTTP::Cookie.new(cookie_values)
96
- @jar.add(cookie)
97
- @jar.add(HTTP::Cookie.new(cookie_values(:path => '/onetwo')))
98
-
99
- assert_equal(1, @jar.cookies(url).length)
100
- assert_equal 2, @jar.cookies(URI('http://rubyforge.org/onetwo')).length
101
- end
102
-
103
- def test_domain_case
104
- url = URI 'http://rubyforge.org/'
105
-
106
- # Add one cookie with an expiration date in the future
107
- cookie = HTTP::Cookie.new(cookie_values)
108
- @jar.add(cookie)
109
- assert_equal(1, @jar.cookies(url).length)
110
-
111
- @jar.add(HTTP::Cookie.new(cookie_values(:domain => 'RuByForge.Org', :name => 'aaron')))
112
-
113
- assert_equal(2, @jar.cookies(url).length)
114
-
115
- url2 = URI 'http://RuByFoRgE.oRg/'
116
- assert_equal(2, @jar.cookies(url2).length)
117
- end
118
-
119
- def test_host_only
120
- url = URI.parse('http://rubyforge.org/')
121
-
122
- @jar.add(HTTP::Cookie.new(
123
- cookie_values(:domain => 'rubyforge.org', :for_domain => false)))
124
-
125
- assert_equal(1, @jar.cookies(url).length)
126
-
127
- assert_equal(1, @jar.cookies(URI('http://RubyForge.org/')).length)
128
-
129
- assert_equal(1, @jar.cookies(URI('https://RubyForge.org/')).length)
130
-
131
- assert_equal(0, @jar.cookies(URI('http://www.rubyforge.org/')).length)
132
- end
133
-
134
- def test_host_only_with_unqualified_hostname
135
- @jar.add(HTTP::Cookie.new(cookie_values(
136
- :origin => 'http://localhost/', :domain => 'localhost', :for_domain => false)))
137
-
138
- assert_equal(1, @jar.cookies(URI('http://localhost/')).length)
139
-
140
- assert_equal(1, @jar.cookies(URI('http://Localhost/')).length)
141
-
142
- assert_equal(1, @jar.cookies(URI('https://Localhost/')).length)
143
- end
144
-
145
- def test_empty_value
146
- url = URI 'http://rubyforge.org/'
147
- values = cookie_values(:value => "")
148
-
149
- # Add one cookie with an expiration date in the future
150
- cookie = HTTP::Cookie.new(values)
151
- @jar.add(cookie)
152
- assert_equal(1, @jar.cookies(url).length)
153
-
154
- @jar.add HTTP::Cookie.new(values.merge(:domain => 'RuByForge.Org',
155
- :name => 'aaron'))
156
-
157
- assert_equal(2, @jar.cookies(url).length)
158
-
159
- url2 = URI 'http://RuByFoRgE.oRg/'
160
- assert_equal(2, @jar.cookies(url2).length)
161
- end
162
-
163
- def test_add_future_cookies
164
- url = URI 'http://rubyforge.org/'
165
-
166
- # Add one cookie with an expiration date in the future
167
- cookie = HTTP::Cookie.new(cookie_values)
168
- @jar.add(cookie)
169
- assert_equal(1, @jar.cookies(url).length)
170
-
171
- # Add the same cookie, and we should still only have one
172
- @jar.add(HTTP::Cookie.new(cookie_values))
173
- assert_equal(1, @jar.cookies(url).length)
174
-
175
- # Make sure we can get the cookie from different paths
176
- assert_equal(1, @jar.cookies(URI('http://rubyforge.org/login')).length)
177
-
178
- # Make sure we can't get the cookie from different domains
179
- assert_equal(0, @jar.cookies(URI('http://google.com/')).length)
180
- end
181
-
182
- def test_add_multiple_cookies
183
- url = URI 'http://rubyforge.org/'
184
-
185
- # Add one cookie with an expiration date in the future
186
- cookie = HTTP::Cookie.new(cookie_values)
187
- @jar.add(cookie)
188
- assert_equal(1, @jar.cookies(url).length)
189
-
190
- # Add the same cookie, and we should still only have one
191
- @jar.add(HTTP::Cookie.new(cookie_values(:name => 'Baz')))
192
- assert_equal(2, @jar.cookies(url).length)
193
-
194
- # Make sure we can get the cookie from different paths
195
- assert_equal(2, @jar.cookies(URI('http://rubyforge.org/login')).length)
196
-
197
- # Make sure we can't get the cookie from different domains
198
- assert_equal(0, @jar.cookies(URI('http://google.com/')).length)
199
- end
200
-
201
- def test_add_multiple_cookies_with_the_same_name
202
- now = Time.now
203
-
204
- cookies = [
205
- { :value => 'a', :path => '/', },
206
- { :value => 'b', :path => '/abc/def/', :created_at => now - 1 },
207
- { :value => 'c', :path => '/abc/def/', :domain => 'www.rubyforge.org', :origin => 'http://www.rubyforge.org/abc/def/', :created_at => now },
208
- { :value => 'd', :path => '/abc/' },
209
- ].map { |attrs|
210
- HTTP::Cookie.new(cookie_values(attrs))
211
- }
212
-
213
- url = URI 'http://www.rubyforge.org/abc/def/ghi'
214
-
215
- cookies.permutation(cookies.size) { |shuffled|
216
- @jar.clear
217
- shuffled.each { |cookie| @jar.add(cookie) }
218
- assert_equal %w[b c d a], @jar.cookies(url).map { |cookie| cookie.value }
219
- }
220
- end
221
-
222
- def test_fall_back_rules_for_local_domains
223
- url = URI 'http://www.example.local'
224
-
225
- sld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.example.local', :origin => url))
226
- @jar.add(sld_cookie)
227
-
228
- assert_equal(1, @jar.cookies(url).length)
229
- end
230
-
231
- def test_add_makes_exception_for_localhost
232
- url = URI 'http://localhost'
233
-
234
- tld_cookie = HTTP::Cookie.new(cookie_values(:domain => 'localhost', :origin => url))
235
- @jar.add(tld_cookie)
236
-
237
- assert_equal(1, @jar.cookies(url).length)
238
- end
239
-
240
- def test_add_cookie_for_the_parent_domain
241
- url = URI 'http://x.foo.com'
242
-
243
- cookie = HTTP::Cookie.new(cookie_values(:domain => '.foo.com', :origin => url))
244
- @jar.add(cookie)
245
-
246
- assert_equal(1, @jar.cookies(url).length)
247
- end
248
-
249
- def test_add_rejects_cookies_with_unknown_domain_or_path
250
- cookie = HTTP::Cookie.new(cookie_values.reject { |k,v| [:origin, :domain].include?(k) })
251
- assert_raises(ArgumentError) {
252
- @jar.add(cookie)
253
- }
254
-
255
- cookie = HTTP::Cookie.new(cookie_values.reject { |k,v| [:origin, :path].include?(k) })
256
- assert_raises(ArgumentError) {
257
- @jar.add(cookie)
258
- }
259
- end
260
-
261
- def test_add_does_not_reject_cookies_from_a_nested_subdomain
262
- url = URI 'http://y.x.foo.com'
263
-
264
- cookie = HTTP::Cookie.new(cookie_values(:domain => '.foo.com', :origin => url))
265
- @jar.add(cookie)
266
-
267
- assert_equal(1, @jar.cookies(url).length)
268
- end
269
-
270
- def test_cookie_without_leading_dot_does_not_cause_substring_match
271
- url = URI 'http://arubyforge.org/'
272
-
273
- cookie = HTTP::Cookie.new(cookie_values(:domain => 'rubyforge.org'))
274
- @jar.add(cookie)
275
-
276
- assert_equal(0, @jar.cookies(url).length)
277
- end
278
-
279
- def test_cookie_without_leading_dot_matches_subdomains
280
- url = URI 'http://admin.rubyforge.org/'
281
-
282
- cookie = HTTP::Cookie.new(cookie_values(:domain => 'rubyforge.org', :origin => url))
283
- @jar.add(cookie)
284
-
285
- assert_equal(1, @jar.cookies(url).length)
286
- end
287
-
288
- def test_cookies_with_leading_dot_match_subdomains
289
- url = URI 'http://admin.rubyforge.org/'
290
-
291
- @jar.add(HTTP::Cookie.new(cookie_values(:domain => '.rubyforge.org', :origin => url)))
292
-
293
- assert_equal(1, @jar.cookies(url).length)
294
- end
295
-
296
- def test_cookies_with_leading_dot_match_parent_domains
297
- url = URI 'http://rubyforge.org/'
298
-
299
- @jar.add(HTTP::Cookie.new(cookie_values(:domain => '.rubyforge.org', :origin => url)))
300
-
301
- assert_equal(1, @jar.cookies(url).length)
302
- end
303
-
304
- def test_cookies_with_leading_dot_match_parent_domains_exactly
305
- url = URI 'http://arubyforge.org/'
306
-
307
- @jar.add(HTTP::Cookie.new(cookie_values(:domain => '.rubyforge.org')))
308
-
309
- assert_equal(0, @jar.cookies(url).length)
310
- end
311
-
312
- def test_cookie_for_ipv4_address_matches_the_exact_ipaddress
313
- url = URI 'http://192.168.0.1/'
314
-
315
- cookie = HTTP::Cookie.new(cookie_values(:domain => '192.168.0.1', :origin => url))
316
- @jar.add(cookie)
317
-
318
- assert_equal(1, @jar.cookies(url).length)
319
- end
320
-
321
- def test_cookie_for_ipv6_address_matches_the_exact_ipaddress
322
- url = URI 'http://[fe80::0123:4567:89ab:cdef]/'
323
-
324
- cookie = HTTP::Cookie.new(cookie_values(:domain => '[fe80::0123:4567:89ab:cdef]', :origin => url))
325
- @jar.add(cookie)
326
-
327
- assert_equal(1, @jar.cookies(url).length)
328
- end
329
-
330
- def test_cookies_dot
331
- url = URI 'http://www.host.example/'
332
-
333
- @jar.add(HTTP::Cookie.new(cookie_values(:domain => 'www.host.example', :origin => url)))
334
-
335
- url = URI 'http://wwwxhost.example/'
336
- assert_equal(0, @jar.cookies(url).length)
337
- end
338
-
339
- def test_cookies_no_host
340
- url = URI 'file:///path/'
341
-
342
- @jar.add(HTTP::Cookie.new(cookie_values(:origin => url)))
343
-
344
- assert_equal(0, @jar.cookies(url).length)
345
- end
346
-
347
- def test_clear
348
- url = URI 'http://rubyforge.org/'
349
-
350
- # Add one cookie with an expiration date in the future
351
- cookie = HTTP::Cookie.new(cookie_values(:origin => url))
352
- @jar.add(cookie)
353
- @jar.add(HTTP::Cookie.new(cookie_values(:name => 'Baz', :origin => url)))
354
- assert_equal(2, @jar.cookies(url).length)
355
-
356
- @jar.clear
357
-
358
- assert_equal(0, @jar.cookies(url).length)
359
- end
360
-
361
- def test_save_cookies_yaml
362
- url = URI 'http://rubyforge.org/'
363
-
364
- # Add one cookie with an expiration date in the future
365
- cookie = HTTP::Cookie.new(cookie_values(:origin => url))
366
- s_cookie = HTTP::Cookie.new(cookie_values(:name => 'Bar',
367
- :expires => nil,
368
- :origin => url))
369
-
370
- @jar.add(cookie)
371
- @jar.add(s_cookie)
372
- @jar.add(HTTP::Cookie.new(cookie_values(:name => 'Baz', :for_domain => false, :origin => url)))
373
-
374
- assert_equal(3, @jar.cookies(url).length)
375
-
376
- Dir.mktmpdir do |dir|
377
- value = @jar.save(File.join(dir, "cookies.yml"))
378
- assert_same @jar, value
379
-
380
- @jar2.load(File.join(dir, "cookies.yml"))
381
- cookies = @jar2.cookies(url).sort_by { |cookie| cookie.name }
382
- assert_equal(2, cookies.length)
383
- assert_equal('Baz', cookies[0].name)
384
- assert_equal(false, cookies[0].for_domain)
385
- assert_equal('Foo', cookies[1].name)
386
- assert_equal(true, cookies[1].for_domain)
387
- end
388
-
389
- assert_equal(3, @jar.cookies(url).length)
390
- end
391
-
392
- def test_save_load_signature
393
- Dir.mktmpdir { |dir|
394
- filename = File.join(dir, "cookies.yml")
395
-
396
- @jar.save(filename, :format => :cookiestxt, :session => true)
397
- @jar.save(filename, :format => :cookiestxt, :session => true)
398
- @jar.save(filename, :format => :cookiestxt)
399
- @jar.save(filename, :cookiestxt, :session => true)
400
- @jar.save(filename, :cookiestxt)
401
- @jar.save(filename, HTTP::CookieJar::CookiestxtSaver)
402
- @jar.save(filename, HTTP::CookieJar::CookiestxtSaver.new)
403
- @jar.save(filename, :session => true)
404
- @jar.save(filename)
405
-
406
- assert_raises(ArgumentError) {
407
- @jar.save()
408
- }
409
- assert_raises(ArgumentError) {
410
- @jar.save(filename, :nonexistent)
411
- }
412
- assert_raises(TypeError) {
413
- @jar.save(filename, { :format => :cookiestxt }, { :session => true })
414
- }
415
- assert_raises(ArgumentError) {
416
- @jar.save(filename, :cookiestxt, { :session => true }, { :format => :cookiestxt })
417
- }
418
-
419
- @jar.load(filename, :format => :cookiestxt, :linefeed => "\n")
420
- @jar.load(filename, :format => :cookiestxt, :linefeed => "\n")
421
- @jar.load(filename, :format => :cookiestxt)
422
- @jar.load(filename, HTTP::CookieJar::CookiestxtSaver)
423
- @jar.load(filename, HTTP::CookieJar::CookiestxtSaver.new)
424
- @jar.load(filename, :cookiestxt, :linefeed => "\n")
425
- @jar.load(filename, :cookiestxt)
426
- @jar.load(filename, :linefeed => "\n")
427
- @jar.load(filename)
428
- assert_raises(ArgumentError) {
429
- @jar.load()
430
- }
431
- assert_raises(ArgumentError) {
432
- @jar.load(filename, :nonexistent)
433
- }
434
- assert_raises(TypeError) {
435
- @jar.load(filename, { :format => :cookiestxt }, { :linefeed => "\n" })
436
- }
437
- assert_raises(ArgumentError) {
438
- @jar.load(filename, :cookiestxt, { :linefeed => "\n" }, { :format => :cookiestxt })
439
- }
440
- }
441
- end
442
-
443
- def test_save_session_cookies_yaml
444
- url = URI 'http://rubyforge.org/'
445
-
446
- # Add one cookie with an expiration date in the future
447
- cookie = HTTP::Cookie.new(cookie_values)
448
- s_cookie = HTTP::Cookie.new(cookie_values(:name => 'Bar',
449
- :expires => nil))
450
-
451
- @jar.add(cookie)
452
- @jar.add(s_cookie)
453
- @jar.add(HTTP::Cookie.new(cookie_values(:name => 'Baz')))
454
-
455
- assert_equal(3, @jar.cookies(url).length)
456
-
457
- Dir.mktmpdir do |dir|
458
- @jar.save(File.join(dir, "cookies.yml"), :format => :yaml, :session => true)
459
-
460
- @jar2.load(File.join(dir, "cookies.yml"))
461
- assert_equal(3, @jar2.cookies(url).length)
462
- end
463
-
464
- assert_equal(3, @jar.cookies(url).length)
465
- end
466
-
467
- def test_save_and_read_cookiestxt
468
- url = URI 'http://rubyforge.org/foo/'
469
-
470
- # Add one cookie with an expiration date in the future
471
- cookie = HTTP::Cookie.new(cookie_values)
472
- expires = cookie.expires
473
- s_cookie = HTTP::Cookie.new(cookie_values(:name => 'Bar',
474
- :expires => nil))
475
- cookie2 = HTTP::Cookie.new(cookie_values(:name => 'Baz',
476
- :value => 'Foo#Baz',
477
- :path => '/foo/',
478
- :for_domain => false))
479
- h_cookie = HTTP::Cookie.new(cookie_values(:name => 'Quux',
480
- :value => 'Foo#Quux',
481
- :httponly => true))
482
- ma_cookie = HTTP::Cookie.new(cookie_values(:name => 'Maxage',
483
- :value => 'Foo#Maxage',
484
- :max_age => 15000))
485
- @jar.add(cookie)
486
- @jar.add(s_cookie)
487
- @jar.add(cookie2)
488
- @jar.add(h_cookie)
489
- @jar.add(ma_cookie)
490
-
491
- assert_equal(5, @jar.cookies(url).length)
492
-
493
- Dir.mktmpdir do |dir|
494
- filename = File.join(dir, "cookies.txt")
495
- @jar.save(filename, :cookiestxt)
496
-
497
- content = File.read(filename)
498
-
499
- filename2 = File.join(dir, "cookies2.txt")
500
- open(filename2, 'w') { |w|
501
- w.puts '# HTTP Cookie File'
502
- @jar.save(w, :cookiestxt, :header => nil)
503
- }
504
- assert_equal content, File.read(filename2)
505
-
506
- assert_match(/^\.rubyforge\.org\t.*\tFoo\t/, content)
507
- assert_match(/^rubyforge\.org\t.*\tBaz\t/, content)
508
- assert_match(/^#HttpOnly_\.rubyforge\.org\t/, content)
509
-
510
- @jar2.load(filename, :cookiestxt) # HACK test the format
511
- cookies = @jar2.cookies(url)
512
- assert_equal(4, cookies.length)
513
- cookies.each { |cookie|
514
- case cookie.name
515
- when 'Foo'
516
- assert_equal 'Bar', cookie.value
517
- assert_equal expires, cookie.expires
518
- assert_equal 'rubyforge.org', cookie.domain
519
- assert_equal true, cookie.for_domain
520
- assert_equal '/', cookie.path
521
- assert_equal false, cookie.httponly?
522
- when 'Baz'
523
- assert_equal 'Foo#Baz', cookie.value
524
- assert_equal 'rubyforge.org', cookie.domain
525
- assert_equal false, cookie.for_domain
526
- assert_equal '/foo/', cookie.path
527
- assert_equal false, cookie.httponly?
528
- when 'Quux'
529
- assert_equal 'Foo#Quux', cookie.value
530
- assert_equal expires, cookie.expires
531
- assert_equal 'rubyforge.org', cookie.domain
532
- assert_equal true, cookie.for_domain
533
- assert_equal '/', cookie.path
534
- assert_equal true, cookie.httponly?
535
- when 'Maxage'
536
- assert_equal 'Foo#Maxage', cookie.value
537
- assert_equal nil, cookie.max_age
538
- assert_in_delta ma_cookie.expires, cookie.expires, 1
539
- else
540
- raise
541
- end
542
- }
543
- end
544
-
545
- assert_equal(5, @jar.cookies(url).length)
546
- end
547
-
548
- def test_load_yaml_mechanize
549
- @jar.load(test_file('mechanize.yml'), :yaml)
550
-
551
- assert_equal 4, @jar.to_a.size
552
-
553
- com_nid, com_pref = @jar.cookies('http://www.google.com/')
554
-
555
- assert_equal 'NID', com_nid.name
556
- assert_equal 'Sun, 23 Sep 2063 08:20:15 GMT', com_nid.expires.httpdate
557
- assert_equal 'google.com', com_nid.domain_name.hostname
558
-
559
- assert_equal 'PREF', com_pref.name
560
- assert_equal 'Tue, 24 Mar 2065 08:20:15 GMT', com_pref.expires.httpdate
561
- assert_equal 'google.com', com_pref.domain_name.hostname
562
-
563
- cojp_nid, cojp_pref = @jar.cookies('http://www.google.co.jp/')
564
-
565
- assert_equal 'NID', cojp_nid.name
566
- assert_equal 'Sun, 23 Sep 2063 08:20:16 GMT', cojp_nid.expires.httpdate
567
- assert_equal 'google.co.jp', cojp_nid.domain_name.hostname
568
-
569
- assert_equal 'PREF', cojp_pref.name
570
- assert_equal 'Tue, 24 Mar 2065 08:20:16 GMT', cojp_pref.expires.httpdate
571
- assert_equal 'google.co.jp', cojp_pref.domain_name.hostname
572
- end
573
-
574
- def test_expire_cookies
575
- url = URI 'http://rubyforge.org/'
576
-
577
- # Add one cookie with an expiration date in the future
578
- cookie = HTTP::Cookie.new(cookie_values)
579
- @jar.add(cookie)
580
- assert_equal(1, @jar.cookies(url).length)
581
-
582
- # Add a second cookie
583
- @jar.add(HTTP::Cookie.new(cookie_values(:name => 'Baz')))
584
- assert_equal(2, @jar.cookies(url).length)
585
-
586
- # Make sure we can get the cookie from different paths
587
- assert_equal(2, @jar.cookies(URI('http://rubyforge.org/login')).length)
588
-
589
- # Expire the first cookie
590
- @jar.add(HTTP::Cookie.new(cookie_values(:expires => Time.now - (10 * 86400))))
591
- assert_equal(1, @jar.cookies(url).length)
592
-
593
- # Expire the second cookie
594
- @jar.add(HTTP::Cookie.new(cookie_values( :name => 'Baz', :expires => Time.now - (10 * 86400))))
595
- assert_equal(0, @jar.cookies(url).length)
596
- end
597
-
598
- def test_session_cookies
599
- values = cookie_values(:expires => nil)
600
- url = URI 'http://rubyforge.org/'
601
-
602
- # Add one cookie with an expiration date in the future
603
- cookie = HTTP::Cookie.new(values)
604
- @jar.add(cookie)
605
- assert_equal(1, @jar.cookies(url).length)
606
-
607
- # Add a second cookie
608
- @jar.add(HTTP::Cookie.new(values.merge(:name => 'Baz')))
609
- assert_equal(2, @jar.cookies(url).length)
610
-
611
- # Make sure we can get the cookie from different paths
612
- assert_equal(2, @jar.cookies(URI('http://rubyforge.org/login')).length)
613
-
614
- # Expire the first cookie
615
- @jar.add(HTTP::Cookie.new(values.merge(:expires => Time.now - (10 * 86400))))
616
- assert_equal(1, @jar.cookies(url).length)
617
-
618
- # Expire the second cookie
619
- @jar.add(HTTP::Cookie.new(values.merge(:name => 'Baz', :expires => Time.now - (10 * 86400))))
620
- assert_equal(0, @jar.cookies(url).length)
621
-
622
- # When given a URI with a blank path, CookieJar#cookies should return
623
- # cookies with the path '/':
624
- url = URI 'http://rubyforge.org'
625
- assert_equal '', url.path
626
- assert_equal(0, @jar.cookies(url).length)
627
- # Now add a cookie with the path set to '/':
628
- @jar.add(HTTP::Cookie.new(values.merge(:name => 'has_root_path', :path => '/')))
629
- assert_equal(1, @jar.cookies(url).length)
630
- end
631
-
632
- def test_paths
633
- url = URI 'http://rubyforge.org/login'
634
- values = cookie_values(:path => "/login", :expires => nil, :origin => url)
635
-
636
- # Add one cookie with an expiration date in the future
637
- cookie = HTTP::Cookie.new(values)
638
- @jar.add(cookie)
639
- assert_equal(1, @jar.cookies(url).length)
640
-
641
- # Add a second cookie
642
- @jar.add(HTTP::Cookie.new(values.merge( :name => 'Baz' )))
643
- assert_equal(2, @jar.cookies(url).length)
644
-
645
- # Make sure we don't get the cookie in a different path
646
- assert_equal(0, @jar.cookies(URI('http://rubyforge.org/hello')).length)
647
- assert_equal(0, @jar.cookies(URI('http://rubyforge.org/')).length)
648
-
649
- # Expire the first cookie
650
- @jar.add(HTTP::Cookie.new(values.merge( :expires => Time.now - (10 * 86400))))
651
- assert_equal(1, @jar.cookies(url).length)
652
-
653
- # Expire the second cookie
654
- @jar.add(HTTP::Cookie.new(values.merge( :name => 'Baz',
655
- :expires => Time.now - (10 * 86400))))
656
- assert_equal(0, @jar.cookies(url).length)
657
- end
658
-
659
- def test_ssl_cookies
660
- # thanks to michal "ocher" ochman for reporting the bug responsible for this test.
661
- values = cookie_values(:expires => nil)
662
- values_ssl = values.merge(:name => 'Baz', :domain => "#{values[:domain]}:443")
663
- url = URI 'https://rubyforge.org/login'
664
-
665
- cookie = HTTP::Cookie.new(values)
666
- @jar.add(cookie)
667
- assert_equal(1, @jar.cookies(url).length, "did not handle SSL cookie")
668
-
669
- cookie = HTTP::Cookie.new(values_ssl)
670
- @jar.add(cookie)
671
- assert_equal(2, @jar.cookies(url).length, "did not handle SSL cookie with :443")
672
- end
673
-
674
- def test_secure_cookie
675
- nurl = URI 'http://rubyforge.org/login'
676
- surl = URI 'https://rubyforge.org/login'
677
-
678
- nncookie = HTTP::Cookie.new(cookie_values(:name => 'Foo1', :origin => nurl))
679
- sncookie = HTTP::Cookie.new(cookie_values(:name => 'Foo1', :origin => surl))
680
- nscookie = HTTP::Cookie.new(cookie_values(:name => 'Foo2', :secure => true, :origin => nurl))
681
- sscookie = HTTP::Cookie.new(cookie_values(:name => 'Foo2', :secure => true, :origin => surl))
682
-
683
- @jar.add(nncookie)
684
- @jar.add(sncookie)
685
- @jar.add(nscookie)
686
- @jar.add(sscookie)
687
-
688
- assert_equal('Foo1', @jar.cookies(nurl).map { |c| c.name }.sort.join(' ') )
689
- assert_equal('Foo1 Foo2', @jar.cookies(surl).map { |c| c.name }.sort.join(' ') )
690
- end
691
-
692
- def test_delete
693
- cookie1 = HTTP::Cookie.new(cookie_values)
694
- cookie2 = HTTP::Cookie.new(:name => 'Foo', :value => '',
695
- :domain => 'rubyforge.org',
696
- :for_domain => false,
697
- :path => '/')
698
- cookie3 = HTTP::Cookie.new(:name => 'Foo', :value => '',
699
- :domain => 'rubyforge.org',
700
- :for_domain => true,
701
- :path => '/')
702
-
703
- @jar.add(cookie1)
704
- @jar.delete(cookie2)
705
-
706
- if mozilla_store?
707
- assert_equal(1, @jar.to_a.length)
708
- @jar.delete(cookie3)
709
- end
710
-
711
- assert_equal(0, @jar.to_a.length)
712
- end
713
-
714
- def test_accessed_at
715
- orig = HTTP::Cookie.new(cookie_values(:expires => nil))
716
- @jar.add(orig)
717
-
718
- time = orig.accessed_at
719
-
720
- assert_in_delta 1.0, time, Time.now, "accessed_at is initialized to the current time"
721
-
722
- cookie, = @jar.to_a
723
-
724
- assert_equal time, cookie.accessed_at, "accessed_at is not updated by each()"
725
-
726
- cookie, = @jar.cookies("http://rubyforge.org/")
727
-
728
- assert_send [cookie.accessed_at, :>, time], "accessed_at is not updated by each(url)"
729
- end
730
-
731
- def test_max_cookies
732
- slimit = HTTP::Cookie::MAX_COOKIES_TOTAL + @gc_threshold
733
-
734
- limit_per_domain = HTTP::Cookie::MAX_COOKIES_PER_DOMAIN
735
- uri = URI('http://www.example.org/')
736
- date = Time.at(Time.now.to_i + 86400)
737
- (1..(limit_per_domain + 1)).each { |i|
738
- @jar << HTTP::Cookie.new(cookie_values(
739
- :name => 'Foo%d' % i,
740
- :value => 'Bar%d' % i,
741
- :domain => uri.host,
742
- :for_domain => true,
743
- :path => '/dir%d/' % (i / 2),
744
- :origin => uri
745
- )).tap { |cookie|
746
- cookie.created_at = i == 42 ? date - i : date
747
- }
748
- }
749
- assert_equal limit_per_domain + 1, @jar.to_a.size
750
- @jar.cleanup
751
- count = @jar.to_a.size
752
- assert_equal limit_per_domain, count
753
- assert_equal [*1..(limit_per_domain + 1)] - [42], @jar.map { |cookie|
754
- cookie.name[/(\d+)$/].to_i
755
- }.sort
756
-
757
- hlimit = HTTP::Cookie::MAX_COOKIES_TOTAL
758
-
759
- n = hlimit / limit_per_domain * 2
760
-
761
- (1..n).each { |i|
762
- (1..(limit_per_domain + 1)).each { |j|
763
- uri = URI('http://www%d.example.jp/' % i)
764
- @jar << HTTP::Cookie.new(cookie_values(
765
- :name => 'Baz%d' % j,
766
- :value => 'www%d.example.jp' % j,
767
- :domain => uri.host,
768
- :for_domain => true,
769
- :path => '/dir%d/' % (i / 2),
770
- :origin => uri
771
- )).tap { |cookie|
772
- cookie.created_at = i == j ? date - i : date
773
- }
774
- count += 1
775
- }
776
- }
777
-
778
- assert_send [count, :>, slimit]
779
- assert_send [@jar.to_a.size, :<=, slimit]
780
- @jar.cleanup
781
- assert_equal hlimit, @jar.to_a.size
782
- assert_equal false, @jar.any? { |cookie|
783
- cookie.domain == cookie.value
784
- }
785
- end
786
-
787
- def test_parse
788
- set_cookie = [
789
- "name=Akinori; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
790
- "country=Japan; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
791
- "city=Tokyo; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
792
- ].join(', ')
793
-
794
- cookies = @jar.parse(set_cookie, 'http://rubyforge.org/')
795
- assert_equal %w[Akinori Japan Tokyo], cookies.map { |c| c.value }
796
- assert_equal %w[Tokyo Japan Akinori], @jar.to_a.sort_by { |c| c.name }.map { |c| c.value }
797
- end
798
-
799
- def test_parse_with_block
800
- set_cookie = [
801
- "name=Akinori; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
802
- "country=Japan; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
803
- "city=Tokyo; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
804
- ].join(', ')
805
-
806
- cookies = @jar.parse(set_cookie, 'http://rubyforge.org/') { |c| c.name != 'city' }
807
- assert_equal %w[Akinori Japan], cookies.map { |c| c.value }
808
- assert_equal %w[Japan Akinori], @jar.to_a.sort_by { |c| c.name }.map { |c| c.value }
809
- end
810
-
811
- def test_expire_by_each_and_cleanup
812
- uri = URI('http://www.example.org/')
813
-
814
- ts = Time.now.to_f
815
- if ts % 1 > 0.5
816
- sleep 0.5
817
- ts += 0.5
818
- end
819
- expires = Time.at(ts.floor)
820
- time = expires
821
-
822
- if mozilla_store?
823
- # MozillaStore only has the time precision of seconds.
824
- time = expires
825
- expires -= 1
826
- end
827
-
828
- 0.upto(2) { |i|
829
- c = HTTP::Cookie.new('Foo%d' % (3 - i), 'Bar', :expires => expires + i, :origin => uri)
830
- @jar << c
831
- @jar2 << c
832
- }
833
-
834
- assert_equal %w[Foo1 Foo2], @jar.cookies.map(&:name)
835
- assert_equal %w[Foo1 Foo2], @jar2.cookies(uri).map(&:name)
836
-
837
- sleep_until time + 1
838
-
839
- assert_equal %w[Foo1], @jar.cookies.map(&:name)
840
- assert_equal %w[Foo1], @jar2.cookies(uri).map(&:name)
841
-
842
- sleep_until time + 2
843
-
844
- @jar.cleanup
845
- @jar2.cleanup
846
-
847
- assert_send [@jar, :empty?]
848
- assert_send [@jar2, :empty?]
849
- end
850
- end
851
-
852
- class WithHashStore < Test::Unit::TestCase
853
- include CommonTests
854
-
855
- def test_new
856
- jar = HTTP::CookieJar.new(:store => :hash)
857
- assert_instance_of HTTP::CookieJar::HashStore, jar.store
858
-
859
- assert_raises(ArgumentError) {
860
- jar = HTTP::CookieJar.new(:store => :nonexistent)
861
- }
862
-
863
- jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore.new)
864
- assert_instance_of HTTP::CookieJar::HashStore, jar.store
865
-
866
- jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore)
867
- end
868
-
869
- def test_clone
870
- jar = @jar.clone
871
- assert_not_send [
872
- @jar.store,
873
- :equal?,
874
- jar.store
875
- ]
876
- assert_not_send [
877
- @jar.store.instance_variable_get(:@jar),
878
- :equal?,
879
- jar.store.instance_variable_get(:@jar)
880
- ]
881
- assert_equal @jar.cookies, jar.cookies
882
- end
883
- end
884
-
885
- class WithMozillaStore < Test::Unit::TestCase
886
- include CommonTests
887
-
888
- def setup
889
- super(
890
- { :store => :mozilla, :filename => ":memory:" },
891
- { :store => :mozilla, :filename => ":memory:" })
892
- end
893
-
894
- def add_and_delete(jar)
895
- jar.parse("name=Akinori; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
896
- 'http://rubyforge.org/')
897
- jar.parse("country=Japan; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
898
- 'http://rubyforge.org/')
899
- jar.delete(HTTP::Cookie.new("name", :domain => 'rubyforge.org'))
900
- end
901
-
902
- def test_clone
903
- assert_raises(TypeError) {
904
- @jar.clone
905
- }
906
- end
907
-
908
- def test_close
909
- add_and_delete(@jar)
910
-
911
- assert_not_send [@jar.store, :closed?]
912
- @jar.store.close
913
- assert_send [@jar.store, :closed?]
914
- @jar.store.close # should do nothing
915
- assert_send [@jar.store, :closed?]
916
- end
917
-
918
- def test_finalizer
919
- db = nil
920
- loop {
921
- jar = HTTP::CookieJar.new(:store => :mozilla, :filename => ':memory:')
922
- add_and_delete(jar)
923
- db = jar.store.instance_variable_get(:@db)
924
- class << db
925
- alias close_orig close
926
- def close
927
- STDERR.print "[finalizer is called]"
928
- STDERR.flush
929
- close_orig
930
- end
931
- end
932
- break
933
- }
934
- end
935
-
936
- def test_upgrade_mozillastore
937
- Dir.mktmpdir { |dir|
938
- filename = File.join(dir, 'cookies.sqlite')
939
-
940
- sqlite = SQLite3::Database.new(filename)
941
- sqlite.execute(<<-'SQL')
942
- CREATE TABLE moz_cookies (
943
- id INTEGER PRIMARY KEY,
944
- name TEXT,
945
- value TEXT,
946
- host TEXT,
947
- path TEXT,
948
- expiry INTEGER,
949
- isSecure INTEGER,
950
- isHttpOnly INTEGER)
951
- SQL
952
- sqlite.execute(<<-'SQL')
953
- PRAGMA user_version = 1
954
- SQL
955
-
956
- begin
957
- st_insert = sqlite.prepare(<<-'SQL')
958
- INSERT INTO moz_cookies (
959
- id, name, value, host, path, expiry, isSecure, isHttpOnly
960
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
961
- SQL
962
-
963
- st_insert.execute(1, 'name1', 'value1', '.example.co.jp', '/', 2312085765, 0, 0)
964
- st_insert.execute(2, 'name1', 'value2', '.example.co.jp', '/', 2312085765, 0, 0)
965
- st_insert.execute(3, 'name1', 'value3', 'www.example.co.jp', '/', 2312085765, 0, 0)
966
- ensure
967
- st_insert.close if st_insert
968
- end
969
-
970
- sqlite.close
971
- jar = HTTP::CookieJar.new(:store => :mozilla, :filename => filename)
972
-
973
- assert_equal 2, jar.to_a.size
974
- assert_equal 2, jar.cookies('http://www.example.co.jp/').size
975
-
976
- cookie, *rest = jar.cookies('http://host.example.co.jp/')
977
- assert_send [rest, :empty?]
978
- assert_equal 'value2', cookie.value
979
- }
980
- end
981
- end if begin
982
- require 'sqlite3'
983
- true
984
- rescue LoadError
985
- STDERR.puts 'sqlite3 missing?'
986
- false
987
- end
988
- end