Froze rails gems
[depot.git] / vendor / rails / actionpack / lib / action_controller / cookies.rb
1 module ActionController #:nodoc:
2 # Cookies are read and written through ActionController#cookies.
3 #
4 # The cookies being read are the ones received along with the request, the cookies
5 # being written will be sent out with the response. Reading a cookie does not get
6 # the cookie object itself back, just the value it holds.
7 #
8 # Examples for writing:
9 #
10 # # Sets a simple session cookie.
11 # cookies[:user_name] = "david"
12 #
13 # # Sets a cookie that expires in 1 hour.
14 # cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now }
15 #
16 # Examples for reading:
17 #
18 # cookies[:user_name] # => "david"
19 # cookies.size # => 2
20 #
21 # Example for deleting:
22 #
23 # cookies.delete :user_name
24 #
25 # Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:
26 #
27 # cookies[:key] = {
28 # :value => 'a yummy cookie',
29 # :expires => 1.year.from_now,
30 # :domain => 'domain.com'
31 # }
32 #
33 # cookies.delete(:key, :domain => 'domain.com')
34 #
35 # The option symbols for setting cookies are:
36 #
37 # * <tt>:value</tt> - The cookie's value or list of values (as an array).
38 # * <tt>:path</tt> - The path for which this cookie applies. Defaults to the root
39 # of the application.
40 # * <tt>:domain</tt> - The domain for which this cookie applies.
41 # * <tt>:expires</tt> - The time at which this cookie expires, as a Time object.
42 # * <tt>:secure</tt> - Whether this cookie is a only transmitted to HTTPS servers.
43 # Default is +false+.
44 # * <tt>:http_only</tt> - Whether this cookie is accessible via scripting or
45 # only HTTP. Defaults to +false+.
46 module Cookies
47 def self.included(base)
48 base.helper_method :cookies
49 end
50
51 protected
52 # Returns the cookie container, which operates as described above.
53 def cookies
54 CookieJar.new(self)
55 end
56 end
57
58 class CookieJar < Hash #:nodoc:
59 def initialize(controller)
60 @controller, @cookies = controller, controller.request.cookies
61 super()
62 update(@cookies)
63 end
64
65 # Returns the value of the cookie by +name+, or +nil+ if no such cookie exists.
66 def [](name)
67 cookie = @cookies[name.to_s]
68 if cookie && cookie.respond_to?(:value)
69 cookie.size > 1 ? cookie.value : cookie.value[0]
70 end
71 end
72
73 # Sets the cookie named +name+. The second argument may be the very cookie
74 # value, or a hash of options as documented above.
75 def []=(name, options)
76 if options.is_a?(Hash)
77 options = options.inject({}) { |options, pair| options[pair.first.to_s] = pair.last; options }
78 options["name"] = name.to_s
79 else
80 options = { "name" => name.to_s, "value" => options }
81 end
82
83 set_cookie(options)
84 end
85
86 # Removes the cookie on the client machine by setting the value to an empty string
87 # and setting its expiration date into the past. Like <tt>[]=</tt>, you can pass in
88 # an options hash to delete cookies with extra data such as a <tt>:path</tt>.
89 def delete(name, options = {})
90 options.stringify_keys!
91 set_cookie(options.merge("name" => name.to_s, "value" => "", "expires" => Time.at(0)))
92 end
93
94 private
95 # Builds a CGI::Cookie object and adds the cookie to the response headers.
96 #
97 # The path of the cookie defaults to "/" if there's none in +options+, and
98 # everything is passed to the CGI::Cookie constructor.
99 def set_cookie(options) #:doc:
100 options["path"] = "/" unless options["path"]
101 cookie = CGI::Cookie.new(options)
102 @controller.logger.info "Cookie set: #{cookie}" unless @controller.logger.nil?
103 @controller.response.headers["cookie"] << cookie
104 end
105 end
106 end