mirror of
https://github.com/samsonjs/http-cookie.git
synced 2026-04-27 14:57:46 +00:00
Use the cookie creation time as base time for Max-Age.
Now #expire returns created_at + max_age when expires is nil. Cookie.parse: the :date keyword is renamed to :created_at, and the value is set to in parsed cookies via #created_at. In YAML serialization, #max_age is stored.
This commit is contained in:
parent
4512c333b4
commit
eed7e57813
4 changed files with 74 additions and 33 deletions
|
|
@ -38,7 +38,8 @@ class HTTP::Cookie
|
||||||
name value
|
name value
|
||||||
domain for_domain path
|
domain for_domain path
|
||||||
secure httponly
|
secure httponly
|
||||||
expires created_at accessed_at
|
expires max_age
|
||||||
|
created_at accessed_at
|
||||||
]
|
]
|
||||||
|
|
||||||
if String.respond_to?(:try_convert)
|
if String.respond_to?(:try_convert)
|
||||||
|
|
@ -110,8 +111,8 @@ class HTTP::Cookie
|
||||||
# The setter method accepts a Time object, a string representation
|
# The setter method accepts a Time object, a string representation
|
||||||
# of date/time, or `nil`.
|
# of date/time, or `nil`.
|
||||||
#
|
#
|
||||||
# Note that #max_age and #expires are mutually exclusive. Setting
|
# Setting this value resets #max_age to nil. When #max_age is
|
||||||
# \#max_age resets #expires to nil, and vice versa.
|
# non-nil, #expires returns `created_at + max_age`.
|
||||||
#
|
#
|
||||||
# :attr_accessor: expires
|
# :attr_accessor: expires
|
||||||
|
|
||||||
|
|
@ -122,8 +123,7 @@ class HTTP::Cookie
|
||||||
# represents an integer which will be stringified and then
|
# represents an integer which will be stringified and then
|
||||||
# integerized using #to_i.
|
# integerized using #to_i.
|
||||||
#
|
#
|
||||||
# Note that #max_age and #expires are mutually exclusive. Setting
|
# This value is reset to nil when #expires= is called.
|
||||||
# \#max_age resets #expires to nil, and vice versa.
|
|
||||||
#
|
#
|
||||||
# :attr_accessor: max_age
|
# :attr_accessor: max_age
|
||||||
|
|
||||||
|
|
@ -232,10 +232,6 @@ class HTTP::Cookie
|
||||||
# given origin is not allowed to issue is not included in the
|
# given origin is not allowed to issue is not included in the
|
||||||
# resulted array.
|
# resulted array.
|
||||||
#
|
#
|
||||||
# Any Max-Age attribute value found is converted to an expires
|
|
||||||
# value computing from the current time so that expiration check
|
|
||||||
# (#expired?) can be performed.
|
|
||||||
#
|
|
||||||
# If a block is given, each cookie object is passed to the block.
|
# If a block is given, each cookie object is passed to the block.
|
||||||
#
|
#
|
||||||
# Available option keywords are below:
|
# Available option keywords are below:
|
||||||
|
|
@ -243,9 +239,8 @@ class HTTP::Cookie
|
||||||
# :origin
|
# :origin
|
||||||
# : The cookie's origin URI/URL
|
# : The cookie's origin URI/URL
|
||||||
#
|
#
|
||||||
# :date
|
# :created_at
|
||||||
# : The base date used for interpreting Max-Age attribute values
|
# : The creation time of the cookies parsed.
|
||||||
# instead of the current time
|
|
||||||
#
|
#
|
||||||
# :logger
|
# :logger
|
||||||
# : Logger object useful for debugging
|
# : Logger object useful for debugging
|
||||||
|
|
@ -271,9 +266,8 @@ class HTTP::Cookie
|
||||||
if options
|
if options
|
||||||
logger = options[:logger]
|
logger = options[:logger]
|
||||||
origin = options[:origin] and origin = URI(origin)
|
origin = options[:origin] and origin = URI(origin)
|
||||||
date = options[:date]
|
created_at = options[:created_at]
|
||||||
end
|
end
|
||||||
date ||= Time.now
|
|
||||||
|
|
||||||
[].tap { |cookies|
|
[].tap { |cookies|
|
||||||
s = Scanner.new(set_cookie, logger)
|
s = Scanner.new(set_cookie, logger)
|
||||||
|
|
@ -282,6 +276,7 @@ class HTTP::Cookie
|
||||||
break if name.nil? || name.empty?
|
break if name.nil? || name.empty?
|
||||||
|
|
||||||
cookie = new(name, value)
|
cookie = new(name, value)
|
||||||
|
cookie.created_at = created_at if created_at
|
||||||
attrs.each { |aname, avalue|
|
attrs.each { |aname, avalue|
|
||||||
begin
|
begin
|
||||||
case aname
|
case aname
|
||||||
|
|
@ -311,10 +306,6 @@ class HTTP::Cookie
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
# Have `expires` set instead of `max_age`, so that
|
|
||||||
# expiration check (`expired?`) can be performed.
|
|
||||||
cookie.expires = date + cookie.max_age if cookie.max_age
|
|
||||||
|
|
||||||
if origin
|
if origin
|
||||||
begin
|
begin
|
||||||
cookie.origin = origin
|
cookie.origin = origin
|
||||||
|
|
@ -445,7 +436,9 @@ class HTTP::Cookie
|
||||||
attr_reader :session
|
attr_reader :session
|
||||||
alias session? session
|
alias session? session
|
||||||
|
|
||||||
attr_reader :expires
|
def expires
|
||||||
|
@expires or @created_at && @max_age ? @created_at + @max_age : nil
|
||||||
|
end
|
||||||
|
|
||||||
# See #expires.
|
# See #expires.
|
||||||
def expires=(t)
|
def expires=(t)
|
||||||
|
|
@ -483,8 +476,11 @@ class HTTP::Cookie
|
||||||
|
|
||||||
# Tests if this cookie is expired by now, or by a given time.
|
# Tests if this cookie is expired by now, or by a given time.
|
||||||
def expired?(time = Time.now)
|
def expired?(time = Time.now)
|
||||||
return false unless @expires
|
if expires = self.expires
|
||||||
time > @expires
|
expires <= time
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Expires this cookie by setting the expires attribute value to a
|
# Expires this cookie by setting the expires attribute value to a
|
||||||
|
|
@ -501,7 +497,8 @@ class HTTP::Cookie
|
||||||
# The comment attribute.
|
# The comment attribute.
|
||||||
attr_accessor :comment
|
attr_accessor :comment
|
||||||
|
|
||||||
# The time this cookie was created at.
|
# The time this cookie was created at. This value is used as a base
|
||||||
|
# date for interpreting the Max-Age attribute value. See #expires.
|
||||||
attr_accessor :created_at
|
attr_accessor :created_at
|
||||||
|
|
||||||
# The time this cookie was last accessed at.
|
# The time this cookie was last accessed at.
|
||||||
|
|
@ -618,11 +615,16 @@ class HTTP::Cookie
|
||||||
|
|
||||||
# YAML deserialization helper for Psych.
|
# YAML deserialization helper for Psych.
|
||||||
def yaml_initialize(tag, map)
|
def yaml_initialize(tag, map)
|
||||||
|
expires = nil
|
||||||
map.each { |key, value|
|
map.each { |key, value|
|
||||||
case key
|
case key
|
||||||
|
when 'expires'
|
||||||
|
# avoid clobbering max_age
|
||||||
|
expires = value
|
||||||
when *PERSISTENT_PROPERTIES
|
when *PERSISTENT_PROPERTIES
|
||||||
__send__(:"#{key}=", value)
|
__send__(:"#{key}=", value)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
self.expires = expires if self.max_age.nil?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class HTTP::CookieJar::CookiestxtSaver < HTTP::CookieJar::AbstractSaver
|
||||||
@for_domain ? True : False,
|
@for_domain ? True : False,
|
||||||
@path,
|
@path,
|
||||||
@secure ? True : False,
|
@secure ? True : False,
|
||||||
@expires.to_i,
|
expires.to_i,
|
||||||
@name,
|
@name,
|
||||||
@value
|
@value
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -200,18 +200,18 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
|
|
||||||
cookie = HTTP::Cookie.parse('name=Akinori; max-age=3600', :origin => url).first
|
cookie = HTTP::Cookie.parse('name=Akinori; max-age=3600', :origin => url).first
|
||||||
assert_in_delta Time.now + 3600, cookie.expires, 1
|
assert_in_delta Time.now + 3600, cookie.expires, 1
|
||||||
cookie = HTTP::Cookie.parse('name=Akinori; max-age=3600', :origin => url, :date => base).first
|
cookie = HTTP::Cookie.parse('name=Akinori; max-age=3600', :origin => url, :created_at => base).first
|
||||||
assert_equal base + 3600, cookie.expires
|
assert_equal base + 3600, cookie.expires
|
||||||
|
|
||||||
# Max-Age has precedence over Expires
|
# Max-Age has precedence over Expires
|
||||||
cookie = HTTP::Cookie.parse("name=Akinori; max-age=3600; expires=#{date}", :origin => url).first
|
cookie = HTTP::Cookie.parse("name=Akinori; max-age=3600; expires=#{date}", :origin => url).first
|
||||||
assert_in_delta Time.now + 3600, cookie.expires, 1
|
assert_in_delta Time.now + 3600, cookie.expires, 1
|
||||||
cookie = HTTP::Cookie.parse("name=Akinori; max-age=3600; expires=#{date}", :origin => url, :date => base).first
|
cookie = HTTP::Cookie.parse("name=Akinori; max-age=3600; expires=#{date}", :origin => url, :created_at => base).first
|
||||||
assert_equal base + 3600, cookie.expires
|
assert_equal base + 3600, cookie.expires
|
||||||
|
|
||||||
cookie = HTTP::Cookie.parse("name=Akinori; expires=#{date}; max-age=3600", :origin => url).first
|
cookie = HTTP::Cookie.parse("name=Akinori; expires=#{date}; max-age=3600", :origin => url).first
|
||||||
assert_in_delta Time.now + 3600, cookie.expires, 1
|
assert_in_delta Time.now + 3600, cookie.expires, 1
|
||||||
cookie = HTTP::Cookie.parse("name=Akinori; expires=#{date}; max-age=3600", :origin => url, :date => base).first
|
cookie = HTTP::Cookie.parse("name=Akinori; expires=#{date}; max-age=3600", :origin => url, :created_at => base).first
|
||||||
assert_equal base + 3600, cookie.expires
|
assert_equal base + 3600, cookie.expires
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -382,8 +382,8 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
date = Time.at(Time.now.to_i)
|
date = Time.at(Time.now.to_i)
|
||||||
cookie_params.keys.combine.each do |keys|
|
cookie_params.keys.combine.each do |keys|
|
||||||
cookie_text = [cookie_value, *keys.map { |key| cookie_params[key] }].join('; ')
|
cookie_text = [cookie_value, *keys.map { |key| cookie_params[key] }].join('; ')
|
||||||
cookie, = HTTP::Cookie.parse(cookie_text, :origin => url, :date => date)
|
cookie, = HTTP::Cookie.parse(cookie_text, :origin => url, :created_at => date)
|
||||||
cookie2, = HTTP::Cookie.parse(cookie.set_cookie_value, :origin => url, :date => date)
|
cookie2, = HTTP::Cookie.parse(cookie.set_cookie_value, :origin => url, :created_at => date)
|
||||||
|
|
||||||
assert_equal(cookie.name, cookie2.name)
|
assert_equal(cookie.name, cookie2.name)
|
||||||
assert_equal(cookie.value, cookie2.value)
|
assert_equal(cookie.value, cookie2.value)
|
||||||
|
|
@ -539,7 +539,7 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
|
|
||||||
cookie.max_age = 3600
|
cookie.max_age = 3600
|
||||||
assert_equal false, cookie.session?
|
assert_equal false, cookie.session?
|
||||||
assert_equal nil, cookie.expires
|
assert_equal cookie.created_at + 3600, cookie.expires
|
||||||
|
|
||||||
cookie.max_age = nil
|
cookie.max_age = nil
|
||||||
assert_equal true, cookie.session?
|
assert_equal true, cookie.session?
|
||||||
|
|
@ -775,6 +775,38 @@ class TestHTTPCookie < Test::Unit::TestCase
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_yaml_expires
|
||||||
|
require 'yaml'
|
||||||
|
cookie = HTTP::Cookie.new(cookie_values)
|
||||||
|
|
||||||
|
assert_equal false, cookie.session?
|
||||||
|
assert_equal nil, cookie.max_age
|
||||||
|
|
||||||
|
ycookie = YAML.load(cookie.to_yaml)
|
||||||
|
assert_equal false, ycookie.session?
|
||||||
|
assert_equal nil, ycookie.max_age
|
||||||
|
|
||||||
|
cookie.expires = nil
|
||||||
|
ycookie = YAML.load(cookie.to_yaml)
|
||||||
|
assert_equal true, ycookie.session?
|
||||||
|
assert_equal nil, ycookie.max_age
|
||||||
|
|
||||||
|
cookie.expires = Time.now + 3600
|
||||||
|
ycookie = YAML.load(cookie.to_yaml)
|
||||||
|
assert_equal false, ycookie.session?
|
||||||
|
assert_equal nil, ycookie.max_age
|
||||||
|
|
||||||
|
cookie.max_age = 3600
|
||||||
|
ycookie = YAML.load(cookie.to_yaml)
|
||||||
|
assert_equal false, ycookie.session?
|
||||||
|
assert_equal cookie.created_at + 3600, ycookie.expires
|
||||||
|
|
||||||
|
cookie.max_age = nil
|
||||||
|
ycookie = YAML.load(cookie.to_yaml)
|
||||||
|
assert_equal true, ycookie.session?
|
||||||
|
assert_equal nil, ycookie.expires
|
||||||
|
end
|
||||||
|
|
||||||
def test_s_path_match?
|
def test_s_path_match?
|
||||||
assert_equal true, HTTP::Cookie.path_match?('/admin/', '/admin/index')
|
assert_equal true, HTTP::Cookie.path_match?('/admin/', '/admin/index')
|
||||||
assert_equal false, HTTP::Cookie.path_match?('/admin/', '/Admin/index')
|
assert_equal false, HTTP::Cookie.path_match?('/admin/', '/Admin/index')
|
||||||
|
|
|
||||||
|
|
@ -363,13 +363,16 @@ class TestHTTPCookieJar < Test::Unit::TestCase
|
||||||
h_cookie = HTTP::Cookie.new(cookie_values(:name => 'Quux',
|
h_cookie = HTTP::Cookie.new(cookie_values(:name => 'Quux',
|
||||||
:value => 'Foo#Quux',
|
:value => 'Foo#Quux',
|
||||||
:httponly => true))
|
:httponly => true))
|
||||||
|
ma_cookie = HTTP::Cookie.new(cookie_values(:name => 'Maxage',
|
||||||
|
:value => 'Foo#Maxage',
|
||||||
|
:max_age => 15000))
|
||||||
@jar.add(cookie)
|
@jar.add(cookie)
|
||||||
@jar.add(s_cookie)
|
@jar.add(s_cookie)
|
||||||
@jar.add(cookie2)
|
@jar.add(cookie2)
|
||||||
@jar.add(h_cookie)
|
@jar.add(h_cookie)
|
||||||
|
@jar.add(ma_cookie)
|
||||||
|
|
||||||
assert_equal(4, @jar.cookies(url).length)
|
assert_equal(5, @jar.cookies(url).length)
|
||||||
|
|
||||||
Dir.mktmpdir do |dir|
|
Dir.mktmpdir do |dir|
|
||||||
filename = File.join(dir, "cookies.txt")
|
filename = File.join(dir, "cookies.txt")
|
||||||
|
|
@ -384,7 +387,7 @@ class TestHTTPCookieJar < Test::Unit::TestCase
|
||||||
jar = HTTP::CookieJar.new
|
jar = HTTP::CookieJar.new
|
||||||
jar.load(filename, :cookiestxt) # HACK test the format
|
jar.load(filename, :cookiestxt) # HACK test the format
|
||||||
cookies = jar.cookies(url)
|
cookies = jar.cookies(url)
|
||||||
assert_equal(3, cookies.length)
|
assert_equal(4, cookies.length)
|
||||||
cookies.each { |cookie|
|
cookies.each { |cookie|
|
||||||
case cookie.name
|
case cookie.name
|
||||||
when 'Foo'
|
when 'Foo'
|
||||||
|
|
@ -407,13 +410,17 @@ class TestHTTPCookieJar < Test::Unit::TestCase
|
||||||
assert_equal true, cookie.for_domain
|
assert_equal true, cookie.for_domain
|
||||||
assert_equal '/', cookie.path
|
assert_equal '/', cookie.path
|
||||||
assert_equal true, cookie.httponly?
|
assert_equal true, cookie.httponly?
|
||||||
|
when 'Maxage'
|
||||||
|
assert_equal 'Foo#Maxage', cookie.value
|
||||||
|
assert_equal nil, cookie.max_age
|
||||||
|
assert_in_delta ma_cookie.expires, cookie.expires, 1
|
||||||
else
|
else
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal(4, @jar.cookies(url).length)
|
assert_equal(5, @jar.cookies(url).length)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_expire_cookies
|
def test_expire_cookies
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue