diff --git a/lib/http/cookie.rb b/lib/http/cookie.rb index 8be45be..6aeffed 100644 --- a/lib/http/cookie.rb +++ b/lib/http/cookie.rb @@ -361,15 +361,28 @@ class HTTP::Cookie # See #domain. def domain=(domain) - if DomainName === domain + case domain + when nil + @for_domain = false + if @origin + @domain_name = DomainName.new(@origin.host) + @domain = @domain_name.hostname + else + @domain_name = @domain = nil + end + return nil + when DomainName @domain_name = domain else domain = check_string_type(domain) or raise TypeError, "#{domain.class} is not a String" if domain.start_with?('.') - @for_domain = true + for_domain = true domain = domain[1..-1] end + if domain.empty? + return self.domain = nil + end # Do we really need to support this? if domain.match(/\A([^:]+):[0-9]+\z/) domain = $1 @@ -377,8 +390,10 @@ class HTTP::Cookie @domain_name = DomainName.new(domain) end # RFC 6265 5.3 5. - if @domain_name.domain.nil? # a public suffix or IP address + if domain_name.domain.nil? # a public suffix or IP address @for_domain = false + else + @for_domain = for_domain unless for_domain.nil? end @domain = @domain_name.hostname end diff --git a/test/test_http_cookie.rb b/test/test_http_cookie.rb index 0f86837..ad4ab1f 100644 --- a/test/test_http_cookie.rb +++ b/test/test_http_cookie.rb @@ -610,7 +610,7 @@ class TestHTTPCookie < Test::Unit::TestCase HTTP::Cookie.new(cookie_values(:value => 'bar'))) end - def test_new_rejects_cookies_that_do_not_contain_an_embedded_dot + def test_new_tld_domain url = URI 'http://rubyforge.org/' tld_cookie1 = HTTP::Cookie.new(cookie_values(:domain => 'org', :origin => url)) @@ -707,6 +707,24 @@ class TestHTTPCookie < Test::Unit::TestCase end } assert 'example.com', cookie.domain + + url = URI 'http://rubyforge.org/' + + [nil, '', '.'].each { |d| + cookie = HTTP::Cookie.new('Foo', 'Bar', :path => '/') + cookie.domain = d + assert_equal nil, cookie.domain, "domain=#{d.inspect}" + assert_equal nil, cookie.domain_name, "domain=#{d.inspect}" + assert_raises(ArgumentError) { + cookie.acceptable? + } + + cookie = HTTP::Cookie.new('Foo', 'Bar', :path => '/') + cookie.origin = url + cookie.domain = d + assert_equal url.host, cookie.domain, "domain=#{d.inspect}" + assert_equal true, cookie.acceptable?, "domain=#{d.inspect}" + } end def test_origin=