Add HTTP::Cookie#set_cookie_value, and alias #cookie_value to #to_s.

This commit is contained in:
Akinori MUSHA 2013-03-14 11:35:25 +09:00
parent f60e678cb8
commit a831fc424c
3 changed files with 92 additions and 17 deletions

View file

@ -23,6 +23,10 @@ Or install it yourself as:
## Usage
########################
# Client side example
########################
# Initialize a cookie jar
jar = HTTP::CookieJar.new
@ -30,15 +34,30 @@ Or install it yourself as:
jar.load(filename) if File.exist?(filename)
# Store received cookies
HTTP::Cookie.parse(set_cookie_header_value, :origin => uri) { |cookie|
HTTP::Cookie.parse(set_cookie_header_value, origin: uri) { |cookie|
jar << cookie
}
# Extract cookies to send
cookie_value_to_send = jar.cookies(uri).join(', ')
# Get the value for the Cookie field of a request header
cookie_header_value = jar.cookies(uri).join(', ')
# Save to a file
jar.save_as(filename)
jar.save(filename)
########################
# Server side example
########################
# Generate a cookie
cookies = HTTP::Cookie.new("uid", "a12345", domain: 'example.org',
for_domain: true,
path: '/',
max_age: 7*86400)
# Get the value for the Set-Cookie field of a response header
set_cookie_header_value = cookies.set_cookie_value(my_url)
## To-Do list

View file

@ -385,21 +385,12 @@ class HTTP::Cookie
acceptable_from_uri?(uri) && normalize_path(uri.path).start_with?(@path)
end
def to_s
# Returns a string for use in a Cookie header value,
# i.e. "name=value".
def cookie_value
"#{@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).nonzero? ||
@value <=> other.value
end
include Comparable
alias to_s cookie_value
# Serializes the cookie into a cookies.txt line.
def to_cookiestxt_line(linefeed = "\n")
@ -414,6 +405,50 @@ class HTTP::Cookie
].join("\t") << linefeed
end
# Returns a string for use in a Set-Cookie header value. If the
# cookie does not have an origin set, one must be given from the
# argument.
#
# This method does not check if this cookie will be accepted from
# the origin.
def set_cookie_value(origin = nil)
origin = origin ? URI(origin) : @origin or
raise "origin must be specified to produce a value for Set-Cookie"
string = cookie_value
if @for_domain || @domain != DomainName.new(origin.host).hostname
string << "; domain=#{@domain}"
end
if (normalize_uri_path(origin) + './').path != @path
string << "; path=#{@path}"
end
if expires = @expires
string << "; expires=#{@expires.httpdate}"
end
if comment = @comment
string << "; comment=#{@comment}"
end
if httponly?
string << "; HttpOnly"
end
if secure?
string << "; secure"
end
string
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).nonzero? ||
@value <=> other.value
end
include Comparable
# YAML serialization helper for Syck.
def to_yaml_properties
PERSISTENT_PROPERTIES.map { |name| "@#{name}" }

View file

@ -369,6 +369,27 @@ class TestHTTPCookie < Test::Unit::TestCase
end
end
def test_set_cookie_value
url = URI.parse('http://rubyforge.org/')
cookie_params = @cookie_params.merge('secure' => 'secure')
cookie_value = 'foo=bar'
cookie_params.keys.combine.each do |keys|
cookie_text = [cookie_value, *keys.map { |key| cookie_params[key] }].join('; ')
cookie, = HTTP::Cookie.parse(cookie_text, :origin => url)
cookie2, = HTTP::Cookie.parse(cookie.set_cookie_value, :origin => url)
assert_equal(cookie.name, cookie2.name)
assert_equal(cookie.value, cookie2.value)
assert_equal(cookie.domain, cookie2.domain)
assert_equal(cookie.for_domain?, cookie2.for_domain?)
assert_equal(cookie.path, cookie2.path)
assert_equal(cookie.expires, cookie2.expires)
assert_equal(cookie.secure?, cookie2.secure?)
assert_equal(cookie.httponly?, cookie2.httponly?)
end
end
def test_parse_cookie_no_spaces
url = URI.parse('http://rubyforge.org/')
cookie_params = @cookie_params