[Patch] Deleting cookies with the same name from multiple domains

222 views
Skip to first unread message

Zach Brock

unread,
Jan 8, 2010, 1:01:18 AM1/8/10
to rack-...@googlegroups.com
This is a fix to an issue I ran into when dealing with a single sign on system. Cookies should be unique per request by name and domain, but Rack currently only treats them as unique by name. This commit basically makes it possible to delete cookie "foo" on both www.example.com and .example.com.

-Zach Brock
multiple_cookie_deletion.patch

Ryan Tomayko

unread,
Jan 15, 2010, 9:52:29 AM1/15/10
to rack-...@googlegroups.com

I've had reports of a bug that disallows same-named cookies to be set
for different domains. It looks like your patch addresses this as
well. Can you confirm?

Thanks,
Ryan

Zach Brock

unread,
Jan 15, 2010, 3:48:15 PM1/15/10
to rack-...@googlegroups.com
Hmm, I don't think so.  The only change I made was to the filtering logic in Utils.delete_cookie_header!
I'd imagine that adding same-named cookies with different domains doesn't work if you're using Rails though.  It puts the cookies in a hash where the key is the cookie name, so multiple domains can't really be represented.

Attached is a spec to show that it works as is.

-Zach
0001-Adding-a-spec-for-adding-multiple-cookies-with-the-s.patch

Ryan Tomayko

unread,
Apr 29, 2010, 6:13:00 PM4/29/10
to rack-...@googlegroups.com, zbr...@gmail.com
Applied the following to allow deleting same-named cookies on different domains.

Thanks,
Ryan

From 55cbbc91ae0a03445dd9e0ba1830f70fbd2f4d52 Mon Sep 17 00:00:00 2001
From: Zach Brock <zbr...@gmail.com>
Date: Thu, 7 Jan 2010 21:43:51 -0800
Subject: [PATCH] allow delete of cookies with same name but different domain

Adding a spec for adding multiple cookies with the same name on
different domains
---
lib/rack/utils.rb | 6 +++++-
test/spec_rack_response.rb | 19 +++++++++++++++++++
2 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb
index 50bee6e..f3b1a62 100644
--- a/lib/rack/utils.rb
+++ b/lib/rack/utils.rb
@@ -216,7 +216,11 @@ module Rack
end

cookies.reject! { |cookie|
- cookie =~ /\A#{escape(key)}=/
+ if value[:domain]
+ cookie =~ /\A#{escape(key)}=.*domain=#{value[:domain]}/
+ else
+ cookie =~ /\A#{escape(key)}=/
+ end
}

header["Set-Cookie"] = cookies.join("\n")
diff --git a/test/spec_rack_response.rb b/test/spec_rack_response.rb
index 98f8289..a8d9dfe 100644
--- a/test/spec_rack_response.rb
+++ b/test/spec_rack_response.rb
@@ -55,6 +55,13 @@ context "Rack::Response" do
response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2",
"foo3=bar3"].join("\n")
end

+ specify "can set cookies with the same name for multiple domains" do
+ response = Rack::Response.new
+ response.set_cookie "foo", {:value => "bar", :domain =>
"sample.example.com"}
+ response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
+ response["Set-Cookie"].should.equal ["foo=bar;
domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
+ end
+
specify "formats the Cookie expiration date accordingly to RFC 2109" do
response = Rack::Response.new

@@ -86,6 +93,18 @@ context "Rack::Response" do
].join("\n")
end

+ specify "can delete cookies with the same name from multiple domains" do
+ response = Rack::Response.new
+ response.set_cookie "foo", {:value => "bar", :domain =>
"sample.example.com"}
+ response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
+ response["Set-Cookie"].should.equal ["foo=bar;
domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
+ response.delete_cookie "foo", :domain => ".example.com"
+ response["Set-Cookie"].should.equal ["foo=bar;
domain=sample.example.com", "foo=; domain=.example.com; expires=Thu,
01-Jan-1970 00:00:00 GMT"].join("\n")
+ response.delete_cookie "foo", :domain => "sample.example.com"
+ response["Set-Cookie"].should.equal ["foo=; domain=.example.com;
expires=Thu, 01-Jan-1970 00:00:00 GMT",
+ "foo=;
domain=sample.example.com; expires=Thu, 01-Jan-1970 00:00:00
GMT"].join("\n")
+ end
+
specify "can do redirects" do
response = Rack::Response.new
response.redirect "/foo"
--
1.7.0.5
Reply all
Reply to author
Forward
0 new messages