Permalink
Browse files

Backport set_cookie_header! and delete_cookie_header! fixes from mast…

…er, affecting rack-cache and rails 2.x
  • Loading branch information...
1 parent 418cb69 commit 7754cdb5f5fa937ed3e1a811680f349d0acba73d @raggi raggi committed Sep 8, 2011
Showing with 41 additions and 14 deletions.
  1. +38 −11 lib/rack/utils.rb
  2. +3 −3 test/spec_rack_response.rb
View
@@ -174,8 +174,8 @@ def set_cookie_header!(header, key, value)
path = "; path=" + value[:path] if value[:path]
# According to RFC 2109, we need dashes here.
# N.B.: cgi.rb uses spaces...
- expires = "; expires=" + value[:expires].clone.gmtime.
- strftime("%a, %d-%b-%Y %H:%M:%S GMT") if value[:expires]
+ expires = "; expires=" +
+ rfc2822(value[:expires].clone.gmtime) if value[:expires]
secure = "; secure" if value[:secure]
httponly = "; HttpOnly" if value[:httponly]
value = value[:value]
@@ -186,27 +186,38 @@ def set_cookie_header!(header, key, value)
"#{domain}#{path}#{expires}#{secure}#{httponly}"
case header["Set-Cookie"]
- when Array
- header["Set-Cookie"] << cookie
- when String
- header["Set-Cookie"] = [header["Set-Cookie"], cookie]
- when nil
+ when nil, ''
header["Set-Cookie"] = cookie
+ when String
+ header["Set-Cookie"] = [header["Set-Cookie"], cookie].join("\n")
+ when Array
+ header["Set-Cookie"] = (header["Set-Cookie"] + [cookie]).join("\n")
end
nil
end
module_function :set_cookie_header!
def delete_cookie_header!(header, key, value = {})
- unless Array === header["Set-Cookie"]
- header["Set-Cookie"] = [header["Set-Cookie"]].compact
+ case header["Set-Cookie"]
+ when nil, ''
+ cookies = []
+ when String
+ cookies = header["Set-Cookie"].split("\n")
+ when Array
+ cookies = header["Set-Cookie"]
end
- header["Set-Cookie"].reject! { |cookie|
- cookie =~ /\A#{escape(key)}=/
+ cookies.reject! { |cookie|
+ if value[:domain]
+ cookie =~ /\A#{escape(key)}=.*domain=#{value[:domain]}/
+ else
+ cookie =~ /\A#{escape(key)}=/
+ end
}
+ header["Set-Cookie"] = cookies.join("\n")
+
set_cookie_header!(header, key,
{:value => '', :path => nil, :domain => nil,
:expires => Time.at(0) }.merge(value))
@@ -215,6 +226,22 @@ def delete_cookie_header!(header, key, value = {})
end
module_function :delete_cookie_header!
+ # Modified version of stdlib time.rb Time#rfc2822 to use '%d-%b-%Y' instead
+ # of '% %b %Y'.
+ # It assumes that the time is in GMT to comply to the RFC 2109.
+ #
+ # NOTE: I'm not sure the RFC says it requires GMT, but is ambigous enough
+ # that I'm certain someone implemented only that option.
+ # Do not use %a and %b from Time.strptime, it would use localized names for
+ # weekday and month.
+ #
+ def rfc2822(time)
+ wday = Time::RFC2822_DAY_NAME[time.wday]
+ mon = Time::RFC2822_MONTH_NAME[time.mon - 1]
+ time.strftime("#{wday}, %d-#{mon}-%Y %H:%M:%S GMT")
+ end
+ module_function :rfc2822
+
# Return the bytesize of String; uses String#length under Ruby 1.8 and
# String#bytesize under 1.9.
if ''.respond_to?(:bytesize)
@@ -50,9 +50,9 @@
response.set_cookie "foo", "bar"
response["Set-Cookie"].should.equal "foo=bar"
response.set_cookie "foo2", "bar2"
- response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2"]
+ response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2"].join("\n")
response.set_cookie "foo3", "bar3"
- response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2", "foo3=bar3"]
+ response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2", "foo3=bar3"].join("\n")
end
specify "formats the Cookie expiration date accordingly to RFC 2109" do
@@ -81,7 +81,7 @@
response.set_cookie "foo2", "bar2"
response.delete_cookie "foo"
response["Set-Cookie"].should.equal ["foo2=bar2",
- "foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT"]
+ "foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT"].join("\n")
end
specify "can do redirects" do

0 comments on commit 7754cdb

Please sign in to comment.