nitro 0.9.5 → 0.10.0

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 (104) hide show
  1. data/ChangeLog +260 -0
  2. data/INSTALL +60 -0
  3. data/LICENSE +1 -0
  4. data/README +19 -20
  5. data/RELEASES +48 -0
  6. data/Rakefile +102 -92
  7. data/benchmark/og/bench.rb +74 -0
  8. data/benchmark/og/sqlite-no-prepare.1.txt +13 -0
  9. data/benchmark/og/sqlite-no-prepare.2.txt +13 -0
  10. data/benchmark/og/sqlite-prepare.1.txt +13 -0
  11. data/benchmark/og/sqlite-prepare.2.txt +13 -0
  12. data/bin/cluster +1 -1
  13. data/bin/nitro +3 -0
  14. data/bin/proto/conf/app.conf.rb +2 -10
  15. data/examples/README.windows +9 -0
  16. data/examples/blog/README +16 -4
  17. data/examples/blog/lib/blog.rb +3 -3
  18. data/examples/blog/lib/blog/controller.rb +7 -9
  19. data/examples/blog/root/fcgi.rb +2 -4
  20. data/examples/blog/root/style.xsl +4 -6
  21. data/examples/blog/run.rb +41 -0
  22. data/examples/flash/run.rb +9 -0
  23. data/examples/no_xsl_blog/README +0 -1
  24. data/examples/no_xsl_blog/conf/app.conf.rb +6 -13
  25. data/examples/no_xsl_blog/lib/blog.rb +2 -2
  26. data/examples/no_xsl_blog/lib/blog/controller.rb +6 -6
  27. data/examples/no_xsl_blog/root/fcgi.rb +2 -4
  28. data/examples/no_xsl_blog/run.rb +38 -0
  29. data/examples/og/mock_example.rb +0 -2
  30. data/examples/og/mysql_to_psql.rb +0 -2
  31. data/examples/og/run.rb +23 -22
  32. data/examples/tiny/root/fcgi.rb +2 -4
  33. data/examples/tiny/root/index.xhtml +21 -5
  34. data/examples/tiny/root/upload.xhtml +23 -0
  35. data/examples/tiny/run.rb +9 -0
  36. data/examples/wee_style/{wee.rb → run.rb} +13 -13
  37. data/install.rb +44 -0
  38. data/lib/glue/array.rb +6 -10
  39. data/lib/glue/attribute.rb +0 -3
  40. data/lib/glue/cache.rb +1 -1
  41. data/lib/glue/inflector.rb +5 -5
  42. data/lib/glue/mixins.rb +3 -12
  43. data/lib/glue/number.rb +1 -1
  44. data/lib/glue/object.rb +7 -1
  45. data/lib/glue/property.rb +32 -22
  46. data/lib/glue/string.rb +13 -75
  47. data/lib/glue/time.rb +2 -2
  48. data/lib/glue/validation.rb +7 -11
  49. data/lib/nitro.rb +16 -1
  50. data/lib/nitro/{adaptors → adapters}/cgi.rb +101 -20
  51. data/lib/nitro/{adaptors → adapters}/fastcgi.rb +3 -2
  52. data/lib/nitro/{adaptors → adapters}/webrick.rb +4 -4
  53. data/lib/nitro/builders/rss.rb +1 -1
  54. data/lib/nitro/builders/xml.rb +8 -10
  55. data/lib/nitro/cluster.rb +1 -1
  56. data/lib/nitro/conf.rb +34 -0
  57. data/lib/nitro/controller.rb +8 -9
  58. data/lib/nitro/dispatcher.rb +38 -11
  59. data/lib/nitro/filters.rb +1 -1
  60. data/lib/nitro/markup.rb +14 -1
  61. data/lib/nitro/render.rb +7 -10
  62. data/lib/nitro/runner.rb +232 -0
  63. data/lib/nitro/ui/pager.rb +2 -6
  64. data/lib/nitro/uri.rb +7 -11
  65. data/lib/og.rb +27 -261
  66. data/lib/og/adapter.rb +352 -0
  67. data/lib/og/adapters/mysql.rb +304 -0
  68. data/lib/og/adapters/psql.rb +286 -0
  69. data/lib/og/adapters/sqlite.rb +262 -0
  70. data/lib/og/backend.rb +1 -1
  71. data/lib/og/connection.rb +123 -87
  72. data/lib/og/database.rb +268 -0
  73. data/lib/og/meta.rb +23 -22
  74. data/lib/og/mock.rb +2 -3
  75. data/lib/xsl/base.xsl +1 -55
  76. data/test/glue/tc_property.rb +2 -0
  77. data/test/glue/tc_property_type_checking.rb +32 -0
  78. data/test/glue/tc_strings.rb +2 -2
  79. data/test/glue/tc_validation.rb +2 -0
  80. data/test/nitro/adapters/raw_post1.bin +0 -0
  81. data/test/nitro/{adaptors → adapters}/tc_cgi.rb +11 -2
  82. data/test/nitro/{adaptors → adapters}/tc_webrick.rb +3 -3
  83. data/test/nitro/builders/tc_xml.rb +14 -5
  84. data/test/nitro/tc_dispatcher.rb +3 -3
  85. data/test/nitro/tc_uri.rb +2 -4
  86. data/test/og/tc_lifecycle.rb +22 -25
  87. data/test/og/tc_sqlite.rb +87 -0
  88. data/test/tc_og.rb +61 -42
  89. metadata +67 -33
  90. data/examples/blog/conf/app.conf.rb +0 -52
  91. data/examples/blog/ctl +0 -4
  92. data/examples/flash/conf/app.conf.rb +0 -21
  93. data/examples/flash/ctl +0 -4
  94. data/examples/no_xsl_blog/conf/apache.conf +0 -0
  95. data/examples/no_xsl_blog/ctl +0 -4
  96. data/examples/tiny/conf/app.conf.rb +0 -17
  97. data/examples/tiny/ctl +0 -4
  98. data/lib/glue/macro.rb +0 -56
  99. data/lib/nitro/adaptors/runner.rb +0 -123
  100. data/lib/nitro/version.rb +0 -15
  101. data/lib/og/backends/mysql.rb +0 -370
  102. data/lib/og/backends/psql.rb +0 -386
  103. data/lib/og/backends/sqlite.rb +0 -383
  104. data/lib/og/version.rb +0 -9
data/lib/glue/time.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: time.rb 202 2005-01-17 10:44:13Z gmosx $
3
+ # $Id: time.rb 259 2005-02-15 08:54:54Z gmosx $
4
4
 
5
- require "time.rb"
5
+ require 'time.rb'
6
6
 
7
7
  module N;
8
8
 
@@ -8,7 +8,7 @@ module N
8
8
  # objects. Typically used in Validator objects but can be
9
9
  # included in managed objects too.
10
10
  #
11
- # == Example
11
+ # === Example
12
12
  #
13
13
  # class User
14
14
  # prop_accessor :name, String
@@ -50,8 +50,6 @@ module N
50
50
 
51
51
  module Validation
52
52
 
53
- # = Errors
54
- #
55
53
  # Encapsulates a list of validation errors.
56
54
 
57
55
  class Errors
@@ -159,8 +157,6 @@ module Validation
159
157
  base.extend(MetaLanguage)
160
158
  end
161
159
 
162
- # = MetaLanguage
163
- #
164
160
  # Implements the Validation meta-language.
165
161
 
166
162
  module MetaLanguage
@@ -172,9 +168,9 @@ module Validation
172
168
  # Validates that the attributes have a values, ie they are
173
169
  # neither nil or empty.
174
170
  #
175
- # == Example
171
+ # === Example
176
172
  #
177
- # validate_value :, :msg => 'No confirmation'
173
+ # validate_value :param, :msg => 'No confirmation'
178
174
 
179
175
  def validate_value(*params)
180
176
  c = {
@@ -199,7 +195,7 @@ module Validation
199
195
 
200
196
  # Validates the confirmation of +String+ attributes.
201
197
  #
202
- # == Example
198
+ # === Example
203
199
  #
204
200
  # validate_confirmation :password, :msg => 'No confirmation'
205
201
 
@@ -228,7 +224,7 @@ module Validation
228
224
 
229
225
  # Validates the format of +String+ attributes.
230
226
  #
231
- # == Example
227
+ # === Example
232
228
  #
233
229
  # validate_format :name, :format => /$A*/, :msg => 'My error', :on => :create
234
230
 
@@ -263,7 +259,7 @@ module Validation
263
259
 
264
260
  # Validates the length of +String+ attributes.
265
261
  #
266
- # == Example
262
+ # === Example
267
263
  #
268
264
  # validate_length :name, :max => 30, :msg => 'Too long'
269
265
  # validate_length :name, :min => 2, :msg => 'Too sort'
@@ -354,7 +350,7 @@ module Validation
354
350
  # Validates that the attributes are included in
355
351
  # an enumeration.
356
352
  #
357
- # == Example
353
+ # === Example
358
354
  #
359
355
  # validate_inclusion :sex, :in => %w{ Male Female }, :msg => 'huh??'
360
356
  # validate_inclusion :age, :in => 5..99
data/lib/nitro.rb CHANGED
@@ -12,7 +12,7 @@
12
12
  #
13
13
  # * George Moschovitis <gm@navel.gr>
14
14
  # (c) 2004-2005 Navel, all rights reserved.
15
- # $Id: nitro.rb 215 2005-01-24 10:44:05Z gmosx $
15
+ # $Id: nitro.rb 259 2005-02-15 08:54:54Z gmosx $
16
16
 
17
17
  require 'glue'
18
18
  require 'glue/logger'
@@ -20,8 +20,23 @@ require 'glue/logger'
20
20
  require 'nitro/context'
21
21
  require 'nitro/dispatcher'
22
22
  require 'nitro/render'
23
+ require 'nitro/conf'
24
+ require 'nitro/runner'
23
25
 
24
26
  # Define Nitro namespace.
25
27
 
26
28
  module Nitro
29
+
30
+ # The name.
31
+
32
+ Name = 'Nitro'
33
+
34
+ # The version.
35
+
36
+ Version = '0.10.0'
37
+
38
+ # Library path.
39
+
40
+ LibPath = File.dirname(__FILE__)
41
+
27
42
  end
@@ -4,24 +4,24 @@
4
4
 
5
5
  require 'cgi'
6
6
 
7
+ require 'glue/attribute'
8
+
7
9
  module N
8
10
 
9
- =begin
10
- # Extend the Request module.
11
+ class Cgi
12
+ # Maximum content length allowed in requests.
11
13
 
12
- module Request
13
- include CGI::QueryExtension
14
-
15
- def stdinput
16
- @in
17
- end
14
+ cattr_accessor :max_content_length, (2 * 1024 * 1024)
15
+
16
+ # Multipart parsing buffer size.
17
+
18
+ cattr_accessor :buffer_size, (10 * 1024)
18
19
  end
19
- =end
20
20
 
21
21
  # CGI utility methods.
22
22
 
23
23
  class CgiUtils
24
-
24
+
25
25
  # HTTP protocol EOL constants
26
26
 
27
27
  CR = "\x0d"
@@ -84,8 +84,8 @@ class CgiUtils
84
84
  # to arrays.
85
85
 
86
86
  def self.parse_query_string(query_string)
87
- # gmosx, THINK: better return nil here?
88
87
 
88
+ # gmosx, THINK: better return nil here?
89
89
  return {} if (query_string.nil? or query_string.empty?)
90
90
 
91
91
  params = {}
@@ -167,13 +167,14 @@ class CgiUtils
167
167
  if (:post == method) and
168
168
  %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(context.headers['CONTENT_TYPE'])
169
169
  boundary = $1.dup
170
- context.params = read_multipart(boundary, Integer(context.headers['CONTENT_LENGTH']))
170
+ # context.params = read_multipart(boundary, Integer(context.headers['CONTENT_LENGTH']), context.in, context.headers)
171
+ parse_multipart(context, boundary)
171
172
  else
172
173
  case method
173
174
  when :get, :head
174
175
  context.params = CgiUtils.parse_query_string(context.query_string)
175
176
  when :post
176
- context.in.binmode if defined?(context.in.binmode)
177
+ context.in.binmode # if defined?(context.in.binmode)
177
178
 
178
179
  context.params = CgiUtils.parse_query_string(
179
180
  context.in.read(
@@ -183,8 +184,85 @@ class CgiUtils
183
184
  end
184
185
 
185
186
  # Parse a multipart request.
187
+
188
+ def self.parse_multipart(context, boundary)
189
+ io = context.in
190
+ env = context.headers
191
+
192
+ io.binmode # if defined?(ins.binmode)
193
+
194
+ buffer = ''
195
+ bufsize = Cgi.buffer_size
196
+
197
+ boundary = "--" + boundary
198
+ boundary_size = boundary.size + EOL.size
199
+
200
+ content_length = context.headers['CONTENT_LENGTH'].to_i
201
+
202
+ if content_length > Cgi.max_content_length
203
+ raise 'Request content length exceeds limit'
204
+ end
205
+
206
+ context.params = {}
207
+
208
+ status = io.read(boundary_size)
209
+
210
+ if (status.nil?) or ( (boundary + EOL) != status )
211
+ raise 'Bad content body'
212
+ end
213
+
214
+ content_length -= boundary_size
215
+
216
+ head = nil
217
+
218
+ loop do
219
+ until head and /#{boundary}(?:#{EOL}|--)/n.match(buffer)
220
+ if (not head) and /#{EOL}#{EOL}/n.match(buffer)
221
+ buffer = buffer.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
222
+ head = $1.dup
223
+ ""
224
+ end
225
+ next
226
+ end
227
+
228
+ puts "*** #{head}"
229
+
230
+ /Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
231
+ filename = $1
232
+ if /Mac/ni.match(env['HTTP_USER_AGENT']) and
233
+ /Mozilla/ni.match(env['HTTP_USER_AGENT']) and
234
+ (not /MSIE/ni.match(env['HTTP_USER_AGENT']))
235
+ filename = CGI::unescape(filename)
236
+ end
237
+
238
+ puts "--- f: #{filename}"
239
+
240
+ if filename
241
+ /Content-Type: (.*)/ni.match(head)
242
+ content_type = $1 or ''
243
+
244
+ puts "--- c: #{content_type}"
245
+ end
246
+
247
+ chunk = if bufsize < content_length
248
+ io.read(bufsize)
249
+ else
250
+ io.read(content_length)
251
+ end
252
+
253
+ raise 'Bad content body' unless chunk
254
+
255
+
256
+ buffer << chunk
257
+ content_length -= chunk.size
258
+ end
259
+ end
260
+ end
261
+
262
+ # Parse a multipart request.
263
+ # Copied from ruby's cgi.rb
186
264
 
187
- def self.read_multipart(boundary, content_length)
265
+ def self.read_multipart(boundary, content_length, stdinput, env_table)
188
266
  params = Hash.new([])
189
267
  boundary = "--" + boundary
190
268
  buf = ""
@@ -192,9 +270,7 @@ class CgiUtils
192
270
 
193
271
  # start multipart/form-data
194
272
  stdinput.binmode if defined? stdinput.binmode
195
- boundary_size = boundary.size + EOL.size
196
- content_length -= boundary_size
197
- status = stdinput.read(boundary_size)
273
+
198
274
  if nil == status
199
275
  raise EOFError, "no content body"
200
276
  elsif boundary + EOL != status
@@ -274,11 +350,16 @@ end
274
350
  /Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
275
351
  name = $1.dup
276
352
 
277
- if params.has_key?(name)
278
- params[name].push(body)
353
+ if name =~ /(.*)\[\]$/
354
+ if params.has_name?($1)
355
+ params[$1] << body
356
+ else
357
+ params[$1] = [body]
358
+ end
279
359
  else
280
- params[name] = [body]
360
+ params[name] = body.nil? ? nil : body
281
361
  end
362
+
282
363
  break if buf.size == 0
283
364
  break if content_length === -1
284
365
  end
@@ -1,5 +1,5 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
- # (c) 2005 Navel, all rights reserved.
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
3
  # $Id$
4
4
 
5
5
  require 'cgi'
@@ -7,7 +7,7 @@ require 'fcgi'
7
7
 
8
8
  require 'nitro/context'
9
9
  require 'nitro/dispatcher'
10
- require 'nitro/adaptors/cgi'
10
+ require 'nitro/adapters/cgi'
11
11
 
12
12
  require 'glue/flexob'
13
13
 
@@ -44,6 +44,7 @@ class FastCGI
44
44
  cgi.out.print(context.out)
45
45
 
46
46
  cgi.finish
47
+
47
48
  end
48
49
  end
49
50
 
@@ -25,7 +25,7 @@ end
25
25
 
26
26
  module N
27
27
 
28
- # Helper methods for the WebrickAdaptor.
28
+ # Helper methods for the WebrickAdapter.
29
29
 
30
30
  class Webrick
31
31
 
@@ -62,16 +62,16 @@ class Webrick
62
62
 
63
63
  trap('INT') { @server.shutdown }
64
64
 
65
- @server.mount('/', WebrickAdaptor, conf)
65
+ @server.mount('/', WebrickAdapter, conf)
66
66
  @server.start
67
67
  end
68
68
  end
69
69
 
70
70
  end
71
71
 
72
- # A Webrick Adaptor for Nitro.
72
+ # A Webrick Adapter for Nitro.
73
73
 
74
- class WebrickAdaptor < WEBrick::HTTPServlet::AbstractServlet
74
+ class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
75
75
 
76
76
  # REQUEST_MUTEX = Mutex.new
77
77
 
@@ -1,6 +1,6 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: rss.rb 202 2005-01-17 10:44:13Z gmosx $
3
+ # $Id: rss.rb 249 2005-02-04 14:03:00Z gmosx $
4
4
 
5
5
  require 'rss/0.9'
6
6
 
@@ -4,8 +4,6 @@
4
4
 
5
5
  module N
6
6
 
7
- # = XmlBuilderMixin
8
- #
9
7
  # A helper mixin for programmatically building XML
10
8
  # blocks.
11
9
 
@@ -25,7 +23,7 @@ module XmlBuilderMixin
25
23
  self << args.first
26
24
  end_tag('#{tag}')
27
25
  else
28
- start_tag('#{tag}', attrs)
26
+ start_tag('#{tag}', attrs, false)
29
27
  self << ' />'
30
28
  end
31
29
  end
@@ -34,9 +32,13 @@ module XmlBuilderMixin
34
32
  self.send(tag, *args, &block)
35
33
  end
36
34
 
37
- def start_tag(tag, attributes = nil)
35
+ def start_tag(tag, attributes = nil, close = true)
38
36
  unless attributes
39
- self << "<#{tag}>"
37
+ if close
38
+ self << "<#{tag}>"
39
+ else
40
+ self << "<#{tag}"
41
+ end
40
42
  else
41
43
  self << "<#{tag}"
42
44
  for name, value in attributes
@@ -46,7 +48,7 @@ module XmlBuilderMixin
46
48
  self << %| #{name}="1"|
47
49
  end
48
50
  end
49
- self << ">"
51
+ self << ">" if close
50
52
  end
51
53
 
52
54
  return self
@@ -72,8 +74,6 @@ module XmlBuilderMixin
72
74
 
73
75
  end
74
76
 
75
- # = XmlString
76
- #
77
77
  # A String extension with XML generation
78
78
  # functionality.
79
79
 
@@ -81,8 +81,6 @@ class XmlString < String
81
81
  include N::XmlBuilderMixin
82
82
  end
83
83
 
84
- # = XmlBuilder
85
- #
86
84
  # A class that encapsulats the XML generation
87
85
  # functionality. Utilizes duck typing to redirect
88
86
  # output to a target buffer.
data/lib/nitro/cluster.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: cluster.rb 234 2005-01-27 13:01:40Z gmosx $
3
+ # $Id: cluster.rb 249 2005-02-04 14:03:00Z gmosx $
4
4
 
5
5
  # WARNING: This is old code, not updated to work in the
6
6
  # latest nitro release. Will be fixed ASAP.
data/lib/nitro/conf.rb ADDED
@@ -0,0 +1,34 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: conf.rb 260 2005-02-15 08:58:04Z gmosx $
4
+
5
+ require 'glue/flexob'
6
+
7
+ module N
8
+
9
+ # Configuration.
10
+
11
+ class Conf < Flexob
12
+
13
+ def initialize(options)
14
+ unless options.is_a?(Hash)
15
+ raise ArgumentError.new('An options hash is required!')
16
+ end
17
+
18
+ # Default configuration parameters.
19
+
20
+ hash = {
21
+ :name => 'Nitro Application',
22
+ :host => 'localhost',
23
+ :port => 8069,
24
+ :dispatcher => Dispatcher.new
25
+ }
26
+
27
+ hash.update(options)
28
+
29
+ super(hash)
30
+ end
31
+
32
+ end
33
+
34
+ end