This class provides a CookieJar object for Mongrels. Just initialize with response and request objects and then treat like a hash. Does not depend on cgi.rb
ry
# Provides a Rails-like CookieJar class for Mongrels. (ry dahl, 1187362405) # Unit tests at the bottom of this file. To execute the unit tests, use # ruby -r rubygems cookies_for_mongrels.rb require 'mongrel' class Time # Abbreviated day-of-week names specified by RFC 822 RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ] # Abbreviated month names specified by RFC 822 RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ] # Strange Cookie Expire time format def gmt_rfc822 t = self.clone.gmtime return format("%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT", RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year, t.hour, t.min, t.sec) end end module Mongrel module Const # :nodoc: HTTP_COOKIE = 'HTTP_COOKIE'.freeze SET_COOKIE = 'Set-Cookie'.freeze COOKIE_VALUE_EXPIRES = "%s=%s; path=/; expires=%s".freeze # as in Merb COOKIE_VALUE = "%s=%s; path=/".freeze COOKIE_EXPIRED_TIME = Time.at(0).freeze COOKIE_SEPARATOR = ';,' end class CookieJar def initialize(request, response) @response = response @cookies = HttpRequest.query_parse( request.params[Const::HTTP_COOKIE], Const::COOKIE_SEPARATOR) end # Returns the value of the cookie by +name+ -- or nil if no such cookie # exists. You set new cookies using either the cookie method # or cookies[]= (for simple name/value cookies without options). def [](name) @cookies[name] end # Determines if a cookie key has been given by request. Does not include # cookies which have been set during this request def has_key?(name) @cookies.has_key?(name) end # Gives the size of the number of cookies read. Does not include cookies # which have been set during this request def size @cookies.size end # Removes the cookie on the client machine by setting the value to an # empty string and setting its expiration date into the past. def delete(name) set_cookie(name, nil, COOKIE_EXPIRED_TIME) end # Sets a (name, value) pair to be stored on as a cookie on the clients # computer. Optionally provide a Time object as an expiration date. def set(name, value, expires = nil) params = [name.to_s, HttpRequest.escape(value)] @response.header[Const::SET_COOKIE] = if expires params << expires.gmt_rfc822 Const::COOKIE_VALUE_EXPIRES % params else Const::COOKIE_VALUE % params end end alias_method :[]=, :set end end if __FILE__ == $0 require 'test/unit' require 'ostruct' require 'cgi' include Mongrel class CookieJarTest < Test::Unit::TestCase # Wdy, DD Mon YYYY HH:MM:SS GMT RFC1123_REGEXP = %r{\w\w\w, \d\d \w\w\w \d\d\d\d \d\d:\d\d:\d\d GMT} def request_mock(cookie_string) OpenStruct.new(:params => {'HTTP_COOKIE' => cookie_string}) end def setup @out = StringIO.new @response = HttpResponse.new(@out) end def test_blank_request request = request_mock nil cookies = CookieJar.new(request, @response) assert_nil cookies['hello'] end def test_set_single request = request_mock '' cookies = CookieJar.new(request, @response) assert_nil cookies['hello'] cookies['hello'] = 'world' @response.send_header @out.rewind assert_match 'Set-Cookie: hello=world; path=/', @out.read end def test_set_multiple request = request_mock '' cookies = CookieJar.new(request, @response) assert_nil cookies['hello'] cookies['hello'] = 'world' cookies['world'] = 'hello' @response.send_header @out.rewind s = @out.read assert_match %r{Set-Cookie: hello=world; path=/}, s assert_match %r{Set-Cookie: world=hello; path=/}, s assert_no_match %r{expires}, s end def test_set_with_expires request = request_mock '' cookies = CookieJar.new(request, @response) cookies.set('hello', 'world', Time.now) cookies.set('world', 'hello', Time.now) @response.send_header @out.rewind s = @out.read assert_match %r{Set-Cookie: hello=world; path=/; expires=}, s assert_match %r{Set-Cookie: world=hello; path=/; expires=}, s assert_match RFC1123_REGEXP, s end def test_read request = request_mock 'hello=world; my name is=haaaaaapy; world=hello' cookies = CookieJar.new(request, @response) assert cookies.has_key?('hello') assert_equal 'world', cookies['hello'] assert_equal 'haaaaaapy', cookies['my name is'] assert_equal 'hello', cookies['world'] assert_equal 3, cookies.size end end end
_______________________________________________ Mongrel-users mailing list Mongrel-users@rubyforge.org http://rubyforge.org/mailman/listinfo/mongrel-users