Make HTTP::Cookie Comparable.

This commit is contained in:
Akinori MUSHA 2012-10-22 00:56:06 +09:00
parent d59a0ee5ca
commit ae4a9d8d40
3 changed files with 33 additions and 5 deletions

View file

@ -300,6 +300,17 @@ class HTTP::Cookie
"#{@name}=#{@value}"
end
# Compares the cookie with another. When there are many cookies with
# the same name for a URL, the value of the smallest must be used.
def <=>(other)
# RFC 6265 5.4
# Precedence: 1. longer path 2. older creation
(@name <=> other.name).nonzero? ||
(other.path.length <=> @path.length).nonzero? ||
@created_at <=> other.created_at
end
include Comparable
# YAML serialization helper for Syck.
def to_yaml_properties
PERSISTENT_PROPERTIES.map { |name| "@#{name}" }

View file

@ -51,11 +51,7 @@ class HTTP::CookieJar
select { |cookie|
!cookie.expired? && cookie.valid_for_uri?(url) && (cookie.accessed_at = now)
}.sort_by { |cookie|
# RFC 6265 5.4
# Precedence: 1. longer path 2. older creation
[-cookie.path.length, cookie.created_at]
}
}.sort
end
def empty?(url)

View file

@ -123,6 +123,27 @@ class TestHTTPCookieJar < Test::Unit::TestCase
assert_equal(0, @jar.cookies(URI('http://google.com/')).length)
end
def test_add_multiple_cookies_with_the_same_name
now = Time.now
cookies = [
{ :value => 'a', :path => '/', },
{ :value => 'b', :path => '/abc/def/', :created_at => now - 1 },
{ :value => 'c', :path => '/abc/def/', :domain => 'www.rubyforge.org', :created_at => now },
{ :value => 'd', :path => '/abc/' },
].map { |attrs|
HTTP::Cookie.new(cookie_values(attrs))
}
url = URI 'http://www.rubyforge.org/abc/def/ghi'
cookies.permutation(cookies.size) { |shuffled|
@jar.clear
shuffled.each { |cookie| @jar.add(url, cookie) }
assert_equal %w[b c d a], @jar.cookies(url).map { |cookie| cookie.value }
}
end
def test_add_rejects_cookies_that_do_not_contain_an_embedded_dot
url = URI 'http://rubyforge.org/'