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