Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

root/trunk/actionpack/lib/action_controller/cgi_ext/session.rb

Revision 7966, 2.1 kB (checked in by bitsweat, 1 year ago)

Use SecureRandom to generate unique ids, if available.

Line 
1 require 'digest/md5'
2 require 'cgi/session'
3 require 'cgi/session/pstore'
4
5 class CGI #:nodoc:
6   # * Expose the CGI instance to session stores.
7   # * Don't require 'digest/md5' whenever a new session id is generated.
8   class Session #:nodoc:
9     begin
10       require 'securerandom'
11
12       # Generate a 32-character unique id using SecureRandom.
13       # This is used to generate session ids but may be reused elsewhere.
14       def self.generate_unique_id(constant = nil)
15         SecureRandom.hex(16)
16       end
17     rescue LoadError
18       # Generate an 32-character unique id based on a hash of the current time,
19       # a random number, the process id, and a constant string. This is used
20       # to generate session ids but may be reused elsewhere.
21       def self.generate_unique_id(constant = 'foobar')
22         md5 = Digest::MD5.new
23         now = Time.now
24         md5 << now.to_s
25         md5 << String(now.usec)
26         md5 << String(rand(0))
27         md5 << String($$)
28         md5 << constant
29         md5.hexdigest
30       end
31     end
32
33     # Make the CGI instance available to session stores.
34     attr_reader :cgi
35     attr_reader :dbman
36     alias_method :initialize_without_cgi_reader, :initialize
37     def initialize(cgi, options = {})
38       @cgi = cgi
39       initialize_without_cgi_reader(cgi, options)
40     end
41
42     private
43       # Create a new session id.
44       def create_new_id
45         @new_session = true
46         self.class.generate_unique_id
47       end
48
49     # * Don't require 'digest/md5' whenever a new session is started.
50     class PStore #:nodoc:
51       def initialize(session, option={})
52         dir = option['tmpdir'] || Dir::tmpdir
53         prefix = option['prefix'] || ''
54         id = session.session_id
55         md5 = Digest::MD5.hexdigest(id)[0,16]
56         path = dir+"/"+prefix+md5
57         path.untaint
58         if File::exist?(path)
59           @hash = nil
60         else
61           unless session.new_session
62             raise CGI::Session::NoSession, "uninitialized session"
63           end
64           @hash = {}
65         end
66         @p = ::PStore.new(path)
67         @p.transaction do |p|
68           File.chmod(0600, p.path)
69         end
70       end
71     end
72   end
73 end
Note: See TracBrowser for help on using the browser.