ramaze 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. data/Rakefile +360 -0
  2. data/bin/ramaze +152 -0
  3. data/doc/CHANGELOG +2021 -0
  4. data/doc/COPYING +56 -0
  5. data/doc/COPYING.ja +51 -0
  6. data/doc/README +275 -0
  7. data/doc/TODO +33 -0
  8. data/doc/allison/LICENSE +184 -0
  9. data/doc/allison/README +37 -0
  10. data/doc/allison/allison.css +300 -0
  11. data/doc/allison/allison.gif +0 -0
  12. data/doc/allison/allison.js +307 -0
  13. data/doc/allison/allison.rb +287 -0
  14. data/doc/allison/cache/BODY +588 -0
  15. data/doc/allison/cache/CLASS_INDEX +4 -0
  16. data/doc/allison/cache/CLASS_PAGE +1 -0
  17. data/doc/allison/cache/FILE_INDEX +4 -0
  18. data/doc/allison/cache/FILE_PAGE +1 -0
  19. data/doc/allison/cache/FONTS +1 -0
  20. data/doc/allison/cache/FR_INDEX_BODY +1 -0
  21. data/doc/allison/cache/IMGPATH +1 -0
  22. data/doc/allison/cache/INDEX +1 -0
  23. data/doc/allison/cache/JAVASCRIPT +307 -0
  24. data/doc/allison/cache/METHOD_INDEX +4 -0
  25. data/doc/allison/cache/METHOD_LIST +1 -0
  26. data/doc/allison/cache/SRC_PAGE +1 -0
  27. data/doc/allison/cache/STYLE +322 -0
  28. data/doc/allison/cache/URL +1 -0
  29. data/examples/blog/main.rb +16 -0
  30. data/examples/blog/public/screen.css +106 -0
  31. data/examples/blog/src/controller.rb +50 -0
  32. data/examples/blog/src/element.rb +53 -0
  33. data/examples/blog/src/model.rb +29 -0
  34. data/examples/blog/template/edit.xhtml +6 -0
  35. data/examples/blog/template/index.xhtml +24 -0
  36. data/examples/blog/template/new.xhtml +5 -0
  37. data/examples/blog/template/view.xhtml +15 -0
  38. data/examples/blog/test/tc_entry.rb +18 -0
  39. data/examples/caching.rb +23 -0
  40. data/examples/element.rb +40 -0
  41. data/examples/hello.rb +23 -0
  42. data/examples/simple.rb +60 -0
  43. data/examples/templates/template/external.haml +21 -0
  44. data/examples/templates/template/external.liquid +28 -0
  45. data/examples/templates/template/external.mab +27 -0
  46. data/examples/templates/template/external.rhtml +29 -0
  47. data/examples/templates/template/external.rmze +24 -0
  48. data/examples/templates/template_erubis.rb +50 -0
  49. data/examples/templates/template_haml.rb +48 -0
  50. data/examples/templates/template_liquid.rb +64 -0
  51. data/examples/templates/template_markaby.rb +52 -0
  52. data/examples/templates/template_ramaze.rb +49 -0
  53. data/examples/whywiki/main.rb +56 -0
  54. data/examples/whywiki/template/edit.xhtml +14 -0
  55. data/examples/whywiki/template/show.xhtml +17 -0
  56. data/lib/proto/conf/benchmark.yaml +35 -0
  57. data/lib/proto/conf/debug.yaml +34 -0
  58. data/lib/proto/conf/live.yaml +33 -0
  59. data/lib/proto/conf/silent.yaml +31 -0
  60. data/lib/proto/conf/stage.yaml +33 -0
  61. data/lib/proto/main.rb +18 -0
  62. data/lib/proto/public/404.jpg +0 -0
  63. data/lib/proto/public/css/coderay.css +105 -0
  64. data/lib/proto/public/css/ramaze_error.css +42 -0
  65. data/lib/proto/public/error.xhtml +74 -0
  66. data/lib/proto/public/favicon.ico +0 -0
  67. data/lib/proto/public/js/jquery.js +1923 -0
  68. data/lib/proto/public/ramaze.png +0 -0
  69. data/lib/proto/src/controller/main.rb +7 -0
  70. data/lib/proto/src/element/page.rb +16 -0
  71. data/lib/proto/src/model.rb +5 -0
  72. data/lib/proto/template/index.xhtml +6 -0
  73. data/lib/ramaze.rb +317 -0
  74. data/lib/ramaze/adapter/mongrel.rb +111 -0
  75. data/lib/ramaze/adapter/webrick.rb +161 -0
  76. data/lib/ramaze/cache.rb +11 -0
  77. data/lib/ramaze/cache/memcached.rb +52 -0
  78. data/lib/ramaze/cache/memory.rb +6 -0
  79. data/lib/ramaze/cache/yaml_store.rb +37 -0
  80. data/lib/ramaze/controller.rb +10 -0
  81. data/lib/ramaze/dispatcher.rb +315 -0
  82. data/lib/ramaze/error.rb +11 -0
  83. data/lib/ramaze/gestalt.rb +108 -0
  84. data/lib/ramaze/global.rb +120 -0
  85. data/lib/ramaze/helper.rb +32 -0
  86. data/lib/ramaze/helper/aspect.rb +189 -0
  87. data/lib/ramaze/helper/auth.rb +120 -0
  88. data/lib/ramaze/helper/cache.rb +52 -0
  89. data/lib/ramaze/helper/feed.rb +135 -0
  90. data/lib/ramaze/helper/form.rb +204 -0
  91. data/lib/ramaze/helper/link.rb +80 -0
  92. data/lib/ramaze/helper/redirect.rb +48 -0
  93. data/lib/ramaze/helper/stack.rb +67 -0
  94. data/lib/ramaze/http_status.rb +66 -0
  95. data/lib/ramaze/inform.rb +166 -0
  96. data/lib/ramaze/snippets.rb +5 -0
  97. data/lib/ramaze/snippets/hash/keys_to_sym.rb +19 -0
  98. data/lib/ramaze/snippets/kernel/aquire.rb +22 -0
  99. data/lib/ramaze/snippets/kernel/autoreload.rb +79 -0
  100. data/lib/ramaze/snippets/kernel/caller_lines.rb +58 -0
  101. data/lib/ramaze/snippets/kernel/constant.rb +24 -0
  102. data/lib/ramaze/snippets/kernel/rescue_require.rb +12 -0
  103. data/lib/ramaze/snippets/kernel/self_method.rb +41 -0
  104. data/lib/ramaze/snippets/kernel/silently.rb +13 -0
  105. data/lib/ramaze/snippets/object/traits.rb +60 -0
  106. data/lib/ramaze/snippets/openstruct/temp.rb +10 -0
  107. data/lib/ramaze/snippets/string/DIVIDE.rb +16 -0
  108. data/lib/ramaze/snippets/string/camel_case.rb +14 -0
  109. data/lib/ramaze/snippets/string/snake_case.rb +12 -0
  110. data/lib/ramaze/snippets/symbol/to_proc.rb +14 -0
  111. data/lib/ramaze/snippets/thread/deadQUESTIONMARK.rb +11 -0
  112. data/lib/ramaze/store/default.rb +48 -0
  113. data/lib/ramaze/template.rb +102 -0
  114. data/lib/ramaze/template/amrita2.rb +40 -0
  115. data/lib/ramaze/template/erubis.rb +58 -0
  116. data/lib/ramaze/template/haml.rb +65 -0
  117. data/lib/ramaze/template/haml/actionview_stub.rb +20 -0
  118. data/lib/ramaze/template/liquid.rb +74 -0
  119. data/lib/ramaze/template/markaby.rb +68 -0
  120. data/lib/ramaze/template/ramaze.rb +177 -0
  121. data/lib/ramaze/template/ramaze/element.rb +166 -0
  122. data/lib/ramaze/template/ramaze/morpher.rb +156 -0
  123. data/lib/ramaze/tool/create.rb +70 -0
  124. data/lib/ramaze/tool/tidy.rb +71 -0
  125. data/lib/ramaze/trinity.rb +38 -0
  126. data/lib/ramaze/trinity/request.rb +244 -0
  127. data/lib/ramaze/trinity/response.rb +41 -0
  128. data/lib/ramaze/trinity/session.rb +129 -0
  129. data/lib/ramaze/version.rb +14 -0
  130. data/spec/spec_all.rb +73 -0
  131. data/spec/spec_helper.rb +215 -0
  132. data/spec/tc_adapter_mongrel.rb +24 -0
  133. data/spec/tc_adapter_webrick.rb +22 -0
  134. data/spec/tc_cache.rb +79 -0
  135. data/spec/tc_controller.rb +39 -0
  136. data/spec/tc_element.rb +100 -0
  137. data/spec/tc_error.rb +23 -0
  138. data/spec/tc_gestalt.rb +90 -0
  139. data/spec/tc_global.rb +46 -0
  140. data/spec/tc_helper_aspect.rb +65 -0
  141. data/spec/tc_helper_auth.rb +61 -0
  142. data/spec/tc_helper_cache.rb +81 -0
  143. data/spec/tc_helper_feed.rb +129 -0
  144. data/spec/tc_helper_form.rb +146 -0
  145. data/spec/tc_helper_link.rb +58 -0
  146. data/spec/tc_helper_redirect.rb +51 -0
  147. data/spec/tc_helper_stack.rb +55 -0
  148. data/spec/tc_morpher.rb +90 -0
  149. data/spec/tc_params.rb +84 -0
  150. data/spec/tc_request.rb +111 -0
  151. data/spec/tc_session.rb +56 -0
  152. data/spec/tc_store.rb +25 -0
  153. data/spec/tc_template_amrita2.rb +34 -0
  154. data/spec/tc_template_erubis.rb +41 -0
  155. data/spec/tc_template_haml.rb +44 -0
  156. data/spec/tc_template_liquid.rb +98 -0
  157. data/spec/tc_template_markaby.rb +74 -0
  158. data/spec/tc_template_ramaze.rb +54 -0
  159. data/spec/tc_tidy.rb +14 -0
  160. data/spec/template/amrita2/data.html +6 -0
  161. data/spec/template/amrita2/index.html +1 -0
  162. data/spec/template/amrita2/sum.html +1 -0
  163. data/spec/template/erubis/sum.rhtml +1 -0
  164. data/spec/template/haml/index.haml +5 -0
  165. data/spec/template/haml/with_vars.haml +4 -0
  166. data/spec/template/liquid/index.liquid +1 -0
  167. data/spec/template/liquid/products.liquid +45 -0
  168. data/spec/template/markaby/external.mab +8 -0
  169. data/spec/template/markaby/sum.mab +1 -0
  170. data/spec/template/ramaze/file_only.rmze +1 -0
  171. data/spec/template/ramaze/index.rmze +1 -0
  172. data/spec/template/ramaze/nested.rmze +1 -0
  173. data/spec/template/ramaze/sum.rmze +1 -0
  174. metadata +317 -0
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'ramaze/trinity/request'
5
+ require 'ramaze/trinity/response'
6
+ require 'ramaze/trinity/session'
7
+
8
+ module Ramaze
9
+
10
+ # The module to be included into the Controller it basically just provides
11
+ # #request, #response and #session, each accessing Thread.current to
12
+ # retrieve the demanded object
13
+
14
+ module Trinity
15
+ private
16
+
17
+ # same as
18
+ # Thread.current[:request]
19
+
20
+ def request
21
+ Thread.current[:request]
22
+ end
23
+
24
+ # same as
25
+ # Thread.current[:response]
26
+
27
+ def response
28
+ Thread.current[:response]
29
+ end
30
+
31
+ # same as
32
+ # Thread.current[:session]
33
+
34
+ def session
35
+ Thread.current[:session]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,244 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'cgi'
5
+ require 'tmpdir'
6
+ require 'digest/md5'
7
+
8
+ module Ramaze
9
+
10
+ # This class is used for processing the information coming in from a request
11
+ # to the dispatcher, it takes the original request-object, processes it and
12
+ # is later available in the controller or as Thread.current[:request]
13
+ #
14
+ # Please note that the implementation is lacking performance and security
15
+ # in favor of simplicity. Hopefully I (or some CGI-guru) will come along
16
+ # and implement this properly, until then consider it unsafe, but functional.
17
+ #
18
+ # Most information you will need is in the #params, which is a compound of
19
+ # all the information available from POST, GET, DELETE and PUT.
20
+
21
+ class Request
22
+ attr_accessor :request, :post_query, :get_query, :puts_query, :get_query
23
+
24
+ class << self
25
+
26
+ # get the current request out of Thread.current[:request]
27
+ #
28
+ # You can call this from everywhere with Ramaze::Request.current
29
+
30
+ def current
31
+ Thread.current[:request]
32
+ end
33
+ end
34
+
35
+ # create a new instance of Request, takes the original request-object
36
+ # and runs #parse_queries to extract/process the information inside
37
+
38
+ def initialize request = {}
39
+ @request = request
40
+ parse_queries
41
+ end
42
+
43
+ # you can access the original @request via this method_missing,
44
+ # first it tries to match your method with any of the HTTP parameters
45
+ # then, in case that fails, it will relay to @request
46
+
47
+ def method_missing meth, *args, &block
48
+ if value = @request.params[meth.to_s.upcase] rescue false
49
+ value
50
+ else
51
+ @request.send(meth, *args, &block)
52
+ end
53
+ end
54
+
55
+ # containts all the parameters given, no matter wheter with
56
+ # POST, GET, PUT or DELETE
57
+ # answers with a hash that is generated from the respective
58
+ # _query instance-variables and cached subsequently in @params
59
+
60
+ def params
61
+ @params ||= [
62
+ @get_query, @post_query, @put_query, @delete_query
63
+ ].inject({}) do |sum, hash|
64
+ sum.merge(hash || {})
65
+ end
66
+ end
67
+
68
+ # this parses stuff like post-requests (very untested)
69
+ # and also ?foo=bar stuff (get-query)
70
+ # WEBrick uses body as a streaming-object, so we have to #read.
71
+ # Mongrel has a normal string as body, we just call to_s in case
72
+ # it's no POST
73
+
74
+ def parse_queries
75
+ case request_method
76
+ when 'GET' : process_get
77
+ when 'POST' : process_post
78
+ when 'PUT' : process_put
79
+ when 'DELETE' : process_delete
80
+ end
81
+ end
82
+
83
+ # very naive implementation of POST-body parsing, this won't withstand
84
+ # any serious testing or multiple simultanous huge posts...
85
+ # However, it just extracts the information inside the @request.body
86
+ # and puts it into proper form
87
+ # you can access its contents via #post_query
88
+
89
+ def process_post
90
+ @post_query = {}
91
+
92
+ type, boundary = content_type.split(';')
93
+
94
+ if type.downcase == 'multipart/form-data' and not boundary.empty?
95
+ parse_multipart(body, boundary.split('=').last)
96
+ else
97
+ post_query = query_parse(body.respond_to?(:read) ? body.read : body)
98
+ post_query.each do |key, value|
99
+ @post_query[CGI.unescape(key)] = CGI.unescape(value)
100
+ end
101
+ end
102
+ end
103
+
104
+ # processing incoming GET, stuffing the results into @get_query,
105
+ # you can access the information via #get_query
106
+
107
+ def process_get
108
+ @get_query = {}
109
+
110
+ get_query = query_parse(query_string) rescue {}
111
+ get_query.each do |key, value|
112
+ @get_query[CGI.unescape(key)] = CGI.unescape(value)
113
+ end
114
+ end
115
+
116
+ # TODO
117
+ # - implement and test DELETE
118
+
119
+ def process_delete
120
+ @delete_query = {}
121
+ raise "Implement me"
122
+ end
123
+
124
+ # again, rather naive, it just gives you the control over what to do
125
+ # with the #body but will parse the parameters from the URL
126
+
127
+ def process_put
128
+ @pust_query = {}
129
+
130
+ put_query = query_parse(query_string) rescue {}
131
+ put_query.each do |key, value|
132
+ @put_query[CGI.unescape(key)] = CGI.unescape(value)
133
+ end
134
+ end
135
+
136
+ # process the parameters passed over the URL, they look like
137
+ #
138
+ # http://foo.bar/action?eins=one&zwei=two
139
+ #
140
+ # that would result in #params containing {'eins' => 'one', 'zwei' => 'two'}
141
+
142
+ def query_parse str
143
+ str = str.split('?').last.to_s rescue ''
144
+ hash = CGI.parse(str)
145
+ hash.each do |key, values|
146
+ key = CGI.unescape(key)
147
+ values = values.map{|v| CGI.unescape(v)}
148
+ hash[key] = values.size == 1 ? values.first : values
149
+ end
150
+ hash
151
+ end
152
+
153
+ # parse multipart-requests, just pass it something that responds to .read
154
+ # and a boundary for the parts.
155
+ # again a naive implementation without any guarantee against DoS.
156
+ #
157
+ # TODO:
158
+ # - rewrite parsing of multipart
159
+ # - chunk through the body and pipe into tempfile
160
+ # - look at merb for example of correct parsing
161
+
162
+ def parse_multipart(body, boundary)
163
+ text = body.read
164
+ text.split("--" << boundary).each do |chunk|
165
+ header = chunk.split("\r\n\r\n").first
166
+ next if (!header or !body) || (header.strip.empty? or chunk.strip.empty?)
167
+ head = parse_multipart_head(header)
168
+ next if head.empty?
169
+ chunk = chunk[(header.size + 4)..-3]
170
+ hash = Digest::MD5.hexdigest([head['name'], chunk.size, head.hash].inspect)
171
+ filename = File.join(Dir.tmpdir, hash)
172
+ File.open(filename, "w+") do |file|
173
+ file.print(chunk)
174
+ end
175
+ @post_query[head['name']] = File.open(filename)
176
+ end
177
+ body.rewind
178
+ end
179
+
180
+ # parse the head of the one part of multipart
181
+ # you most likely won't have to use this on your own :)
182
+
183
+ def parse_multipart_head(string)
184
+ string.gsub("\r\n", ";").split(';').inject({}) do |sum, param|
185
+ key, value = param.strip.split('=')
186
+ sum[key] = value[1..-2] if key and value
187
+ sum
188
+ end
189
+ end
190
+
191
+ # like request.params[key]
192
+
193
+ def [](key)
194
+ params[key]
195
+ end
196
+
197
+ # like reuqest.params[key] = value
198
+
199
+ def []=(key, value)
200
+ params[key] = value
201
+ end
202
+
203
+ # request_method == 'GET'
204
+ def get?() request_method == 'GET' end
205
+ # request_method == 'POST'
206
+ def post?() request_method == 'POST' end
207
+ # request_method == 'PUT'
208
+ def put?() request_method == 'PUT' end
209
+ # request_method == 'DELETE'
210
+ def delete?() request_method == 'DELETE' end
211
+
212
+ # remote_addr == '127.0.0.1'
213
+
214
+ def local?
215
+ remote_addr == '127.0.0.1'
216
+ end
217
+
218
+ # Is the request coming from a local network?
219
+
220
+ def local_net?(ip = remote_addr)
221
+ bip = ip.split('.').map{ |x| x.to_i }.pack('C4').unpack('N')[0]
222
+
223
+ # 127.0.0.1/32 => 2130706433
224
+ # 192.168.0.0/16 => 49320
225
+ # 172.16.0.0/12 => 2753
226
+ # 10.0.0.0/8 => 10
227
+
228
+ { 0 => 2130706433, 16 => 49320, 20 => 2753, 24 => 10}.each do |s,c|
229
+ return true if (bip >> s) == c
230
+ end
231
+
232
+ return false
233
+ end
234
+
235
+ # check the referer from which the browser came
236
+ # '/' if no referer given.
237
+
238
+ def referer
239
+ headers['HTTP_REFERER'] || '/'
240
+ rescue
241
+ params['HTTP_REFERER'] || '/'
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,41 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ module Ramaze
5
+ # The Response given back to the adapter, this is the center of every request
6
+ # made.
7
+ #
8
+ # In case you do a custom response, just make sure you implement all three
9
+ # properties: #out, #code, #head
10
+ # where head has to #respond_to? #[]
11
+ #
12
+ # code is the status-code ( http://en.wikipedia.org/wiki/List_of_HTTP_status_codes )
13
+ # and out should be something very String-like
14
+
15
+ class ResponseStruct < Struct
16
+
17
+ # get the current response out of Thread.current[:response]
18
+ #
19
+ # You can call this from everywhere with Ramaze::Response.current
20
+
21
+ def current
22
+ Thread.current[:response]
23
+ end
24
+
25
+ # just #inspect for this class in the format of
26
+ # <Response#324543 @code => 200, @head => {'Content-Type'=>'text/html', @out.size => 234>
27
+
28
+ def inspect
29
+ "<Response##{object_id} @code => #{code}, @head => #{head.inspect}, @out.size => #{out.size}>"
30
+ end
31
+ alias pretty_inspect inspect
32
+
33
+ # same as #head['Content-Type']
34
+
35
+ def content_type
36
+ head['Content-Type']
37
+ end
38
+ end
39
+
40
+ Response = ResponseStruct.new(:out, :code, :head)
41
+ end
@@ -0,0 +1,129 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'digest/sha2'
5
+
6
+ module Ramaze
7
+
8
+ # Session is the object that stores all the session-information of the user.
9
+ # It is heavily based on cookies storing the key to the information stored
10
+ # on the server.
11
+ #
12
+ # It uses caching as set in Global.cache and tries to set a cookie in case
13
+ # there is none set yet.
14
+
15
+ class Session
16
+ SESSION_KEY = '_ramaze_session_id'
17
+ attr_accessor :session
18
+
19
+ class << self
20
+
21
+ # Get the current session out of Thread.current[:session]
22
+ #
23
+ # You can call this from everywhere with Ramaze::Session.current
24
+
25
+ def current
26
+ Thread.current[:session]
27
+ end
28
+ end
29
+
30
+ # pass the request-object and it will extract the session-id (which is
31
+ # stored in the cookie with the key of SESSION_KEY
32
+
33
+ def initialize request
34
+ @session_id = parse(request)[SESSION_KEY]
35
+ end
36
+
37
+ # current session_id, will generate a new one based on #hash if no session
38
+ # is currently active
39
+
40
+ def session_id
41
+ @session_id ||= hash
42
+ end
43
+
44
+ # the current contents of session
45
+
46
+ def current
47
+ sessions[session_id] ||= {}
48
+ end
49
+
50
+ # all the sessions currently stored, in case there are none yet it will
51
+ # set the constant Ramaze::SessionCache and from then on start populating
52
+ # it with the sessions. SessionCache is an instance of Global.cache as
53
+ # well.
54
+
55
+ def sessions
56
+ Thread.main[:session_cache] ||= Global.cache.new
57
+ end
58
+
59
+ # this runs before #parse and will extract the information stored in the cookie
60
+ # of the client, in case there is none it will try to set one.
61
+ # Unfortunatly we have to go seperate paths here for mongrel and webrick,
62
+ # since they do not share the same API.
63
+ #
64
+ # ARGH, 3 different ways for webrick to hand us cookies!? (and counting)
65
+
66
+ def pre_parse request
67
+ if Global.adapter == :webrick
68
+ # input looks like this:
69
+ # "Set-Cookie: _ramaze__session_id=fa8cc88dafcb0973b48d4d65ef57e7d3\r\n"
70
+ cookie = request.raw_header.grep(/Set-Cookie/).first rescue ''
71
+ cookie = request.post_query.delete('Set-Cookie') if cookie.to_s.empty? and request.post?
72
+ cookie = request.header['cookie'] unless cookie
73
+ cookie.to_s.gsub(/Set-Cookie: (.*?)\r\n/, '\1')
74
+ else
75
+ cookie = (request.http_cookie rescue request.http_set_cookie rescue '') || ''
76
+ end
77
+ end
78
+
79
+ # parse the cookie and extract all the variables stored in there.
80
+
81
+ def parse request
82
+ cookie = pre_parse(request)
83
+
84
+ return cookie if cookie.respond_to?(:to_hash)
85
+
86
+ cookie.split('; ').inject({}) do |s,v|
87
+ key, value = v.split('=')
88
+ s.merge key.strip => value
89
+ end
90
+ rescue => ex
91
+ Informer.error ex
92
+ {SESSION_KEY => hash}
93
+ end
94
+
95
+ # tries to catch all methods and proxy them to the #current
96
+ # this makes it easier to do i.e. hash-manipulation directly
97
+ # on #session in the controller.
98
+
99
+ def method_missing meth, *args, &block
100
+ current.send(meth, *args, &block)
101
+ end
102
+
103
+ # show the contents of the session without key/value of the cookie
104
+
105
+ def inspect
106
+ tmp = current.clone
107
+ tmp.delete SESSION_KEY
108
+ tmp.inspect
109
+ end
110
+
111
+ # show only the key/value of the cookie, useful for debugging.
112
+
113
+ def export
114
+ "#{SESSION_KEY}=#{session_id}"
115
+ end
116
+
117
+ # generate an unique #hash for the current session
118
+
119
+ def hash
120
+ h = [
121
+ Time.now.to_f.to_s.reverse, rand,
122
+ Thread.current[:request].hash, rand,
123
+ Process.pid, rand,
124
+ object_id, rand
125
+ ].join
126
+ Digest::SHA512.hexdigest(h)
127
+ end
128
+ end
129
+ end