summaryrefslogtreecommitdiff
path: root/lib/cgi/session/pstore.rb
blob: d681d994a94248e867654963be34440767089df5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
require 'cgi/session'
require 'pstore'

class CGI
  class Session
    def []=(key, val)
      unless @write_lock
	@write_lock = true
      end
      unless @data
	@data = @dbman.restore
      end
      #@data[key] = String(val)
      @data[key] = val
    end

    class PStore
      def check_id(id)
	/[^0-9a-zA-Z]/ =~ id.to_s ? false : true
      end

      def initialize session, option={}
	dir = option['tmpdir'] || ENV['TMP'] || '/tmp'
	prefix = option['prefix'] || ''
	id = session.session_id
	unless check_id(id)
	  raise ArgumentError, "session_id `%s' is invalid" % id
	end
	path = dir+"/"+prefix+id
	path.untaint
	unless File::exist? path
	  @hash = {}
	end
	@p = ::PStore.new path 
      end

      def restore
	unless @hash
	  @p.transaction do
	    begin
	      @hash = @p['hash']
	    rescue
	      @hash = {}
	    end
	  end
	end
	@hash
      end

      def update 
	@p.transaction do
	    @p['hash'] = @hash
	end
      end

      def close
	update
      end

      def delete
	path = @p.path
	File::unlink path
      end

    end
  end
end

if $0 == __FILE__
  STDIN.reopen("/dev/null")
  cgi = CGI.new
  session = CGI::Session.new cgi, 'database_manager' => CGI::Session::PStore
  session['key'] = {'k' => 'v'}
  puts session['key'].class
  fail unless Hash === session['key']
  puts session['key'].inspect
  fail unless session['key'].inspect == '{"k"=>"v"}'
end