http-cookie 1.0.0.pre8 → 1.0.0.pre9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +2 -2
- data/lib/http/cookie.rb +58 -21
- data/lib/http/cookie/version.rb +1 -1
- data/lib/http/cookie_jar.rb +18 -18
- data/test/test_http_cookie.rb +84 -16
- data/test/test_http_cookie_jar.rb +1 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53cb4c9e7487abb35fc5566cadc3c2f8afbea819
|
4
|
+
data.tar.gz: dfa1e8393cc3f71df62e55984196046788942c6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e232e6d966c1fb49b9e7e6ab50456b955d4b377962f71d570531aa622200ef94031ec602bddea8d2c475e51b20240c85306ff6dc9b874c27453acacaf0ae9cd
|
7
|
+
data.tar.gz: 188e45b944168d04516707ad503710b938acae9f50a50d61d3351e6e12e936fba53cc0ce26e7ee80b370e18809df95e91160f12ef4c73d760ad4202a8eaa9cb6
|
data/Rakefile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
2
|
require 'rake/testtask'
|
3
3
|
|
4
4
|
Rake::TestTask.new(:test) do |test|
|
5
|
-
test.ruby_opts << '-r./test/simplecov_start.rb' if
|
5
|
+
test.ruby_opts << '-r./test/simplecov_start.rb' if RUBY_VERSION >= '1.9'
|
6
6
|
test.pattern = 'test/**/test_*.rb'
|
7
7
|
test.verbose = true
|
8
8
|
end
|
data/lib/http/cookie.rb
CHANGED
@@ -14,7 +14,14 @@ if RUBY_VERSION < "1.9.3"
|
|
14
14
|
URI(URI(''))
|
15
15
|
rescue
|
16
16
|
def URI(url) # :nodoc:
|
17
|
-
|
17
|
+
case url
|
18
|
+
when URI
|
19
|
+
url
|
20
|
+
when String
|
21
|
+
URI.parse(url)
|
22
|
+
else
|
23
|
+
raise ArgumentError, 'bad argument (expected URI object or URI string)'
|
24
|
+
end
|
18
25
|
end
|
19
26
|
end
|
20
27
|
end
|
@@ -102,7 +109,10 @@ class HTTP::Cookie
|
|
102
109
|
# The origin of the cookie.
|
103
110
|
#
|
104
111
|
# Setting this will initialize the #domain and #path attribute
|
105
|
-
# values if unknown yet.
|
112
|
+
# values if unknown yet. If the cookie already has a domain value
|
113
|
+
# set, it is checked against the origin URL to see if the origin is
|
114
|
+
# allowed to issue a cookie of the domain, and ArgumentError is
|
115
|
+
# raised if the check fails.
|
106
116
|
#
|
107
117
|
# :attr_accessor: origin
|
108
118
|
|
@@ -310,14 +320,9 @@ class HTTP::Cookie
|
|
310
320
|
end
|
311
321
|
}
|
312
322
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
rescue => e
|
317
|
-
logger.warn("Invalid cookie for the origin: #{origin} (#{e})") if logger
|
318
|
-
next
|
319
|
-
end
|
320
|
-
end
|
323
|
+
cookie.origin = origin
|
324
|
+
|
325
|
+
cookie.acceptable? or next
|
321
326
|
|
322
327
|
yield cookie if block_given?
|
323
328
|
|
@@ -363,15 +368,28 @@ class HTTP::Cookie
|
|
363
368
|
|
364
369
|
# See #domain.
|
365
370
|
def domain=(domain)
|
366
|
-
|
371
|
+
case domain
|
372
|
+
when nil
|
373
|
+
@for_domain = false
|
374
|
+
if @origin
|
375
|
+
@domain_name = DomainName.new(@origin.host)
|
376
|
+
@domain = @domain_name.hostname
|
377
|
+
else
|
378
|
+
@domain_name = @domain = nil
|
379
|
+
end
|
380
|
+
return nil
|
381
|
+
when DomainName
|
367
382
|
@domain_name = domain
|
368
383
|
else
|
369
384
|
domain = check_string_type(domain) or
|
370
385
|
raise TypeError, "#{domain.class} is not a String"
|
371
386
|
if domain.start_with?('.')
|
372
|
-
|
387
|
+
for_domain = true
|
373
388
|
domain = domain[1..-1]
|
374
389
|
end
|
390
|
+
if domain.empty?
|
391
|
+
return self.domain = nil
|
392
|
+
end
|
375
393
|
# Do we really need to support this?
|
376
394
|
if domain.match(/\A([^:]+):[0-9]+\z/)
|
377
395
|
domain = $1
|
@@ -379,8 +397,10 @@ class HTTP::Cookie
|
|
379
397
|
@domain_name = DomainName.new(domain)
|
380
398
|
end
|
381
399
|
# RFC 6265 5.3 5.
|
382
|
-
if
|
400
|
+
if domain_name.domain.nil? # a public suffix or IP address
|
383
401
|
@for_domain = false
|
402
|
+
else
|
403
|
+
@for_domain = for_domain unless for_domain.nil?
|
384
404
|
end
|
385
405
|
@domain = @domain_name.hostname
|
386
406
|
end
|
@@ -419,10 +439,10 @@ class HTTP::Cookie
|
|
419
439
|
@origin.nil? or
|
420
440
|
raise ArgumentError, "origin cannot be changed once it is set"
|
421
441
|
origin = URI(origin)
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
442
|
+
if URI::HTTP === origin
|
443
|
+
self.domain ||= origin.host
|
444
|
+
self.path ||= (origin + './').path
|
445
|
+
end
|
426
446
|
@origin = origin
|
427
447
|
end
|
428
448
|
|
@@ -514,22 +534,39 @@ class HTTP::Cookie
|
|
514
534
|
attr_accessor :accessed_at
|
515
535
|
|
516
536
|
# Tests if it is OK to accept this cookie if it is sent from a given
|
517
|
-
# `uri`.
|
537
|
+
# URI/URL, `uri`.
|
518
538
|
def acceptable_from_uri?(uri)
|
519
539
|
uri = URI(uri)
|
520
540
|
return false unless URI::HTTP === uri && uri.host
|
521
541
|
host = DomainName.new(uri.host)
|
522
542
|
|
523
543
|
# RFC 6265 5.3
|
524
|
-
|
525
|
-
|
526
|
-
|
544
|
+
case
|
545
|
+
when host.hostname == @domain
|
546
|
+
true
|
547
|
+
when @for_domain # !host-only-flag
|
527
548
|
host.cookie_domain?(@domain_name)
|
528
549
|
else
|
529
550
|
@domain.nil?
|
530
551
|
end
|
531
552
|
end
|
532
553
|
|
554
|
+
# Tests if it is OK to accept this cookie considering its origin.
|
555
|
+
# If either domain or path is missing, raises ArgumentError. If
|
556
|
+
# origin is missing, returns true.
|
557
|
+
def acceptable?
|
558
|
+
case
|
559
|
+
when @domain.nil?
|
560
|
+
raise ArgumentError, "domain is missing"
|
561
|
+
when @path.nil?
|
562
|
+
raise ArgumentError, "path is missing"
|
563
|
+
when @origin.nil?
|
564
|
+
true
|
565
|
+
else
|
566
|
+
acceptable_from_uri?(@origin)
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
533
570
|
# Tests if it is OK to send this cookie to a given `uri`. A runtime
|
534
571
|
# error is raised if the cookie's domain is unknown.
|
535
572
|
def valid_for_uri?(uri)
|
data/lib/http/cookie/version.rb
CHANGED
data/lib/http/cookie_jar.rb
CHANGED
@@ -45,17 +45,17 @@ class HTTP::CookieJar
|
|
45
45
|
@store = other.instance_eval { @store.dup }
|
46
46
|
end
|
47
47
|
|
48
|
-
# Adds a cookie to the jar
|
49
|
-
#
|
50
|
-
# ArgumentError is raised.
|
48
|
+
# Adds a cookie to the jar if it is acceptable, and returns self in
|
49
|
+
# any case. A given cookie must have domain and path attributes
|
50
|
+
# set, or ArgumentError is raised.
|
51
51
|
#
|
52
52
|
# ### Compatibility Note for Mechanize::Cookie users
|
53
53
|
#
|
54
54
|
# In HTTP::Cookie, each cookie object can store its origin URI
|
55
55
|
# (cf. #origin). While the origin URI of a cookie can be set
|
56
56
|
# manually by #origin=, one is typically given in its generation.
|
57
|
-
# To be more specific, HTTP::Cookie.new
|
58
|
-
#
|
57
|
+
# To be more specific, HTTP::Cookie.new takes an `:origin` option
|
58
|
+
# and HTTP::Cookie.parse takes one via the second argument.
|
59
59
|
#
|
60
60
|
# `HTTP::Cookie.parse`. Compare these:
|
61
61
|
#
|
@@ -64,14 +64,10 @@ class HTTP::CookieJar
|
|
64
64
|
# jar.add!(cookie) # no acceptance check is performed
|
65
65
|
#
|
66
66
|
# # HTTP::Cookie
|
67
|
-
# jar.origin = origin
|
67
|
+
# jar.origin = origin
|
68
68
|
# jar.add(cookie) # acceptance check is performed
|
69
69
|
def add(cookie)
|
70
|
-
|
71
|
-
raise ArgumentError, "a cookie with unknown domain or path cannot be added"
|
72
|
-
end
|
73
|
-
|
74
|
-
@store.add(cookie)
|
70
|
+
@store.add(cookie) if cookie.acceptable?
|
75
71
|
self
|
76
72
|
end
|
77
73
|
alias << add
|
@@ -136,7 +132,11 @@ class HTTP::CookieJar
|
|
136
132
|
yield cookie
|
137
133
|
}
|
138
134
|
else
|
139
|
-
HTTP::Cookie.parse(set_cookie, origin, options
|
135
|
+
HTTP::Cookie.parse(set_cookie, origin, options) { |cookie|
|
136
|
+
add(cookie)
|
137
|
+
}
|
138
|
+
# XXX: ruby 1.8 fails to call super from a proc'ized method
|
139
|
+
# HTTP::Cookie.parse(set_cookie, origin, options, &method(:add)
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
@@ -145,8 +145,8 @@ class HTTP::CookieJar
|
|
145
145
|
# jar.save(filename_or_io, format = :yaml, **options)
|
146
146
|
#
|
147
147
|
# Saves the cookie jar into a file or an IO in the format specified
|
148
|
-
# and
|
149
|
-
# as an IO, or taken as a filename otherwise.
|
148
|
+
# and returns self. If a given object responds to #write it is
|
149
|
+
# taken as an IO, or taken as a filename otherwise.
|
150
150
|
#
|
151
151
|
# Available option keywords are below:
|
152
152
|
#
|
@@ -211,8 +211,8 @@ class HTTP::CookieJar
|
|
211
211
|
# jar.load(filename_or_io, format = :yaml, **options)
|
212
212
|
#
|
213
213
|
# Loads cookies recorded in a file or an IO in the format specified
|
214
|
-
# into the jar and
|
215
|
-
# it is taken as an IO, or taken as a filename otherwise.
|
214
|
+
# into the jar and returns self. If a given object responds to
|
215
|
+
# #read it is taken as an IO, or taken as a filename otherwise.
|
216
216
|
#
|
217
217
|
# Available option keywords are below:
|
218
218
|
#
|
@@ -264,13 +264,13 @@ class HTTP::CookieJar
|
|
264
264
|
self
|
265
265
|
end
|
266
266
|
|
267
|
-
# Clears the cookie jar and
|
267
|
+
# Clears the cookie jar and returns self.
|
268
268
|
def clear
|
269
269
|
@store.clear
|
270
270
|
self
|
271
271
|
end
|
272
272
|
|
273
|
-
# Removes expired cookies and
|
273
|
+
# Removes expired cookies and returns self.
|
274
274
|
def cleanup(session = false)
|
275
275
|
@store.cleanup session
|
276
276
|
self
|
data/test/test_http_cookie.rb
CHANGED
@@ -450,6 +450,9 @@ class TestHTTPCookie < Test::Unit::TestCase
|
|
450
450
|
assert_equal 'key', cookie.name
|
451
451
|
assert_equal 'value', cookie.value
|
452
452
|
assert_equal nil, cookie.expires
|
453
|
+
assert_raises(ArgumentError) {
|
454
|
+
cookie.acceptable?
|
455
|
+
}
|
453
456
|
|
454
457
|
# Minimum unit for the expires attribute is second
|
455
458
|
expires = Time.at((Time.now + 3600).to_i)
|
@@ -458,24 +461,39 @@ class TestHTTPCookie < Test::Unit::TestCase
|
|
458
461
|
assert_equal 'key', cookie.name
|
459
462
|
assert_equal 'value', cookie.value
|
460
463
|
assert_equal expires, cookie.expires
|
464
|
+
assert_raises(ArgumentError) {
|
465
|
+
cookie.acceptable?
|
466
|
+
}
|
461
467
|
|
462
468
|
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup)
|
463
469
|
assert_equal 'key', cookie.name
|
464
470
|
assert_equal 'value', cookie.value
|
465
471
|
assert_equal expires, cookie.expires
|
466
472
|
assert_equal false, cookie.for_domain?
|
473
|
+
assert_raises(ArgumentError) {
|
474
|
+
# domain and path are missing
|
475
|
+
cookie.acceptable?
|
476
|
+
}
|
467
477
|
|
468
478
|
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup, :domain => '.example.com')
|
469
479
|
assert_equal 'key', cookie.name
|
470
480
|
assert_equal 'value', cookie.value
|
471
481
|
assert_equal expires, cookie.expires
|
472
482
|
assert_equal true, cookie.for_domain?
|
483
|
+
assert_raises(ArgumentError) {
|
484
|
+
# path is missing
|
485
|
+
cookie.acceptable?
|
486
|
+
}
|
473
487
|
|
474
488
|
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup, :domain => 'example.com', :for_domain => false)
|
475
489
|
assert_equal 'key', cookie.name
|
476
490
|
assert_equal 'value', cookie.value
|
477
491
|
assert_equal expires, cookie.expires
|
478
492
|
assert_equal false, cookie.for_domain?
|
493
|
+
assert_raises(ArgumentError) {
|
494
|
+
# path is missing
|
495
|
+
cookie.acceptable?
|
496
|
+
}
|
479
497
|
|
480
498
|
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup, :domain => 'example.org', :for_domain? => true)
|
481
499
|
assert_equal 'key', cookie.name
|
@@ -483,6 +501,10 @@ class TestHTTPCookie < Test::Unit::TestCase
|
|
483
501
|
assert_equal expires, cookie.expires
|
484
502
|
assert_equal 'example.org', cookie.domain
|
485
503
|
assert_equal true, cookie.for_domain?
|
504
|
+
assert_raises(ArgumentError) {
|
505
|
+
# path is missing
|
506
|
+
cookie.acceptable?
|
507
|
+
}
|
486
508
|
|
487
509
|
assert_raises(ArgumentError) { HTTP::Cookie.new(:name => 'name') }
|
488
510
|
assert_raises(ArgumentError) { HTTP::Cookie.new(:value => 'value') }
|
@@ -588,33 +610,49 @@ class TestHTTPCookie < Test::Unit::TestCase
|
|
588
610
|
HTTP::Cookie.new(cookie_values(:value => 'bar')))
|
589
611
|
end
|
590
612
|
|
591
|
-
def
|
613
|
+
def test_new_tld_domain
|
592
614
|
url = URI 'http://rubyforge.org/'
|
593
615
|
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
616
|
+
tld_cookie1 = HTTP::Cookie.new(cookie_values(:domain => 'org', :origin => url))
|
617
|
+
assert_equal false, tld_cookie1.for_domain?
|
618
|
+
assert_equal 'org', tld_cookie1.domain
|
619
|
+
assert_equal false, tld_cookie1.acceptable?
|
620
|
+
|
621
|
+
tld_cookie2 = HTTP::Cookie.new(cookie_values(:domain => '.org', :origin => url))
|
622
|
+
assert_equal false, tld_cookie1.for_domain?
|
623
|
+
assert_equal 'org', tld_cookie2.domain
|
624
|
+
assert_equal false, tld_cookie2.acceptable?
|
625
|
+
end
|
626
|
+
|
627
|
+
def test_new_tld_domain_from_tld
|
628
|
+
url = URI 'http://org/'
|
629
|
+
|
630
|
+
tld_cookie1 = HTTP::Cookie.new(cookie_values(:domain => 'org', :origin => url))
|
631
|
+
assert_equal false, tld_cookie1.for_domain?
|
632
|
+
assert_equal 'org', tld_cookie1.domain
|
633
|
+
assert_equal true, tld_cookie1.acceptable?
|
634
|
+
|
635
|
+
tld_cookie2 = HTTP::Cookie.new(cookie_values(:domain => '.org', :origin => url))
|
636
|
+
assert_equal false, tld_cookie1.for_domain?
|
637
|
+
assert_equal 'org', tld_cookie2.domain
|
638
|
+
assert_equal true, tld_cookie2.acceptable?
|
600
639
|
end
|
601
640
|
|
602
641
|
def test_fall_back_rules_for_local_domains
|
603
642
|
url = URI 'http://www.example.local'
|
604
643
|
|
605
|
-
|
606
|
-
|
607
|
-
}
|
644
|
+
tld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.local', :origin => url))
|
645
|
+
assert_equal false, tld_cookie.acceptable?
|
608
646
|
|
609
647
|
sld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.example.local', :origin => url))
|
648
|
+
assert_equal true, sld_cookie.acceptable?
|
610
649
|
end
|
611
650
|
|
612
651
|
def test_new_rejects_cookies_with_ipv4_address_subdomain
|
613
652
|
url = URI 'http://192.168.0.1/'
|
614
653
|
|
615
|
-
|
616
|
-
|
617
|
-
}
|
654
|
+
cookie = HTTP::Cookie.new(cookie_values(:domain => '.0.1', :origin => url))
|
655
|
+
assert_equal false, cookie.acceptable?
|
618
656
|
end
|
619
657
|
|
620
658
|
def test_path
|
@@ -669,17 +707,39 @@ class TestHTTPCookie < Test::Unit::TestCase
|
|
669
707
|
end
|
670
708
|
}
|
671
709
|
assert 'example.com', cookie.domain
|
710
|
+
|
711
|
+
url = URI 'http://rubyforge.org/'
|
712
|
+
|
713
|
+
[nil, '', '.'].each { |d|
|
714
|
+
cookie = HTTP::Cookie.new('Foo', 'Bar', :path => '/')
|
715
|
+
cookie.domain = d
|
716
|
+
assert_equal nil, cookie.domain, "domain=#{d.inspect}"
|
717
|
+
assert_equal nil, cookie.domain_name, "domain=#{d.inspect}"
|
718
|
+
assert_raises(ArgumentError) {
|
719
|
+
cookie.acceptable?
|
720
|
+
}
|
721
|
+
|
722
|
+
cookie = HTTP::Cookie.new('Foo', 'Bar', :path => '/')
|
723
|
+
cookie.origin = url
|
724
|
+
cookie.domain = d
|
725
|
+
assert_equal url.host, cookie.domain, "domain=#{d.inspect}"
|
726
|
+
assert_equal true, cookie.acceptable?, "domain=#{d.inspect}"
|
727
|
+
}
|
672
728
|
end
|
673
729
|
|
674
730
|
def test_origin=
|
675
731
|
url = URI.parse('http://example.com/path/')
|
676
732
|
|
677
733
|
cookie = HTTP::Cookie.new('a', 'b')
|
734
|
+
assert_raises(ArgumentError) {
|
735
|
+
cookie.origin = 123
|
736
|
+
}
|
678
737
|
cookie.origin = url
|
679
738
|
assert_equal '/path/', cookie.path
|
680
739
|
assert_equal 'example.com', cookie.domain
|
681
740
|
assert_equal false, cookie.for_domain
|
682
741
|
assert_raises(ArgumentError) {
|
742
|
+
# cannot change the origin once set
|
683
743
|
cookie.origin = URI.parse('http://www.example.com/')
|
684
744
|
}
|
685
745
|
|
@@ -689,13 +749,21 @@ class TestHTTPCookie < Test::Unit::TestCase
|
|
689
749
|
assert_equal 'example.com', cookie.domain
|
690
750
|
assert_equal true, cookie.for_domain
|
691
751
|
assert_raises(ArgumentError) {
|
752
|
+
# cannot change the origin once set
|
692
753
|
cookie.origin = URI.parse('http://www.example.com/')
|
693
754
|
}
|
694
755
|
|
695
756
|
cookie = HTTP::Cookie.new('a', 'b', :domain => '.example.com')
|
696
|
-
|
697
|
-
|
698
|
-
|
757
|
+
cookie.origin = URI.parse('http://example.org/')
|
758
|
+
assert_equal false, cookie.acceptable?
|
759
|
+
|
760
|
+
cookie = HTTP::Cookie.new('a', 'b', :domain => '.example.com')
|
761
|
+
cookie.origin = 'file:///tmp/test.html'
|
762
|
+
assert_equal nil, cookie.path
|
763
|
+
|
764
|
+
cookie = HTTP::Cookie.new('a', 'b', :domain => '.example.com', :path => '/')
|
765
|
+
cookie.origin = 'file:///tmp/test.html'
|
766
|
+
assert_equal false, cookie.acceptable?
|
699
767
|
end
|
700
768
|
|
701
769
|
def test_acceptable_from_uri?
|
@@ -284,9 +284,7 @@ module TestHTTPCookieJar
|
|
284
284
|
def test_cookies_no_host
|
285
285
|
url = URI 'file:///path/'
|
286
286
|
|
287
|
-
|
288
|
-
@jar.add(HTTP::Cookie.new(cookie_values(:origin => url)))
|
289
|
-
}
|
287
|
+
@jar.add(HTTP::Cookie.new(cookie_values(:origin => url)))
|
290
288
|
|
291
289
|
assert_equal(0, @jar.cookies(url).length)
|
292
290
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http-cookie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.pre9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akinori MUSHA
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-03
|
14
|
+
date: 2013-04-03 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: domain_name
|