ramaze 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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