Even a host that equals a public suffix may not issue domain wide cookies.

This is described in RFC 6265 5.3.
This commit is contained in:
Akinori MUSHA 2013-03-28 00:36:01 +09:00
parent c5252649c8
commit a3a1acfee2

View file

@ -283,8 +283,8 @@ class HTTP::Cookie
begin begin
case aname case aname
when 'domain' when 'domain'
cookie.domain = avalue
cookie.for_domain = true cookie.for_domain = true
cookie.domain = avalue # This may negate @for_domain
when 'path' when 'path'
cookie.path = avalue cookie.path = avalue
when 'expires' when 'expires'
@ -376,6 +376,10 @@ class HTTP::Cookie
end end
@domain_name = DomainName.new(domain) @domain_name = DomainName.new(domain)
end end
# RFC 6265 5.3 5.
if @domain_name.domain.nil? # a public suffix or IP address
@for_domain = false
end
@domain = @domain_name.hostname @domain = @domain_name.hostname
end end
@ -514,16 +518,12 @@ class HTTP::Cookie
host = DomainName.new(uri.host) host = DomainName.new(uri.host)
# RFC 6265 5.3 # RFC 6265 5.3
# When the user agent "receives a cookie": return true if host.hostname == @domain
return @domain.nil? || host.hostname == @domain unless @for_domain
if host.cookie_domain?(@domain_name) if @for_domain # !host-only-flag
true host.cookie_domain?(@domain_name)
elsif host.hostname == @domain
@for_domain = false
true
else else
false @domain.nil?
end end
end end
@ -534,6 +534,7 @@ class HTTP::Cookie
raise "cannot tell if this cookie is valid because the domain is unknown" raise "cannot tell if this cookie is valid because the domain is unknown"
end end
uri = URI(uri) uri = URI(uri)
# RFC 6265 5.4
return false if secure? && !(URI::HTTPS === uri) return false if secure? && !(URI::HTTPS === uri)
acceptable_from_uri?(uri) && HTTP::Cookie.path_match?(@path, uri.path) acceptable_from_uri?(uri) && HTTP::Cookie.path_match?(@path, uri.path)
end end
@ -556,7 +557,7 @@ class HTTP::Cookie
raise "origin must be specified to produce a value for Set-Cookie" raise "origin must be specified to produce a value for Set-Cookie"
string = "#{@name}=#{Scanner.quote(@value)}" string = "#{@name}=#{Scanner.quote(@value)}"
if @for_domain || @domain != DomainName.new(origin.host).hostname if @for_domain
string << "; Domain=#{@domain}" string << "; Domain=#{@domain}"
end end
if (origin + './').path != @path if (origin + './').path != @path