mirror of
https://github.com/samsonjs/http-cookie.git
synced 2026-04-27 14:57:46 +00:00
Perform acceptance check in CookieJar#add instead of origin=.
- Cookie#acceptable? is added, which is called by such methods as Cookie.parse and CookieJar#add. - Cookie#origin= no longer raises ArgumentError just because it conflicts with the domain. - Cookie#origin= raises ArgumentError if it is given an object that is not URI or string-like.
This commit is contained in:
parent
90ffce9aa6
commit
ffabb614ad
4 changed files with 95 additions and 39 deletions
|
|
@ -313,14 +313,9 @@ class HTTP::Cookie
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
if origin
|
|
||||||
begin
|
|
||||||
cookie.origin = origin
|
cookie.origin = origin
|
||||||
rescue => e
|
|
||||||
logger.warn("Invalid cookie for the origin: #{origin} (#{e})") if logger
|
cookie.acceptable? or next
|
||||||
next
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
yield cookie if block_given?
|
yield cookie if block_given?
|
||||||
|
|
||||||
|
|
@ -422,10 +417,10 @@ class HTTP::Cookie
|
||||||
@origin.nil? or
|
@origin.nil? or
|
||||||
raise ArgumentError, "origin cannot be changed once it is set"
|
raise ArgumentError, "origin cannot be changed once it is set"
|
||||||
origin = URI(origin)
|
origin = URI(origin)
|
||||||
|
if URI::HTTP === origin
|
||||||
self.domain ||= origin.host
|
self.domain ||= origin.host
|
||||||
self.path ||= (origin + './').path
|
self.path ||= (origin + './').path
|
||||||
acceptable_from_uri?(origin) or
|
end
|
||||||
raise ArgumentError, "unacceptable cookie sent from URI #{origin}"
|
|
||||||
@origin = origin
|
@origin = origin
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -534,6 +529,22 @@ class HTTP::Cookie
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Tests if it is OK to accept this cookie considering its origin.
|
||||||
|
# If either domain or path is missing, raises ArgumentError. If
|
||||||
|
# origin is missing, returns true.
|
||||||
|
def acceptable?
|
||||||
|
case
|
||||||
|
when @domain.nil?
|
||||||
|
raise ArgumentError, "domain is missing"
|
||||||
|
when @path.nil?
|
||||||
|
raise ArgumentError, "path is missing"
|
||||||
|
when @origin.nil?
|
||||||
|
true
|
||||||
|
else
|
||||||
|
acceptable_from_uri?(@origin)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Tests if it is OK to send this cookie to a given `uri`. A runtime
|
# Tests if it is OK to send this cookie to a given `uri`. A runtime
|
||||||
# error is raised if the cookie's domain is unknown.
|
# error is raised if the cookie's domain is unknown.
|
||||||
def valid_for_uri?(uri)
|
def valid_for_uri?(uri)
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,9 @@ class HTTP::CookieJar
|
||||||
@store = other.instance_eval { @store.dup }
|
@store = other.instance_eval { @store.dup }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a cookie to the jar and returns self. A given cookie must
|
# Adds a cookie to the jar if it is acceptable, and returns self in
|
||||||
# have domain and path attributes set, or ArgumentError is raised.
|
# any case. A given cookie must have domain and path attributes
|
||||||
|
# set, or ArgumentError is raised.
|
||||||
#
|
#
|
||||||
# ### Compatibility Note for Mechanize::Cookie users
|
# ### Compatibility Note for Mechanize::Cookie users
|
||||||
#
|
#
|
||||||
|
|
@ -63,14 +64,10 @@ class HTTP::CookieJar
|
||||||
# jar.add!(cookie) # no acceptance check is performed
|
# jar.add!(cookie) # no acceptance check is performed
|
||||||
#
|
#
|
||||||
# # HTTP::Cookie
|
# # HTTP::Cookie
|
||||||
# jar.origin = origin # acceptance check is performed
|
# jar.origin = origin
|
||||||
# jar.add(cookie)
|
# jar.add(cookie) # acceptance check is performed
|
||||||
def add(cookie)
|
def add(cookie)
|
||||||
if cookie.domain.nil? || cookie.path.nil?
|
@store.add(cookie) if cookie.acceptable?
|
||||||
raise ArgumentError, "a cookie with unknown domain or path cannot be added"
|
|
||||||
end
|
|
||||||
|
|
||||||
@store.add(cookie)
|
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
alias << add
|
alias << add
|
||||||
|
|
|
||||||
|
|
@ -450,6 +450,9 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
assert_equal 'key', cookie.name
|
assert_equal 'key', cookie.name
|
||||||
assert_equal 'value', cookie.value
|
assert_equal 'value', cookie.value
|
||||||
assert_equal nil, cookie.expires
|
assert_equal nil, cookie.expires
|
||||||
|
assert_raises(ArgumentError) {
|
||||||
|
cookie.acceptable?
|
||||||
|
}
|
||||||
|
|
||||||
# Minimum unit for the expires attribute is second
|
# Minimum unit for the expires attribute is second
|
||||||
expires = Time.at((Time.now + 3600).to_i)
|
expires = Time.at((Time.now + 3600).to_i)
|
||||||
|
|
@ -458,24 +461,39 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
assert_equal 'key', cookie.name
|
assert_equal 'key', cookie.name
|
||||||
assert_equal 'value', cookie.value
|
assert_equal 'value', cookie.value
|
||||||
assert_equal expires, cookie.expires
|
assert_equal expires, cookie.expires
|
||||||
|
assert_raises(ArgumentError) {
|
||||||
|
cookie.acceptable?
|
||||||
|
}
|
||||||
|
|
||||||
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup)
|
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup)
|
||||||
assert_equal 'key', cookie.name
|
assert_equal 'key', cookie.name
|
||||||
assert_equal 'value', cookie.value
|
assert_equal 'value', cookie.value
|
||||||
assert_equal expires, cookie.expires
|
assert_equal expires, cookie.expires
|
||||||
assert_equal false, cookie.for_domain?
|
assert_equal false, cookie.for_domain?
|
||||||
|
assert_raises(ArgumentError) {
|
||||||
|
# domain and path are missing
|
||||||
|
cookie.acceptable?
|
||||||
|
}
|
||||||
|
|
||||||
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup, :domain => '.example.com')
|
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup, :domain => '.example.com')
|
||||||
assert_equal 'key', cookie.name
|
assert_equal 'key', cookie.name
|
||||||
assert_equal 'value', cookie.value
|
assert_equal 'value', cookie.value
|
||||||
assert_equal expires, cookie.expires
|
assert_equal expires, cookie.expires
|
||||||
assert_equal true, cookie.for_domain?
|
assert_equal true, cookie.for_domain?
|
||||||
|
assert_raises(ArgumentError) {
|
||||||
|
# path is missing
|
||||||
|
cookie.acceptable?
|
||||||
|
}
|
||||||
|
|
||||||
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup, :domain => 'example.com', :for_domain => false)
|
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup, :domain => 'example.com', :for_domain => false)
|
||||||
assert_equal 'key', cookie.name
|
assert_equal 'key', cookie.name
|
||||||
assert_equal 'value', cookie.value
|
assert_equal 'value', cookie.value
|
||||||
assert_equal expires, cookie.expires
|
assert_equal expires, cookie.expires
|
||||||
assert_equal false, cookie.for_domain?
|
assert_equal false, cookie.for_domain?
|
||||||
|
assert_raises(ArgumentError) {
|
||||||
|
# path is missing
|
||||||
|
cookie.acceptable?
|
||||||
|
}
|
||||||
|
|
||||||
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup, :domain => 'example.org', :for_domain? => true)
|
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup, :domain => 'example.org', :for_domain? => true)
|
||||||
assert_equal 'key', cookie.name
|
assert_equal 'key', cookie.name
|
||||||
|
|
@ -483,6 +501,10 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
assert_equal expires, cookie.expires
|
assert_equal expires, cookie.expires
|
||||||
assert_equal 'example.org', cookie.domain
|
assert_equal 'example.org', cookie.domain
|
||||||
assert_equal true, cookie.for_domain?
|
assert_equal true, cookie.for_domain?
|
||||||
|
assert_raises(ArgumentError) {
|
||||||
|
# path is missing
|
||||||
|
cookie.acceptable?
|
||||||
|
}
|
||||||
|
|
||||||
assert_raises(ArgumentError) { HTTP::Cookie.new(:name => 'name') }
|
assert_raises(ArgumentError) { HTTP::Cookie.new(:name => 'name') }
|
||||||
assert_raises(ArgumentError) { HTTP::Cookie.new(:value => 'value') }
|
assert_raises(ArgumentError) { HTTP::Cookie.new(:value => 'value') }
|
||||||
|
|
@ -591,30 +613,46 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
def test_new_rejects_cookies_that_do_not_contain_an_embedded_dot
|
def test_new_rejects_cookies_that_do_not_contain_an_embedded_dot
|
||||||
url = URI 'http://rubyforge.org/'
|
url = URI 'http://rubyforge.org/'
|
||||||
|
|
||||||
assert_raises(ArgumentError) {
|
tld_cookie1 = HTTP::Cookie.new(cookie_values(:domain => 'org', :origin => url))
|
||||||
tld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.org', :origin => url))
|
assert_equal false, tld_cookie1.for_domain?
|
||||||
}
|
assert_equal 'org', tld_cookie1.domain
|
||||||
assert_raises(ArgumentError) {
|
assert_equal false, tld_cookie1.acceptable?
|
||||||
single_dot_cookie = HTTP::Cookie.new(cookie_values(:domain => '.', :origin => url))
|
|
||||||
}
|
tld_cookie2 = HTTP::Cookie.new(cookie_values(:domain => '.org', :origin => url))
|
||||||
|
assert_equal false, tld_cookie1.for_domain?
|
||||||
|
assert_equal 'org', tld_cookie2.domain
|
||||||
|
assert_equal false, tld_cookie2.acceptable?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_new_tld_domain_from_tld
|
||||||
|
url = URI 'http://org/'
|
||||||
|
|
||||||
|
tld_cookie1 = HTTP::Cookie.new(cookie_values(:domain => 'org', :origin => url))
|
||||||
|
assert_equal false, tld_cookie1.for_domain?
|
||||||
|
assert_equal 'org', tld_cookie1.domain
|
||||||
|
assert_equal true, tld_cookie1.acceptable?
|
||||||
|
|
||||||
|
tld_cookie2 = HTTP::Cookie.new(cookie_values(:domain => '.org', :origin => url))
|
||||||
|
assert_equal false, tld_cookie1.for_domain?
|
||||||
|
assert_equal 'org', tld_cookie2.domain
|
||||||
|
assert_equal true, tld_cookie2.acceptable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_fall_back_rules_for_local_domains
|
def test_fall_back_rules_for_local_domains
|
||||||
url = URI 'http://www.example.local'
|
url = URI 'http://www.example.local'
|
||||||
|
|
||||||
assert_raises(ArgumentError) {
|
|
||||||
tld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.local', :origin => url))
|
tld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.local', :origin => url))
|
||||||
}
|
assert_equal false, tld_cookie.acceptable?
|
||||||
|
|
||||||
sld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.example.local', :origin => url))
|
sld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.example.local', :origin => url))
|
||||||
|
assert_equal true, sld_cookie.acceptable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_new_rejects_cookies_with_ipv4_address_subdomain
|
def test_new_rejects_cookies_with_ipv4_address_subdomain
|
||||||
url = URI 'http://192.168.0.1/'
|
url = URI 'http://192.168.0.1/'
|
||||||
|
|
||||||
assert_raises(ArgumentError) {
|
|
||||||
cookie = HTTP::Cookie.new(cookie_values(:domain => '.0.1', :origin => url))
|
cookie = HTTP::Cookie.new(cookie_values(:domain => '.0.1', :origin => url))
|
||||||
}
|
assert_equal false, cookie.acceptable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_path
|
def test_path
|
||||||
|
|
@ -675,11 +713,15 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
url = URI.parse('http://example.com/path/')
|
url = URI.parse('http://example.com/path/')
|
||||||
|
|
||||||
cookie = HTTP::Cookie.new('a', 'b')
|
cookie = HTTP::Cookie.new('a', 'b')
|
||||||
|
assert_raises(ArgumentError) {
|
||||||
|
cookie.origin = 123
|
||||||
|
}
|
||||||
cookie.origin = url
|
cookie.origin = url
|
||||||
assert_equal '/path/', cookie.path
|
assert_equal '/path/', cookie.path
|
||||||
assert_equal 'example.com', cookie.domain
|
assert_equal 'example.com', cookie.domain
|
||||||
assert_equal false, cookie.for_domain
|
assert_equal false, cookie.for_domain
|
||||||
assert_raises(ArgumentError) {
|
assert_raises(ArgumentError) {
|
||||||
|
# cannot change the origin once set
|
||||||
cookie.origin = URI.parse('http://www.example.com/')
|
cookie.origin = URI.parse('http://www.example.com/')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -689,13 +731,21 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
assert_equal 'example.com', cookie.domain
|
assert_equal 'example.com', cookie.domain
|
||||||
assert_equal true, cookie.for_domain
|
assert_equal true, cookie.for_domain
|
||||||
assert_raises(ArgumentError) {
|
assert_raises(ArgumentError) {
|
||||||
|
# cannot change the origin once set
|
||||||
cookie.origin = URI.parse('http://www.example.com/')
|
cookie.origin = URI.parse('http://www.example.com/')
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie = HTTP::Cookie.new('a', 'b', :domain => '.example.com')
|
cookie = HTTP::Cookie.new('a', 'b', :domain => '.example.com')
|
||||||
assert_raises(ArgumentError) {
|
|
||||||
cookie.origin = URI.parse('http://example.org/')
|
cookie.origin = URI.parse('http://example.org/')
|
||||||
}
|
assert_equal false, cookie.acceptable?
|
||||||
|
|
||||||
|
cookie = HTTP::Cookie.new('a', 'b', :domain => '.example.com')
|
||||||
|
cookie.origin = 'file:///tmp/test.html'
|
||||||
|
assert_equal nil, cookie.path
|
||||||
|
|
||||||
|
cookie = HTTP::Cookie.new('a', 'b', :domain => '.example.com', :path => '/')
|
||||||
|
cookie.origin = 'file:///tmp/test.html'
|
||||||
|
assert_equal false, cookie.acceptable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_acceptable_from_uri?
|
def test_acceptable_from_uri?
|
||||||
|
|
|
||||||
|
|
@ -284,9 +284,7 @@ module TestHTTPCookieJar
|
||||||
def test_cookies_no_host
|
def test_cookies_no_host
|
||||||
url = URI 'file:///path/'
|
url = URI 'file:///path/'
|
||||||
|
|
||||||
assert_raises(ArgumentError) {
|
|
||||||
@jar.add(HTTP::Cookie.new(cookie_values(:origin => url)))
|
@jar.add(HTTP::Cookie.new(cookie_values(:origin => url)))
|
||||||
}
|
|
||||||
|
|
||||||
assert_equal(0, @jar.cookies(url).length)
|
assert_equal(0, @jar.cookies(url).length)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue