nitro 0.8.0 → 0.9.3

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 (198) hide show
  1. data/AUTHORS +3 -4
  2. data/ChangeLog +418 -0
  3. data/LICENSE +1 -1
  4. data/README +157 -89
  5. data/RELEASES +50 -0
  6. data/Rakefile +5 -7
  7. data/benchmark/nitro/bench.rb +5 -0
  8. data/benchmark/nitro/simple-webrick-n-200.txt +44 -0
  9. data/benchmark/nitro/static-webrick-n-200.txt +43 -0
  10. data/benchmark/nitro/tiny-lhttpd-n-200-c-5.txt +43 -0
  11. data/benchmark/nitro/tiny-webrick-n-200-c-5.txt +44 -0
  12. data/benchmark/nitro/tiny-webrick-n-200.txt +44 -0
  13. data/benchmark/nitro/tiny2-webrick-n-200.txt +44 -0
  14. data/{lib/nitro/server/cluster.rb → bin/cluster} +26 -30
  15. data/bin/proto/README +2 -2
  16. data/bin/proto/{apache.conf → conf/apache.conf} +0 -0
  17. data/bin/proto/conf/app.conf.rb +22 -0
  18. data/bin/proto/conf/lhttpd.conf +236 -0
  19. data/bin/proto/ctl +4 -0
  20. data/bin/proto/lib/README +5 -0
  21. data/bin/proto/log/README +3 -0
  22. data/bin/proto/root/fcgi.rb +6 -0
  23. data/bin/proto/root/index.xhtml +65 -7
  24. data/bin/proto/root/m/nitro.png +0 -0
  25. data/examples/blog/README +7 -5
  26. data/examples/blog/{apache.conf → conf/apache.conf} +0 -0
  27. data/examples/blog/conf/app.conf.rb +56 -0
  28. data/examples/blog/conf/lhttpd.conf +236 -0
  29. data/examples/blog/ctl +4 -0
  30. data/examples/blog/lib/blog.rb +11 -136
  31. data/examples/blog/lib/blog/controller.rb +99 -0
  32. data/examples/blog/lib/blog/model.rb +39 -0
  33. data/examples/blog/log/README +3 -0
  34. data/examples/blog/root/comments.xhtml +2 -2
  35. data/examples/blog/root/fcgi.rb +6 -0
  36. data/examples/blog/root/index.xhtml +4 -5
  37. data/examples/blog/root/login.xhtml +2 -2
  38. data/examples/blog/root/style.xsl +9 -9
  39. data/examples/blog/root/view_entry.xhtml +2 -2
  40. data/examples/flash/conf/app.conf.rb +23 -0
  41. data/examples/flash/ctl +4 -0
  42. data/examples/flash/log/README +3 -0
  43. data/examples/flash/root/index.xhtml +0 -9
  44. data/examples/flash/root/show_inline_text.xhtml +10 -5
  45. data/examples/no_xsl_blog/README +12 -0
  46. data/examples/no_xsl_blog/conf/apache.conf +0 -0
  47. data/examples/no_xsl_blog/conf/app.conf.rb +57 -0
  48. data/examples/no_xsl_blog/conf/lhttpd.conf +236 -0
  49. data/examples/no_xsl_blog/ctl +4 -0
  50. data/examples/no_xsl_blog/lib/blog.rb +20 -0
  51. data/examples/no_xsl_blog/lib/blog/controller.rb +102 -0
  52. data/examples/no_xsl_blog/lib/blog/model.rb +39 -0
  53. data/examples/no_xsl_blog/lib/blog/template.rb +134 -0
  54. data/examples/no_xsl_blog/log/README +3 -0
  55. data/examples/no_xsl_blog/root/comments.xhtml +41 -0
  56. data/examples/no_xsl_blog/root/entry_form.xhtml +22 -0
  57. data/examples/no_xsl_blog/root/fcgi.rb +6 -0
  58. data/examples/no_xsl_blog/root/index.xhtml +39 -0
  59. data/examples/no_xsl_blog/root/login.xhtml +21 -0
  60. data/examples/no_xsl_blog/root/m/bubbles.gif +0 -0
  61. data/examples/no_xsl_blog/root/m/comments_curve.gif +0 -0
  62. data/examples/no_xsl_blog/root/m/down.gif +0 -0
  63. data/examples/no_xsl_blog/root/m/footer_bg.gif +0 -0
  64. data/examples/no_xsl_blog/root/m/garrow.gif +0 -0
  65. data/examples/no_xsl_blog/root/m/gbull.gif +0 -0
  66. data/examples/no_xsl_blog/root/m/grbull.gif +0 -0
  67. data/examples/no_xsl_blog/root/m/h1_bg.gif +0 -0
  68. data/examples/no_xsl_blog/root/m/header_bg.gif +0 -0
  69. data/examples/no_xsl_blog/root/m/nitro.gif +0 -0
  70. data/examples/no_xsl_blog/root/m/obull.gif +0 -0
  71. data/examples/no_xsl_blog/root/m/page_bg.gif +0 -0
  72. data/examples/no_xsl_blog/root/m/rss.gif +0 -0
  73. data/examples/no_xsl_blog/root/m/side_title_bg.gif +0 -0
  74. data/examples/no_xsl_blog/root/m/sidebar_bg.gif +0 -0
  75. data/examples/no_xsl_blog/root/recent_posts.xhtml +14 -0
  76. data/examples/no_xsl_blog/root/style.css +301 -0
  77. data/examples/no_xsl_blog/root/view_entry.xhtml +25 -0
  78. data/examples/no_xsl_blog/root/view_entry.xml +12 -0
  79. data/examples/og/run.rb +2 -2
  80. data/examples/tiny/README +2 -2
  81. data/examples/tiny/conf/apache.conf +5 -0
  82. data/examples/tiny/conf/app.conf.rb +21 -0
  83. data/examples/tiny/conf/lhttpd.conf +236 -0
  84. data/examples/tiny/ctl +4 -0
  85. data/examples/tiny/log/README +3 -0
  86. data/examples/tiny/root/fcgi.rb +6 -0
  87. data/examples/tiny/root/index.xhtml +7 -4
  88. data/examples/tiny/root/nitro.png +0 -0
  89. data/lib/glue.rb +13 -9
  90. data/lib/glue/array.rb +1 -1
  91. data/lib/glue/cache.rb +1 -1
  92. data/lib/glue/flexob.rb +12 -0
  93. data/lib/glue/hash.rb +1 -1
  94. data/lib/glue/inflector.rb +2 -2
  95. data/lib/glue/logger.rb +4 -8
  96. data/lib/glue/misc.rb +14 -0
  97. data/lib/glue/number.rb +1 -1
  98. data/lib/glue/object.rb +26 -0
  99. data/lib/glue/pool.rb +1 -1
  100. data/lib/glue/property.rb +84 -91
  101. data/lib/glue/string.rb +1 -1
  102. data/lib/glue/time.rb +1 -1
  103. data/lib/glue/validation.rb +1 -1
  104. data/lib/nitro.rb +18 -6
  105. data/lib/nitro/adaptors/cgi.rb +291 -0
  106. data/lib/nitro/adaptors/fastcgi.rb +42 -0
  107. data/lib/nitro/adaptors/runner.rb +123 -0
  108. data/lib/nitro/adaptors/webrick.rb +110 -0
  109. data/lib/nitro/buffering.rb +43 -0
  110. data/lib/nitro/builders/form.rb +1 -1
  111. data/lib/nitro/builders/rss.rb +1 -1
  112. data/{bin → lib/nitro}/cluster.rb +26 -30
  113. data/lib/nitro/context.rb +82 -0
  114. data/lib/nitro/controller.rb +50 -0
  115. data/lib/nitro/cookie.rb +46 -0
  116. data/lib/nitro/dispatcher.rb +105 -0
  117. data/lib/nitro/filters.rb +9 -10
  118. data/lib/nitro/localization.rb +42 -0
  119. data/lib/nitro/mail.rb +11 -14
  120. data/lib/nitro/render.rb +275 -0
  121. data/lib/nitro/request.rb +128 -0
  122. data/lib/nitro/response.rb +38 -0
  123. data/lib/nitro/scaffold.rb +11 -11
  124. data/lib/nitro/session.rb +84 -0
  125. data/lib/nitro/{server/shaders.rb → shaders.rb} +56 -36
  126. data/lib/nitro/ui/pager.rb +23 -26
  127. data/lib/nitro/{sitemap.rb → ui/sitemap.rb} +4 -12
  128. data/lib/nitro/uri.rb +1 -1
  129. data/lib/nitro/version.rb +10 -8
  130. data/lib/og.rb +66 -65
  131. data/lib/og/backend.rb +1 -1
  132. data/lib/og/backends/mysql.rb +48 -52
  133. data/lib/og/backends/psql.rb +34 -37
  134. data/lib/og/connection.rb +15 -15
  135. data/lib/og/enchant.rb +16 -9
  136. data/lib/og/meta.rb +127 -54
  137. data/lib/og/mock.rb +18 -18
  138. data/lib/og/version.rb +6 -4
  139. data/lib/parts/content.rb +4 -8
  140. data/test/glue/tc_logger.rb +3 -0
  141. data/test/glue/tc_property.rb +19 -3
  142. data/test/nitro/adaptors/tc_cgi.rb +63 -0
  143. data/test/nitro/adaptors/tc_webrick.rb +15 -0
  144. data/test/nitro/builders/tc_xml.rb +2 -2
  145. data/test/nitro/tc_context.rb +13 -0
  146. data/test/nitro/tc_controller.rb +47 -0
  147. data/test/nitro/tc_dispatcher.rb +64 -0
  148. data/test/nitro/tc_session.rb +20 -0
  149. data/test/nitro/{tc_sitemap.rb → ui/tc_sitemap.rb} +1 -1
  150. data/test/root/blog/list.xhtml +6 -0
  151. data/test/tc_og.rb +41 -4
  152. metadata +115 -59
  153. data/bin/proto/app.rb +0 -20
  154. data/bin/proto/config.rb +0 -77
  155. data/examples/blog/app.rb +0 -21
  156. data/examples/blog/config.rb +0 -95
  157. data/examples/blog/env.rb +0 -22
  158. data/examples/flash/README +0 -34
  159. data/examples/flash/app.rb +0 -20
  160. data/examples/flash/config.rb +0 -38
  161. data/examples/flash/lib/flash.rb +0 -40
  162. data/examples/flash/tmp.swf +0 -0
  163. data/examples/tiny/app.rb +0 -19
  164. data/examples/tiny/config.rb +0 -29
  165. data/examples/tiny/root/nitro-small.png +0 -0
  166. data/lib/nitro/application.rb +0 -217
  167. data/lib/nitro/config.rb +0 -128
  168. data/lib/nitro/events.rb +0 -122
  169. data/lib/nitro/html.rb +0 -151
  170. data/lib/nitro/http.rb +0 -102
  171. data/lib/nitro/l10n.rb +0 -30
  172. data/lib/nitro/server.rb +0 -59
  173. data/lib/nitro/server/appserver.rb +0 -67
  174. data/lib/nitro/server/cookie.rb +0 -87
  175. data/lib/nitro/server/dispatcher.rb +0 -62
  176. data/lib/nitro/server/filters.rb +0 -75
  177. data/lib/nitro/server/filters/autologin.rb +0 -51
  178. data/lib/nitro/server/fragment.rb +0 -70
  179. data/lib/nitro/server/handlers.rb +0 -127
  180. data/lib/nitro/server/render.rb +0 -426
  181. data/lib/nitro/server/request.rb +0 -658
  182. data/lib/nitro/server/requestpart.rb +0 -54
  183. data/lib/nitro/server/script.rb +0 -387
  184. data/lib/nitro/server/server.rb +0 -57
  185. data/lib/nitro/server/session.rb +0 -220
  186. data/lib/nitro/server/user.rb +0 -46
  187. data/lib/nitro/server/webrick.rb +0 -180
  188. data/lib/nitro/service.rb +0 -26
  189. data/lib/xsl/ui.xsl +0 -51
  190. data/lib/xsl/xforms.xsl +0 -28
  191. data/test/nitro/server/tc_cookie.rb +0 -34
  192. data/test/nitro/server/tc_filters.rb +0 -38
  193. data/test/nitro/server/tc_request.rb +0 -70
  194. data/test/nitro/server/tc_requestpart.rb +0 -28
  195. data/test/nitro/server/tc_session.rb +0 -34
  196. data/test/nitro/tc_events.rb +0 -44
  197. data/test/nitro/tc_html.rb +0 -79
  198. data/test/nitro/tc_http.rb +0 -18
@@ -1,658 +0,0 @@
1
- # code:
2
- # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: request.rb 167 2004-11-23 14:03:10Z gmosx $
6
-
7
- require "cgi"
8
- require "ftools"
9
-
10
- require "glue/string"
11
- require "nitro/uri"
12
- require "nitro/http"
13
- require "nitro/server/cookie"
14
- require "nitro/server/requestpart"
15
-
16
- module N
17
-
18
- # = RequestUtils
19
- #
20
- # A collection of Request utility methods. Factored out from the
21
- # Request object in a separate module to allow for inclusion in generic
22
- # request objects (for example WEBrick).
23
- #
24
- module RequestUtils
25
-
26
- # Full URI
27
- #
28
- def full_uri
29
- if @query_string
30
- return "#{@translated_uri}?#{@query_string}"
31
- else
32
- return @translated_uri
33
- end
34
- end
35
-
36
- # Expand URI
37
- # Calculates a new uri based on the request.uri that includes
38
- # the additional parameters suplied.
39
- #
40
- def expand_uri(params)
41
- hash = @parameters.dup()
42
- hash.update(params)
43
-
44
- pairs = []
45
- hash.each { |param, value|
46
- pairs << "#{param}=#{value}"
47
- }
48
-
49
- # gmosx: hash is ALWAYS non empty!
50
- return "#{@translated_uri}?#{pairs.join(';')}"
51
- end
52
-
53
- # Uses the passed oid_param to load a managed object (entity).
54
- # Enforces some form of security by checking the klass of the
55
- # requested entity.
56
- #
57
- def get_entity(oid_param, klass = nil)
58
- if oid = self[oid_param]
59
- obj = $og.load(oid, klass)
60
-
61
- if klass
62
- if obj.is_a?(klass)
63
- return obj
64
- else
65
- return nil
66
- end
67
- else
68
- return obj
69
- end
70
- else
71
- # Logger.error "request.get_object('#{oid_param}') failed!"
72
- return nil
73
- end
74
- end
75
-
76
- # Uses the passed name_param to load a managed object (entity)
77
- # by name.
78
- # Enforces some form of security by checking the klass of the
79
- # requested entity.
80
- #
81
- def get_entity_by_name(name_param, klass)
82
- if name = self[name_param]
83
- obj = $og.load_by_name(name, klass)
84
-
85
- if klass
86
- if obj.is_a?(klass)
87
- return obj
88
- else
89
- return nil
90
- end
91
- else
92
- # Logger.error "request.get_object_by_name('#{name_param}') failed!"
93
- return obj
94
- end
95
- else
96
- return nil
97
- end
98
- end
99
-
100
- end
101
-
102
- # = Request
103
- #
104
- # The context of an http protocol request. Encapsulates both
105
- # the request and the response context.
106
- #
107
- # === Future:
108
- #
109
- # - USE libapreq!
110
- # - Dont use env_table (arghhhh!)
111
- # - dont use a separate path and real path
112
- # - MEGA: unify request and request (like a socket, io
113
- # stream,etc). Evan subclass IO!
114
- # - extend request from hash? to make more compatible with irb?
115
- #
116
- # === Design:
117
- #
118
- # - uri: the original uri entered to the browser (INCLUDES qs)
119
- # gmosx: i included the qs and removed full_uri (always forgot
120
- # to use it anyway, was very error prone)
121
- # - translated_uri: as translated by the web server (no query string)
122
- # - path: the path to the actual script (or object)
123
- #
124
- # Example:
125
- #
126
- # http://www.site.com/faq/?id=1
127
- # ->
128
- # uri: /faq/?id=1
129
- # translated_uri: /faq/index.sx
130
- # path: base/site/root/faq/index.sx
131
- # query_string: id=1
132
- #
133
- # - querystring should probably include the ?
134
- # - Encapsulate ModRuby/Apache requests
135
- # - Based on resin3.0 excellent code:
136
- # com/caucho/server/http/HttpRequest.java
137
- # - use as much of ruby's default cgi/http code as
138
- # possible (why reinvent the wheel?)
139
- # Will use params with symbols for args. use uppercase for system
140
- # 'args'.
141
- #
142
- class Request
143
- # include usefull query parsing code from the standard
144
- # lib. ARGHHH cgi.rb sucks!
145
- include CGI::QueryExtension
146
- include RequestUtils
147
-
148
- # request methods enumeration
149
- METHOD_GET = 0
150
- METHOD_POST = 1
151
- METHOD_HEAD = 2
152
-
153
- # request method
154
- attr_accessor :method
155
-
156
- # content type
157
- attr_accessor :content_type
158
-
159
- # the uri for the request. For sub-requests keeps the
160
- # uri of the top level request.
161
- # gmosx: the writer is needed for injects.
162
- attr_accessor :uri
163
-
164
- # the uri as translated by the web server. For sub-requests keeps
165
- # the usri of the top level request.
166
- attr_accessor :translated_uri
167
-
168
- # the path to the actual object (script)
169
- # gets overriden by sub-requests, is not needed in scripts.
170
- attr_accessor :path
171
-
172
- # path info (extra parameters in the uri)
173
- #
174
- attr_accessor :path_info
175
-
176
- # the query string part of the uri
177
- attr_accessor :query_string
178
-
179
- # The query string is parsed to the parameters
180
- # hash.
181
- attr_accessor :parameters
182
- # alias for the parameters hash
183
- alias_method :query, :parameters
184
- # alias for the parameters hash
185
- alias_method :params, :parameters
186
-
187
- # the session this request is part-of.
188
- attr_accessor :session
189
-
190
- # The parts attached to this request.
191
- # A part is typically an uploaded file. By using
192
- # a separate hash instead of the parameters hash one
193
- # can easily enumerate parts.
194
- attr_accessor :parts
195
-
196
- # The level of the request (0 = toplevel). When the evaluating
197
- # the sub-scripts that the top level script includes, the
198
- # request level is incremented.
199
- attr_accessor :level
200
-
201
- # the remote address for this request
202
- attr_accessor :remote_addr
203
-
204
- # Is the request cacheable?
205
- # Set this attribute to 'true' to avoid caching the request
206
- # fragment. Used to avoid caching 'action' requests.
207
- attr_accessor :uncacheable
208
-
209
- # the locale hash for this request.
210
- attr_accessor :locale
211
-
212
- # the shader for this request.
213
- attr_accessor :shader
214
-
215
- # the script hash for this request
216
- attr_accessor :tag
217
-
218
- # keep the original handler process uri, usefull as a cache key.
219
- # Typically updated in subrequests only. Investigate if we could
220
- # use a hash here!
221
- attr_accessor :fragment_hash
222
-
223
- # Keep all errors to present them in-page when in admin mode.
224
- attr_accessor :error_log
225
-
226
- # The top level script for this request.
227
- attr_accessor :top_script
228
-
229
- # last modified cache
230
- attr_accessor :lm
231
-
232
- # request:
233
-
234
- # the incoming headers
235
- # gmosx: writer needed for inject (sub-req cloning)
236
- attr_accessor :in
237
-
238
- # the incoming cookies
239
- attr_accessor :in_cookies
240
-
241
- # response:
242
-
243
- # the outgoing headers
244
- attr_accessor :out
245
-
246
- # the outgoing cookies
247
- attr_accessor :out_cookies
248
-
249
- # the outgoing buffer
250
- attr_accessor :out_buffer
251
-
252
- # request content type, default: text/html
253
- attr_accessor :content_type
254
-
255
- # HTTP request status
256
- attr_accessor :status
257
-
258
- # HTTP request message
259
- attr_accessor :message
260
-
261
- def initialize
262
- # set to 0 (== top level). When including fragments
263
- # the level is incremented.
264
- @level = 0
265
-
266
- # gmosx: it would be good to defere the hash creation,
267
- # but having the hash always created saves as a LOT of
268
- # checks in client code, so we create it here.
269
- #
270
- # FIXME: WE SHOULD NOT CREATE unneeded hash objects.
271
- #
272
- # @parts = {}
273
-
274
- # request:
275
- # provide some fair initialization values.
276
- set_status(200)
277
- @content_type = "text/html; charset=iso-8859-7"
278
- @out = {}
279
- @out_cookies = {}
280
- end
281
-
282
- #-----------------------------------------------------------------------
283
- # Headers
284
-
285
- # Return the referer to this resource. For the initial page in the
286
- # clickstream there is no referer, set "/" by default.
287
-
288
- def referer
289
- return @in["REFERER"] || "/"
290
- end
291
- alias_method :referrer, :referer
292
-
293
- #-----------------------------------------------------------------------
294
- # Cookies
295
-
296
- # this method is also usefull for probing (testing) the request class.
297
- # FIXME: optimize this (libapreq)
298
-
299
- def parse_cookies(cookie_string)
300
- @cookies = Cookie.parse(cookie_string)
301
- end
302
- alias_method :parse_cookie_string, :parse_cookies
303
-
304
- # === Input:
305
- #
306
- # the cookie name
307
- #
308
- # === Output:
309
- # - the cookie value, or an array of values for multivalued cookies.
310
- # - nil if the cookie doesnt exist.
311
- #
312
- # === Example:
313
- # nsid = request.get_cookie("nsid")
314
- #
315
- def get_cookie(cookie_name)
316
- return nil unless @in_cookies
317
- cookie = @in_cookies[cookie_name]
318
- return nil unless cookie
319
- return CGI.unescape(cookie.value)
320
- end
321
-
322
- # Removes a cookie from the client by seting the expire
323
- # time to the past (epoch).
324
- #
325
- def del_cookie(name)
326
- cookie = N::Cookie.new(name, "nil")
327
- cookie.path = "/"
328
- cookie.expires = Time.at(0)
329
- @out_cookies[name] = cookie
330
- end
331
-
332
- #-------------------------------------------------------------------------------
333
- # Query
334
-
335
- # Parse the query string and populate the parameters hash.
336
- #
337
- def parse_query_string
338
- return N::UriUtils.query_string_to_hash(@query_string)
339
- end
340
-
341
- # Return the value of a query parameter
342
- #
343
- def [](name)
344
- return @parameters[name]
345
- end
346
-
347
- # Same as [] but enforces a default value to!
348
- # Also tries to guess the parameters type from the default
349
- # value. It works like delete (ie returns nil for 'empty'
350
- # String parameters).
351
- #
352
- def get(key, default=nil)
353
- val = @parameters[key]
354
-
355
- if !val or (val.is_a?(String) and (not N::StringUtils.valid?(val)))
356
- @parameters[key] = default
357
- return default
358
- elsif default.is_a?(Integer)
359
- return val.to_i
360
- else
361
- return val
362
- end
363
- end
364
-
365
- # Set the value of a query parameter
366
- #
367
- # === FIXME:
368
- #
369
- # - handle multivalued parameters!
370
- #
371
- def []=(name, value)
372
- @parameters[name] = value
373
- end
374
-
375
- #-----------------------------------------------------------------------
376
- # Utilities
377
-
378
- # Returns true for the top-level request, but false for
379
- # any inject or forward
380
- #
381
- def is_top?
382
- return 0 == @level
383
- end
384
-
385
- # Is this an admin request?
386
- # FIXME: no longer valid, recode.
387
- #
388
- def admin?
389
- return @parameters.include?("*admin")
390
- end
391
-
392
- # Shorthand for request.session.user
393
- #
394
- def user
395
- return @session.user
396
- end
397
-
398
- # Shorthand for request.session.user.anonymous?
399
- #
400
- def anonymous?
401
- return @session.user.anonymous?
402
- end
403
-
404
- # Set errors as a transaction entity.
405
- # Returns the txid for the errors
406
- def set_errors(errors)
407
- new_tx_entity!(errors, "errid") unless errors.empty?
408
- end
409
-
410
- # Shorthand
411
- #
412
- # Output:
413
- # nil if no errors.
414
- #
415
- def errors
416
- return del_tx_entity!("errid")
417
- end
418
-
419
- # Returns the errors as an array.
420
- #
421
- def errors_to_a
422
- if errors = del_tx_entity!("errid")
423
- return errors.values
424
- end
425
- return nil
426
- end
427
- alias_method :errors_list, :errors_to_a
428
-
429
- # Check if a parameter is valid
430
- #
431
- def param?(param)
432
- return N::StringUtils.valid?(self[param])
433
- end
434
- alias_method :action?, :param?
435
-
436
- # Check if a parameter exists!
437
- # Example:
438
- # url:www.mysite.com/page.sx?admin
439
- # request.include?(admin) => true
440
- #
441
- def include?(param)
442
- return @parameters.include?(param)
443
- end
444
-
445
- def update(*params)
446
- @parameters.update(*params)
447
- end
448
-
449
- # Use the delete name to make the request compatible with
450
- # hashes.
451
- # Tests is a parameter is passed to the request and removes it!
452
- # Used in action handlers.
453
- #
454
- def delete(param)
455
- oparam = param
456
- if param = @parameters.delete(param)
457
- # gmosx: remove from querystring too! NEEDED.
458
- # perhaps kinda slow but happens seldom and optimizes
459
- # another frequent case
460
- @query_string = @parameters.collect { |k, v| (v && k.is_a?(String)) ? "#{k}=#{v}" : k }.join(";")
461
-
462
- # If the parameter exist this is an action request, so
463
- # do NOT cache the fragment.
464
- @uncacheable = true
465
- end
466
-
467
- # gmosx: to avoid using param?
468
- if param.is_a?(String) and (not N::StringUtils.valid?(param))
469
- return nil
470
- else
471
- return param
472
- end
473
- end
474
-
475
- # exclude those parameters for security
476
- EXCLUDED_PARAMETERS = %w{ oid pid name }
477
-
478
- # gmosx: hmm this is a really dangerous method, the EXCLUDED params
479
- # above dont seem enough :(
480
- #
481
- def update_entity(entity)
482
- @parameters.each { |param, val|
483
- begin
484
- # gmosx: DO NOT escape by default !!!
485
- # gmosx: We need to get non valid params
486
- if (not EXCLUDED_PARAMETERS.include?(param))
487
- entity.send("__force_#{param}", val)
488
- end
489
- rescue NameError
490
- next
491
- end
492
- }
493
-
494
- return entity
495
- end
496
-
497
- # --------------------------------------------------------------------
498
-
499
- # The tx sequence increases, the count of transactions / session
500
- # is usually bounded.
501
- #
502
- def new_tx_entity!(entity, txparam = "txid")
503
- unless seq = @session["TXSEQ"]
504
- seq = 0
505
- end
506
- seq += 1
507
- @session["TXSEQ"] = seq
508
- txid = "TX#{seq}"
509
- @session[txid] = entity
510
- @parameters[txparam] = txid
511
- return txid
512
- end
513
-
514
- # Set (update) an existing tx entity. Does NOT increase the
515
- # tx sequence.
516
- #
517
- def set_tx_entity!(entity, txparam = "txid")
518
- if txid = @parameters[txparam]
519
- @session[txid] = entity
520
- end
521
- end
522
- alias_method :update_tx_entity!, :set_tx_entity!
523
-
524
- #
525
- #
526
- def get_tx_entity(txparam = "txid")
527
- if txid = @parameters[txparam]
528
- return @session[txid]
529
- end
530
- return nil
531
- end
532
-
533
- #
534
- #
535
- def del_tx_entity!(txparam = "txid")
536
- if txid = @parameters[txparam]
537
- @session.delete(txid)
538
- end
539
- end
540
-
541
- # --------------------------------------------------------------------
542
- # Debugging helper
543
-
544
- # Accumulate errors in a request log. This log can be presented
545
- # in the offending page when running in debug mode.
546
- #
547
- def log_error(str)
548
- @error_log = [] unless @error_log
549
- @error_log << str if @error_log.size < 200 # gmosx: dod attack!
550
- Logger.error str
551
- end
552
-
553
- # ====================================================================
554
- # Response
555
-
556
- # TODO: add status codes, messages
557
-
558
- # Set the request HTTP status and lookup the
559
- # corresponding request status message.
560
-
561
- def set_status(status = 200)
562
- @status = status
563
- @message = HTTP::STATUS_STRINGS[status]
564
- end
565
-
566
- # Set the HTTP NOT_MODIFIED status code.
567
- # Usefull for HTTP Caching.
568
- #
569
- def set_not_modified!
570
- @status = 304
571
- @message = N::HTTP::STATUS_STRINGS[status]
572
- end
573
-
574
- # 302 is the redirect status!
575
- #
576
- # === Status 303:
577
- #
578
- # The request to the request can be found
579
- # under a different URI and SHOULD be retrieved using
580
- # a GET method on that resource. This method exists
581
- # primarily to allow the output of a POST-activated script
582
- # to redirect the user agent to a selected resource. The new
583
- # URI is not a substitute reference for the originally
584
- # requested resource. The 303 request MUST NOT be cached,
585
- # but the request to the second (redirected) request might
586
- # be cacheable.
587
- #
588
- # Note: Many pre-HTTP/1.1 user agents do not understand the
589
- # 303 status. When interoperability with such clients is a
590
- # concern, the 302 status code may be used instead, since
591
- # most user agents react to a 302 request as described
592
- # here for 303.
593
- #
594
- # === WARNING:
595
- #
596
- # Konqueror always performs a 307 redirect ARGH!
597
- #
598
- # === Redesign:
599
- #
600
- # Use one redirect method with an optional status
601
- # parameter, that reads messages from the status
602
- # constants.
603
- #
604
- # === Input:
605
- #
606
- # - url to redirect to
607
- # - if force_exit == true raises a ScriptExitException
608
- # - status (303 or 307) default = 303
609
- #
610
- def redirect(url = nil, force_exit = false, status = 302)
611
- # FIXME: normalize the url
612
- # url = $srv_url + url if url =~ /^\//om
613
- # FIXME: check arguments
614
-
615
- # enforce a meaningfull default
616
- url ||= self["_go"] || referer()
617
-
618
- # the url should have a leading "/"
619
- # enforce it to be sure. FIXME: optimize this!
620
- url = "/#{url}".squeeze("/") unless url =~ /^http/
621
-
622
- @out["Location"] = url
623
- # gmosx: NOT needed? see the exceprt from the spec.
624
- # @out['Cache-Control'] = "max-age=1"
625
-
626
- set_status(status)
627
- @out_buffer = "The URL has moved <a href='#{url}'>here</a>"
628
-
629
- if force_exit
630
- # Stop rendering the script immediately!
631
- # This is the default behaviour!
632
- raise N::ScriptExitException
633
- end
634
-
635
- # for unit testing
636
- return url
637
- end
638
-
639
- # Internal redirect
640
- #
641
- # FIXME: implement me
642
- #
643
- def internal_redirect(url)
644
- end
645
-
646
- # Utility method to set the expires header.
647
- #
648
- def expires!(exp_time)
649
- @out["Expires"] = N::HttpUtils.time_to_string(exp_time)
650
- end
651
-
652
- def expires?
653
- return @out["Expires"]
654
- end
655
-
656
- end
657
-
658
- end # module